Re: [PATCH v3 02/15] mei: add support to GSC extended header
On Thu, Sep 08, 2022 at 09:24:07PM +, Winkler, Tomas wrote: > > > > > On Fri, Aug 19, 2022 at 03:53:22PM -0700, Daniele Ceraolo Spurio wrote: > > > --- a/drivers/misc/mei/hw-me.c > > > +++ b/drivers/misc/mei/hw-me.c > > > @@ -590,7 +590,10 @@ static int mei_me_hbuf_write(struct mei_device > > *dev, > > > u32 dw_cnt; > > > int empty_slots; > > > > > > - if (WARN_ON(!hdr || !data || hdr_len & 0x3)) > > > + if (WARN_ON(!hdr || hdr_len & 0x3)) > > > + return -EINVAL; > > > + > > > + if (WARN_ON(!data && data_len)) > > > > Do not add more WARN_ON() calls, please just handle this properly and do > > not reboot people's machines for a coding error :( > > As far as I understand WARN_ON() will produce solely a backtrace , Except when you have panic_on_warn() enabled in your systems, as many do :( > This particular condition should never ever happen in theory, Then don't check it! > anyhow we can use dev_err() here as well. That would be best. thanks, greg k-h
[Bug 205089] amdgpu : drm:amdgpu_cs_ioctl : Failed to initialize parser -125
https://bugzilla.kernel.org/show_bug.cgi?id=205089 Oscar Parada (oparada1...@gmail.com) changed: What|Removed |Added CC||oparada1...@gmail.com --- Comment #48 from Oscar Parada (oparada1...@gmail.com) --- Came to add that this issue is still ongoing. Ubuntu 22.04.1 This happens recently when I stream, I'm able to play for a couple of minutes then screen goes black, comes back all is frozen, mouse cursor moves but I can't click. -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
RE: [PATCH v2 15/15] vfio: Add struct device to vfio_device
> From: Jason Gunthorpe > Sent: Thursday, September 8, 2022 8:37 PM > > On Thu, Sep 08, 2022 at 11:39:07AM +0200, Eric Auger wrote: > > > >> I am not totally clear about remaining 'struct device *dev;' in > > >> vfio_device struct. I see it used in some places. Is it supposed to > > >> disappear at some point? > > > > > > no, Eric. *dev will not disappear, it stores the dev pointet passed in by > > > caller of vfio_init_device(). > > > > yeah I see but you have device->device.parent = device->dev; > > IIRC we have a number of these redundancies now, often the drivers > store another copy of the dev too. > > A significant use of dev is for printing things, what should be done > here is to create a subsystem wide vfio_warn/etc that takes in the > vfio_device, and then print properly from there. Now that we have a > struct device all the prints should also include the VFIO struct > device name, and then the PCI device perhaps in brackets. > Let me handle it in a separate patch (after this series).
[PATCH v3 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 5bc221730d7b..37cbd10f3faf 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 v3 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. Also take this chance to rename chardev 'vfio' to 'vfio-group' in /proc/devices. 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 | 67 +++ include/linux/vfio.h | 6 +- 4 files changed, 67 insertions(+), 15 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 37cbd10f3faf..cd23d35c878c 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); /* * Alloc 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) -
[PATCH v3 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 v3 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 v3 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 v3 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 v3 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 v3 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..a07dac16d873 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); + 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); + mdpy_count--; } 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 v3 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..df95f25fbc0e 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); + 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); + atomic_add(mdev_state->type->mbytes, _avail_mbytes); } 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 v3 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..803aadfd0876 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) +{ + vfio_free_device(vdev); + atomic_inc(_dev->available_instances); +} + 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 v3 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 v3 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..41301d50b247 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); + + kfree(mdev_state->vconfig); + vfio_free_device(vdev); + atomic_add(mdev_state->nr_ports, _avail_ports); +} + 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 v3 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..adc1b697bb78 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); + +/* + * Alloc 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 0e2826559091..f67cac700e6f
[PATCH v3 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 anyay. 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/ v3: - 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 | 167 +++--- 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, 730 insertions(+), 381 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-devices-vfio-dev base-commit: f39856aacb078c1c93acef011a37121b17d54fe0 -- 2.21.3
[PATCH v3 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 v3 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] drm/qxl: drop set_prod_notify parameter from qxl_ring_create
Since qxl_io_reset(qdev) will be called immediately after qxl_ring_create() been called, and parameter like notify_on_prod will be set to default value. So the call to qxl_ring_init_hdr() before becomes meaningless. Signed-off-by: Zongmin Zhou Suggested-by: Ming Xie --- drivers/gpu/drm/qxl/qxl_cmd.c | 8 drivers/gpu/drm/qxl/qxl_drv.h | 2 -- drivers/gpu/drm/qxl/qxl_kms.c | 4 +--- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 7b00c955cd82..63aa96a69752 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -53,17 +53,11 @@ void qxl_ring_free(struct qxl_ring *ring) kfree(ring); } -void qxl_ring_init_hdr(struct qxl_ring *ring) -{ - ring->ring->header.notify_on_prod = ring->n_elements; -} - struct qxl_ring * qxl_ring_create(struct qxl_ring_header *header, int element_size, int n_elements, int prod_notify, - bool set_prod_notify, wait_queue_head_t *push_event) { struct qxl_ring *ring; @@ -77,8 +71,6 @@ qxl_ring_create(struct qxl_ring_header *header, ring->n_elements = n_elements; ring->prod_notify = prod_notify; ring->push_event = push_event; - if (set_prod_notify) - qxl_ring_init_hdr(ring); spin_lock_init(>lock); return ring; } diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 47c169673088..432758ad39a3 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -277,10 +277,8 @@ struct qxl_ring *qxl_ring_create(struct qxl_ring_header *header, int element_size, int n_elements, int prod_notify, -bool set_prod_notify, wait_queue_head_t *push_event); void qxl_ring_free(struct qxl_ring *ring); -void qxl_ring_init_hdr(struct qxl_ring *ring); int qxl_check_idle(struct qxl_ring *ring); static inline uint64_t diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index 9bf6d4cc98d4..dc3828db1991 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -194,7 +194,6 @@ int qxl_device_init(struct qxl_device *qdev, sizeof(struct qxl_command), QXL_COMMAND_RING_SIZE, qdev->io_base + QXL_IO_NOTIFY_CMD, -false, >display_event); if (!qdev->command_ring) { DRM_ERROR("Unable to create command ring\n"); @@ -207,7 +206,6 @@ int qxl_device_init(struct qxl_device *qdev, sizeof(struct qxl_command), QXL_CURSOR_RING_SIZE, qdev->io_base + QXL_IO_NOTIFY_CURSOR, - false, >cursor_event); if (!qdev->cursor_ring) { @@ -219,7 +217,7 @@ int qxl_device_init(struct qxl_device *qdev, qdev->release_ring = qxl_ring_create( &(qdev->ram_header->release_ring_hdr), sizeof(uint64_t), - QXL_RELEASE_RING_SIZE, 0, true, + QXL_RELEASE_RING_SIZE, 0, NULL); if (!qdev->release_ring) { -- 2.25.1 No virus found Checked by Hillstone Network AntiVirus
RE: [PATCH v2 13/15] vfio/ccw: Use the new device life cycle helpers
> From: Eric Farman > Sent: Friday, September 9, 2022 4:51 AM > > On Thu, 2022-09-08 at 07:19 +, Tian, Kevin wrote: > > ping @Eric Farman. > > > > ccw is the only tricky player in this series. Please help take a look > > in case of > > any oversight here. > > Apologies, I had started looking at v1 before I left on holiday, and > only returned today. > > > > > > From: Tian, Kevin > > > Sent: Thursday, September 1, 2022 10:38 PM > > > > > > 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. > > I did start looking at the above, while the mdev series is outstanding. > Will try to get back to that sooner rather than later, but for the > purposes of this series this patch looks/works fine to me. > > Reviewed-by: Eric Farman > Thanks!
Re: [PATCH 1/2] dt-bindings: display: panel: Add NewVision NV3051D panel bindings
On Wed, Sep 07, 2022 at 08:35:13AM -0500, Chris Morgan wrote: > On Wed, Sep 07, 2022 at 02:53:56PM +0200, Krzysztof Kozlowski wrote: > > On 06/09/2022 20:52, Chris Morgan wrote: > > > 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. > > > > > > Signed-off-by: Chris Morgan > > > --- > > > .../display/panel/newvision,nv3051d.yaml | 48 +++ > > > 1 file changed, 48 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 ..016168d8d7b2 > > > --- /dev/null > > > +++ > > > b/Documentation/devicetree/bindings/display/panel/newvision,nv3051d.yaml > > > @@ -0,0 +1,48 @@ > > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > > +%YAML 1.2 > > > +--- > > > +$id: > > > https://nam12.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fdisplay%2Fpanel%2Fnewvision%2Cnv3051d.yaml%23data=05%7C01%7C%7C69d30de15aea41517acb08da90d0079f%7C84df9e7fe9f640afb435%7C1%7C0%7C637981520397977782%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7Csdata=qfuvbrQYP3rKnp%2ByPmPmn%2BCJJOQkNkTGT49FkJmIics%3Dreserved=0 > > > > You need to document vendor prefix... but the filename does not match > > compatible. > > Okay, will do that. This is a tricky one because while I know the panel > controller IC (a NewVision NV3051D) I don't actually know the LCD panel > itself, the vendor is somewhat tight lipped. I do know the product it > goes into, so that's why I did what I did with the compatible strings. > If that's not correct I guess let me know. I did see for other drivers > (such as the NewVision NV3052C) the driver was written for the IC > and the panel name was listed differently, hence what I was going for > here. I think most cases like this targeting a specific LCD driver IC, there's a driver IC compatible as a fallback. (TBC, 'driver' here is not Linux driver, but the h/w chip.) Rob
Re: [PATCH v2 2/5] dt-bindings: phy-rockchip-inno-dsidphy: add compatible for rk3568
On Tue, 06 Sep 2022 12:48:20 -0500, Chris Morgan wrote: > From: Chris Morgan > > Add a compatible string for the rk3568 dsi-dphy. > > Signed-off-by: Chris Morgan > --- > .../devicetree/bindings/phy/rockchip,px30-dsi-dphy.yaml | 1 + > 1 file changed, 1 insertion(+) > Acked-by: Rob Herring
Re: [PATCH v2 1/5] dt-bindings: display: rockchip-dsi: add rk3568 compatible
On Tue, 06 Sep 2022 12:48:19 -0500, Chris Morgan wrote: > From: Chris Morgan > > The rk3568 uses the same dw-mipi-dsi controller as previous Rockchip > SOCs, so add a compatible string for it. > > Signed-off-by: Chris Morgan > --- > .../bindings/display/rockchip/dw_mipi_dsi_rockchip.txt | 1 + > 1 file changed, 1 insertion(+) > Acked-by: Rob Herring
Re: [PATCH v4 15/15] HAX: drm/i915: force INTEL_MEI_GSC and INTEL_MEI_PXP on for CI
I've submitted a merge request to have those flags turned on by default in our CI builds: https://gitlab.freedesktop.org/gfx-ci/i915-infra/-/merge_requests/116 Daniele On 9/8/2022 5:16 PM, Daniele Ceraolo Spurio wrote: Both are required for HuC loading. Signed-off-by: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/Kconfig.debug | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index e7fd3e76f8a2..a6576ffbc4dc 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -48,6 +48,8 @@ config DRM_I915_DEBUG select DRM_I915_DEBUG_RUNTIME_PM select DRM_I915_SW_FENCE_DEBUG_OBJECTS select DRM_I915_SELFTEST + select INTEL_MEI_GSC + select INTEL_MEI_PXP select BROKEN # for prototype uAPI default n help
[PATCH v4 12/15] drm/i915/huc: stall media submission until HuC is loaded
Wait on the fence to be signalled to avoid the submissions finding HuC not yet loaded. Signed-off-by: Daniele Ceraolo Spurio Cc: Tony Ye Reviewed-by: Alan Previn --- drivers/gpu/drm/i915/gt/uc/intel_huc.h | 6 ++ drivers/gpu/drm/i915/i915_request.c| 24 2 files changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h index 915d281c1c72..52db03620c60 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h @@ -81,6 +81,12 @@ static inline bool intel_huc_is_loaded_by_gsc(const struct intel_huc *huc) return huc->fw.loaded_via_gsc; } +static inline bool intel_huc_wait_required(struct intel_huc *huc) +{ + return intel_huc_is_used(huc) && intel_huc_is_loaded_by_gsc(huc) && + !intel_huc_is_authenticated(huc); +} + void intel_huc_load_status(struct intel_huc *huc, struct drm_printer *p); #endif diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 62fad16a55e8..77f45a3cb01f 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1621,6 +1621,20 @@ i915_request_await_object(struct i915_request *to, return ret; } +static void i915_request_await_huc(struct i915_request *rq) +{ + struct intel_huc *huc = >context->engine->gt->uc.huc; + + /* don't stall kernel submissions! */ + if (!rcu_access_pointer(rq->context->gem_context)) + return; + + if (intel_huc_wait_required(huc)) + i915_sw_fence_await_sw_fence(>submit, +>delayed_load.fence, +>submitq); +} + static struct i915_request * __i915_request_ensure_parallel_ordering(struct i915_request *rq, struct intel_timeline *timeline) @@ -1702,6 +1716,16 @@ __i915_request_add_to_timeline(struct i915_request *rq) struct intel_timeline *timeline = i915_request_timeline(rq); struct i915_request *prev; + /* +* Media workloads may require HuC, so stall them until HuC loading is +* complete. Note that HuC not being loaded when a user submission +* arrives can only happen when HuC is loaded via GSC and in that case +* we still expect the window between us starting to accept submissions +* and HuC loading completion to be small (a few hundred ms). +*/ + if (rq->engine->class == VIDEO_DECODE_CLASS) + i915_request_await_huc(rq); + /* * Dependency tracking and request ordering along the timeline * is special cased so that we can eliminate redundant ordering -- 2.37.2
[PATCH v4 15/15] HAX: drm/i915: force INTEL_MEI_GSC and INTEL_MEI_PXP on for CI
Both are required for HuC loading. Signed-off-by: Daniele Ceraolo Spurio --- drivers/gpu/drm/i915/Kconfig.debug | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index e7fd3e76f8a2..a6576ffbc4dc 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -48,6 +48,8 @@ config DRM_I915_DEBUG select DRM_I915_DEBUG_RUNTIME_PM select DRM_I915_SW_FENCE_DEBUG_OBJECTS select DRM_I915_SELFTEST + select INTEL_MEI_GSC + select INTEL_MEI_PXP select BROKEN # for prototype uAPI default n help -- 2.37.2
[PATCH v4 09/15] drm/i915/pxp: add huc authentication and loading command
From: Tomas Winkler Add support for loading HuC via a pxp stream command. V4: 1. Remove unnecessary include in intel_pxp_huc.h (Jani) 2. Adjust copyright year to 2022 Signed-off-by: Tomas Winkler Signed-off-by: Vitaly Lubart Signed-off-by: Daniele Ceraolo Spurio Cc: Alan Previn Reviewed-by: Alan Previn --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 69 +++ drivers/gpu/drm/i915/pxp/intel_pxp_huc.h | 13 .../drm/i915/pxp/intel_pxp_tee_interface.h| 23 ++- 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 589823ad62ed..5bee787d3c2a 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -310,7 +310,8 @@ i915-y += i915_perf.o # Protected execution platform (PXP) support. Base support is required for HuC i915-y += \ pxp/intel_pxp.o \ - pxp/intel_pxp_tee.o + pxp/intel_pxp_tee.o \ + pxp/intel_pxp_huc.o i915-$(CONFIG_DRM_I915_PXP) += \ pxp/intel_pxp_cmd.o \ diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c new file mode 100644 index ..7ec36d94e758 --- /dev/null +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2021-2022, Intel Corporation. All rights reserved. + */ + +#include "drm/i915_drm.h" +#include "i915_drv.h" + +#include "gem/i915_gem_region.h" +#include "gt/intel_gt.h" + +#include "intel_pxp.h" +#include "intel_pxp_huc.h" +#include "intel_pxp_tee.h" +#include "intel_pxp_types.h" +#include "intel_pxp_tee_interface.h" + +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp) +{ + struct intel_gt *gt = pxp_to_gt(pxp); + struct intel_huc *huc = >uc.huc; + struct pxp_tee_start_huc_auth_in huc_in = {0}; + struct pxp_tee_start_huc_auth_out huc_out = {0}; + dma_addr_t huc_phys_addr; + u8 client_id = 0; + u8 fence_id = 0; + int err; + + if (!pxp->pxp_component) + return -ENODEV; + + huc_phys_addr = i915_gem_object_get_dma_address(huc->fw.obj, 0); + + /* write the PXP message into the lmem (the sg list) */ + huc_in.header.api_version = PXP_TEE_43_APIVER; + huc_in.header.command_id = PXP_TEE_43_START_HUC_AUTH; + huc_in.header.status = 0; + huc_in.header.buffer_len = sizeof(huc_in.huc_base_address); + huc_in.huc_base_address = huc_phys_addr; + + err = intel_pxp_tee_stream_message(pxp, client_id, fence_id, + _in, sizeof(huc_in), + _out, sizeof(huc_out)); + if (err < 0) { + drm_err(>i915->drm, + "Failed to send HuC load and auth command to GSC [%d]!\n", + err); + return err; + } + + /* +* HuC does sometimes survive suspend/resume (it depends on how "deep" +* a sleep state the device reaches) so we can end up here on resume +* with HuC already loaded, in which case the GSC will return +* PXP_STATUS_OP_NOT_PERMITTED. We can therefore consider the GuC +* correctly transferred in this scenario; if the same error is ever +* returned with HuC not loaded we'll still catch it when we check the +* authentication bit later. +*/ + if (huc_out.header.status != PXP_STATUS_SUCCESS && + huc_out.header.status != PXP_STATUS_OP_NOT_PERMITTED) { + drm_err(>i915->drm, + "HuC load failed with GSC error = 0x%x\n", + huc_out.header.status); + return -EPROTO; + } + + return 0; +} diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h new file mode 100644 index ..e40847a91c39 --- /dev/null +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_huc.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright(c) 2021-2022, Intel Corporation. All rights reserved. + */ + +#ifndef __INTEL_PXP_HUC_H__ +#define __INTEL_PXP_HUC_H__ + +struct intel_pxp; + +int intel_pxp_huc_load_and_auth(struct intel_pxp *pxp); + +#endif /* __INTEL_PXP_HUC_H__ */ diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h index 36e9b0868f5c..7edc1760f142 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT */ /* - * Copyright(c) 2020, Intel Corporation. All rights reserved. + * Copyright(c) 2020-2022, Intel Corporation. All rights reserved. */ #ifndef __INTEL_PXP_TEE_INTERFACE_H__ @@ -9,8 +9,20
[PATCH v4 06/15] mei: pxp: support matching with a gfx discrete card
From: Tomas Winkler With on-boards graphics card, both i915 and MEI are in the same device hierarchy with the same parent, while for discrete gfx card the MEI is its child device. Adjust the match function for that scenario by matching MEI parent device with i915. V2: 1. More detailed commit message 2. Check for dev is not null before it is accessed. Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Vitaly Lubart Cc: Greg Kroah-Hartman Reviewed-by: Alan Previn --- drivers/misc/mei/pxp/mei_pxp.c | 13 ++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index 17c5d201603f..afc047627800 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -159,17 +159,24 @@ static int mei_pxp_component_match(struct device *dev, int subcomponent, { struct device *base = data; + if (!dev) + return 0; + if (!dev->driver || strcmp(dev->driver->name, "i915") || subcomponent != I915_COMPONENT_PXP) return 0; base = base->parent; - if (!base) + if (!base) /* mei device */ return 0; - base = base->parent; - dev = dev->parent; + base = base->parent; /* pci device */ + /* for dgfx */ + if (base && dev == base) + return 1; + /* for pch */ + dev = dev->parent; return (base && dev && dev == base); } -- 2.37.2
[PATCH v4 05/15] mei: pxp: add command streamer API to the PXP driver
From: Vitaly Lubart The discrete graphics card with GSC firmware using command streamer API hence it requires to enhance pxp module with the new gsc_command() handler. The handler is implemented via mei_pxp_gsc_command() which is just a thin wrapper around mei_cldev_send_gsc_command() V2: 1. More detailed commit message 2. Fix typo in the comments V3: Rebase V4: 1. Use forward declaration for struct scatterlist (Jani) 2. Drop double 'just' in the commit message Signed-off-by: Vitaly Lubart Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Greg Kroah-Hartman Reviewed-by: Alan Previn --- drivers/misc/mei/pxp/mei_pxp.c | 28 include/drm/i915_pxp_tee_interface.h | 5 + 2 files changed, 33 insertions(+) diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index 5c39457e3f53..17c5d201603f 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -77,10 +77,38 @@ mei_pxp_receive_message(struct device *dev, void *buffer, size_t size) return byte; } +/** + * mei_pxp_gsc_command() - sends a gsc command, by sending + * a sgl mei message to gsc and receiving reply from gsc + * + * @dev: device corresponding to the mei_cl_device + * @client_id: client id to send the command to + * @fence_id: fence id to send the command to + * @sg_in: scatter gather list containing addresses for rx message buffer + * @total_in_len: total length of data in 'in' sg, can be less than the sum of buffers sizes + * @sg_out: scatter gather list containing addresses for tx message buffer + * + * Return: bytes sent on Success, <0 on Failure + */ +static ssize_t mei_pxp_gsc_command(struct device *dev, u8 client_id, u32 fence_id, + struct scatterlist *sg_in, size_t total_in_len, + struct scatterlist *sg_out) +{ + struct mei_cl_device *cldev; + + if (!dev || !sg_in || !sg_out) + return -EINVAL; + + cldev = to_mei_cl_device(dev); + + return mei_cldev_send_gsc_command(cldev, client_id, fence_id, sg_in, total_in_len, sg_out); +} + static const struct i915_pxp_component_ops mei_pxp_ops = { .owner = THIS_MODULE, .send = mei_pxp_send_message, .recv = mei_pxp_receive_message, + .gsc_command = mei_pxp_gsc_command, }; static int mei_component_master_bind(struct device *dev) diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/i915_pxp_tee_interface.h index af593ec64469..a702b6ec17f7 100644 --- a/include/drm/i915_pxp_tee_interface.h +++ b/include/drm/i915_pxp_tee_interface.h @@ -8,6 +8,7 @@ #include #include +struct scatterlist; /** * struct i915_pxp_component_ops - ops for PXP services. @@ -23,6 +24,10 @@ struct i915_pxp_component_ops { int (*send)(struct device *dev, const void *message, size_t size); int (*recv)(struct device *dev, void *buffer, size_t size); + ssize_t (*gsc_command)(struct device *dev, u8 client_id, u32 fence_id, + struct scatterlist *sg_in, size_t total_in_len, + struct scatterlist *sg_out); + }; /** -- 2.37.2
[PATCH v4 07/15] drm/i915/pxp: load the pxp module when we have a gsc-loaded huc
The mei_pxp module is required to send the command to load authenticate the HuC to the GSC even if pxp is not in use for protected content management. Signed-off-by: Daniele Ceraolo Spurio Cc: Alan Previn Reviewed-by: Alan Previn --- drivers/gpu/drm/i915/Makefile| 10 +++--- drivers/gpu/drm/i915/pxp/intel_pxp.c | 32 +--- drivers/gpu/drm/i915/pxp/intel_pxp.h | 32 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 8 + drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 8 - drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 11 +-- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 10 -- 7 files changed, 57 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 522ef9b4aff3..589823ad62ed 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -307,15 +307,17 @@ i915-y += \ i915-y += i915_perf.o -# Protected execution platform (PXP) support -i915-$(CONFIG_DRM_I915_PXP) += \ +# Protected execution platform (PXP) support. Base support is required for HuC +i915-y += \ pxp/intel_pxp.o \ + pxp/intel_pxp_tee.o + +i915-$(CONFIG_DRM_I915_PXP) += \ pxp/intel_pxp_cmd.o \ pxp/intel_pxp_debugfs.o \ pxp/intel_pxp_irq.o \ pxp/intel_pxp_pm.o \ - pxp/intel_pxp_session.o \ - pxp/intel_pxp_tee.o + pxp/intel_pxp_session.o # Post-mortem debug and GPU hang state capture i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index 17109c513259..b0bcc25bf1ce 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -103,19 +103,15 @@ static int create_vcs_context(struct intel_pxp *pxp) static void destroy_vcs_context(struct intel_pxp *pxp) { - intel_engine_destroy_pinned_context(fetch_and_zero(>ce)); + if (pxp->ce) + intel_engine_destroy_pinned_context(fetch_and_zero(>ce)); } -void intel_pxp_init(struct intel_pxp *pxp) +static void pxp_init_full(struct intel_pxp *pxp) { struct intel_gt *gt = pxp_to_gt(pxp); int ret; - if (!HAS_PXP(gt->i915)) - return; - - mutex_init(>tee_mutex); - /* * we'll use the completion to check if there is a termination pending, * so we start it as completed and we reinit it when a termination @@ -124,8 +120,7 @@ void intel_pxp_init(struct intel_pxp *pxp) init_completion(>termination); complete_all(>termination); - mutex_init(>arb_mutex); - INIT_WORK(>session_work, intel_pxp_session_work); + intel_pxp_session_management_init(pxp); ret = create_vcs_context(pxp); if (ret) @@ -143,11 +138,26 @@ void intel_pxp_init(struct intel_pxp *pxp) destroy_vcs_context(pxp); } -void intel_pxp_fini(struct intel_pxp *pxp) +void intel_pxp_init(struct intel_pxp *pxp) { - if (!intel_pxp_is_enabled(pxp)) + struct intel_gt *gt = pxp_to_gt(pxp); + + /* we rely on the mei PXP module */ + if (!IS_ENABLED(CONFIG_INTEL_MEI_PXP)) return; + /* +* If HuC is loaded by GSC but PXP is disabled, we can skip the init of +* the full PXP session/object management and just init the tee channel. +*/ + if (HAS_PXP(gt->i915)) + pxp_init_full(pxp); + else if (intel_huc_is_loaded_by_gsc(>uc.huc) && intel_uc_uses_huc(>uc)) + intel_pxp_tee_component_init(pxp); +} + +void intel_pxp_fini(struct intel_pxp *pxp) +{ pxp->arb_is_valid = false; intel_pxp_tee_component_fini(pxp); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h index 73847e535cab..2da309088c6d 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h @@ -12,7 +12,6 @@ struct intel_pxp; struct drm_i915_gem_object; -#ifdef CONFIG_DRM_I915_PXP struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp); bool intel_pxp_is_enabled(const struct intel_pxp *pxp); bool intel_pxp_is_active(const struct intel_pxp *pxp); @@ -32,36 +31,5 @@ int intel_pxp_key_check(struct intel_pxp *pxp, bool assign); void intel_pxp_invalidate(struct intel_pxp *pxp); -#else -static inline void intel_pxp_init(struct intel_pxp *pxp) -{ -} - -static inline void intel_pxp_fini(struct intel_pxp *pxp) -{ -} - -static inline int intel_pxp_start(struct intel_pxp *pxp) -{ - return -ENODEV; -} - -static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp) -{ - return false; -} - -static inline bool intel_pxp_is_active(const struct intel_pxp *pxp) -{ - return false; -} - -static inline int intel_pxp_key_check(struct intel_pxp *pxp, - struct drm_i915_gem_object *obj, - bool
[PATCH v4 14/15] drm/i915/huc: define gsc-compatible HuC fw for DG2
The fw name is different and we need to record the fact that the blob is gsc-loaded, so add a new macro to help. Note: A-step DG2 G10 does not support HuC loading via GSC and would require a separate firmware to be loaded the legacy way, but that's not a production stepping so we're not going to bother. v2: rebase on new fw fetch logic Signed-off-by: Daniele Ceraolo Spurio Cc: Tony Ye Reviewed-by: Alan Previn #v1 --- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index 4792960d9c04..09e06ac8bcf1 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -91,7 +91,8 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, fw_def(BROXTON, 0, guc_mmp(bxt, 70, 1, 1)) \ fw_def(SKYLAKE, 0, guc_mmp(skl, 70, 1, 1)) -#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp) \ +#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_raw, huc_mmp, huc_gsc) \ + fw_def(DG2, 0, huc_gsc(dg2)) \ fw_def(ALDERLAKE_P, 0, huc_mmp(tgl, 7, 9, 3)) \ fw_def(ALDERLAKE_S, 0, huc_mmp(tgl, 7, 9, 3)) \ fw_def(DG1, 0, huc_mmp(dg1, 7, 9, 3)) \ @@ -137,6 +138,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, #define MAKE_HUC_FW_PATH_BLANK(prefix_) \ __MAKE_UC_FW_PATH_BLANK(prefix_, "_huc") +#define MAKE_HUC_FW_PATH_GSC(prefix_) \ + __MAKE_UC_FW_PATH_BLANK(prefix_, "_huc_gsc") + #define MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \ __MAKE_UC_FW_PATH_MMP(prefix_, "_huc_", major_, minor_, patch_) @@ -149,7 +153,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw, MODULE_FIRMWARE(uc_); INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH_MAJOR, MAKE_GUC_FW_PATH_MMP) -INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, MAKE_HUC_FW_PATH_MMP) +INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH_BLANK, MAKE_HUC_FW_PATH_MMP, MAKE_HUC_FW_PATH_GSC) /* * The next expansion of the table macros (in __uc_fw_auto_select below) provides @@ -164,6 +168,7 @@ struct __packed uc_fw_blob { u8 major; u8 minor; u8 patch; + bool loaded_via_gsc; }; #define UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \ @@ -172,16 +177,16 @@ struct __packed uc_fw_blob { .patch = patch_, \ .path = path_, -#define UC_FW_BLOB_NEW(major_, minor_, patch_, path_) \ +#define UC_FW_BLOB_NEW(major_, minor_, patch_, gsc_, path_) \ { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \ - .legacy = false } + .legacy = false, .loaded_via_gsc = gsc_ } #define UC_FW_BLOB_OLD(major_, minor_, patch_, path_) \ { UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \ .legacy = true } #define GUC_FW_BLOB(prefix_, major_, minor_) \ - UC_FW_BLOB_NEW(major_, minor_, 0, \ + UC_FW_BLOB_NEW(major_, minor_, 0, false, \ MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_)) #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \ @@ -189,12 +194,15 @@ struct __packed uc_fw_blob { MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)) #define HUC_FW_BLOB(prefix_) \ - UC_FW_BLOB_NEW(0, 0, 0, MAKE_HUC_FW_PATH_BLANK(prefix_)) + UC_FW_BLOB_NEW(0, 0, 0, false, MAKE_HUC_FW_PATH_BLANK(prefix_)) #define HUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \ UC_FW_BLOB_OLD(major_, minor_, patch_, \ MAKE_HUC_FW_PATH_MMP(prefix_, major_, minor_, patch_)) +#define HUC_FW_BLOB_GSC(prefix_) \ + UC_FW_BLOB_NEW(0, 0, 0, true, MAKE_HUC_FW_PATH_GSC(prefix_)) + struct __packed uc_fw_platform_requirement { enum intel_platform p; u8 rev; /* first platform rev using this FW */ @@ -220,7 +228,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP) }; static const struct uc_fw_platform_requirement blobs_huc[] = { - INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP) + INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC) }; static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = { [INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) }, @@ -266,6 +274,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw) uc_fw->file_wanted.path = blob->path; uc_fw->file_wanted.major_ver = blob->major; uc_fw->file_wanted.minor_ver = blob->minor; + uc_fw->loaded_via_gsc = blob->loaded_via_gsc; break; } -- 2.37.2
[PATCH v4 13/15] drm/i915/huc: better define HuC status getparam possible return values.
The current HuC status getparam return values are a bit confusing in regards to what happens in some scenarios. In particular, most of the error cases cause the ioctl to return an error, but a couple of them, INIT_FAIL and LOAD_FAIL, are not explicitly handled and neither is their expected return value documented; these 2 error cases therefore end up into the catch-all umbrella of the "HuC not loaded" case, with this case therefore including both some error scenarios and the load in progress one. The updates included in this patch change the handling so that all error cases behave the same way, i.e. return an errno code, and so that the HuC load in progress case is unambiguous. The patch also includes a small change to the FW init path to make sure we always transition to an error state if something goes wrong. Signed-off-by: Daniele Ceraolo Spurio Cc: Tvrtko Ursulin Cc: Tony Ye Acked-by: Tvrtko Ursulin Acked-by: Tony Ye Reviewed-by: Alan Previn --- drivers/gpu/drm/i915/gt/uc/intel_guc.c | 1 + drivers/gpu/drm/i915/gt/uc/intel_huc.c | 14 +++--- drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 1 - include/uapi/drm/i915_drm.h | 16 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c index 24451d000a6a..bfc5a8d3d603 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c @@ -441,6 +441,7 @@ int intel_guc_init(struct intel_guc *guc) err_fw: intel_uc_fw_fini(>fw); out: + intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_INIT_FAIL); i915_probe_error(gt->i915, "failed with %d\n", ret); return ret; } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index 13d93e69766f..529ddd1e9c06 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -285,6 +285,7 @@ int intel_huc_init(struct intel_huc *huc) return 0; out: + intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_INIT_FAIL); drm_info(>drm, "HuC init failed with %d\n", err); return err; } @@ -404,13 +405,8 @@ bool intel_huc_is_authenticated(struct intel_huc *huc) * This function reads status register to verify if HuC * firmware was successfully loaded. * - * Returns: - * * -ENODEV if HuC is not present on this platform, - * * -EOPNOTSUPP if HuC firmware is disabled, - * * -ENOPKG if HuC firmware was not installed, - * * -ENOEXEC if HuC firmware is invalid or mismatched, - * * 0 if HuC firmware is not running, - * * 1 if HuC firmware is authenticated and running. + * The return values match what is expected for the I915_PARAM_HUC_STATUS + * getparam. */ int intel_huc_check_status(struct intel_huc *huc) { @@ -423,6 +419,10 @@ int intel_huc_check_status(struct intel_huc *huc) return -ENOPKG; case INTEL_UC_FIRMWARE_ERROR: return -ENOEXEC; + case INTEL_UC_FIRMWARE_INIT_FAIL: + return -ENOMEM; + case INTEL_UC_FIRMWARE_LOAD_FAIL: + return -EIO; default: break; } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c index af425916cdf6..4792960d9c04 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c @@ -890,7 +890,6 @@ int intel_uc_fw_init(struct intel_uc_fw *uc_fw) out_unpin: i915_gem_object_unpin_pages(uc_fw->obj); out: - intel_uc_fw_change_status(uc_fw, INTEL_UC_FIRMWARE_INIT_FAIL); return err; } diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index 520ad2691a99..629198f1d8d8 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -645,6 +645,22 @@ typedef struct drm_i915_irq_wait { */ #define I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP (1ul << 5) +/* + * Query the status of HuC load. + * + * The query can fail in the following scenarios with the listed error codes: + * -ENODEV if HuC is not present on this platform, + * -EOPNOTSUPP if HuC firmware usage is disabled, + * -ENOPKG if HuC firmware fetch failed, + * -ENOEXEC if HuC firmware is invalid or mismatched, + * -ENOMEM if i915 failed to prepare the FW objects for transfer to the uC, + * -EIO if the FW transfer or the FW authentication failed. + * + * If the IOCTL is successful, the returned parameter will be set to one of the + * following values: + * * 0 if HuC firmware load is not complete, + * * 1 if HuC firmware is authenticated and running. + */ #define I915_PARAM_HUC_STATUS 42 /* Query whether DRM_I915_GEM_EXECBUFFER2 supports the ability to opt-out of -- 2.37.2
[PATCH v4 11/15] drm/i915/huc: track delayed HuC load with a fence
Given that HuC load is delayed on DG2, this patch adds support for a fence that can be used to wait for load completion. No waiters are added in this patch (they're coming up in the next one), to keep the focus of the patch on the tracking logic. The full HuC loading flow on boot DG2 is as follows: 1) i915 exports the GSC as an aux device; 2) the mei-gsc driver is loaded on the aux device; 3) the mei-pxp component is loaded; 4) mei-pxp calls back into i915 and we load the HuC. Between steps 1 and 2 there can be several seconds of gap, mainly due to the kernel doing other work during the boot. The resume flow is slightly different, because we don't need to re-expose or re-probe the aux device, so we go directly to step 3 once i915 and mei-gsc have completed their resume flow. Here's an example of the boot timing, captured with some logs added to i915: [ 17.908307] [drm] adding GSC device [ 17.915717] [drm] i915 probe done [ 22.282917] [drm] mei-gsc bound [ 22.938153] [drm] HuC authenticated Also to note is that if something goes wrong during GSC HW init the mei-gsc driver will still bind, but steps 3 and 4 will not happen. The status tracking is done by registering a bus_notifier to receive a callback when the mei-gsc driver binds, with a large enough timeout to account for delays. Once mei-gsc is bound, we switch to a smaller timeout to wait for the mei-pxp component to load. The fence is signalled on HuC load complete or if anything goes wrong in any of the tracking steps. Timeout are enforced via hrtimer callbacks. v2: fix includes (Jani) Signed-off-by: Daniele Ceraolo Spurio Reviewed-by: Alan Previn #v1 --- drivers/gpu/drm/i915/gt/intel_gsc.c| 22 ++- drivers/gpu/drm/i915/gt/uc/intel_huc.c | 199 + drivers/gpu/drm/i915/gt/uc/intel_huc.h | 23 +++ 3 files changed, 241 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c index 7af6db3194dd..f544f70401f8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gsc.c +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c @@ -142,8 +142,14 @@ static void gsc_destroy_one(struct drm_i915_private *i915, struct intel_gsc_intf *intf = >intf[intf_id]; if (intf->adev) { - auxiliary_device_delete(>adev->aux_dev); - auxiliary_device_uninit(>adev->aux_dev); + struct auxiliary_device *aux_dev = >adev->aux_dev; + + if (intf_id == 0) + intel_huc_unregister_gsc_notifier(_to_gt(gsc)->uc.huc, + aux_dev->dev.bus); + + auxiliary_device_delete(aux_dev); + auxiliary_device_uninit(aux_dev); intf->adev = NULL; } @@ -242,14 +248,24 @@ static void gsc_init_one(struct drm_i915_private *i915, struct intel_gsc *gsc, goto fail; } + intf->adev = adev; /* needed by the notifier */ + + if (intf_id == 0) + intel_huc_register_gsc_notifier(_to_gt(gsc)->uc.huc, + aux_dev->dev.bus); + ret = auxiliary_device_add(aux_dev); if (ret < 0) { drm_err(>drm, "gsc aux add failed %d\n", ret); + if (intf_id == 0) + intel_huc_unregister_gsc_notifier(_to_gt(gsc)->uc.huc, + aux_dev->dev.bus); + intf->adev = NULL; + /* adev will be freed with the put_device() and .release sequence */ auxiliary_device_uninit(aux_dev); goto fail; } - intf->adev = adev; return; fail: diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index f0188931d8e4..13d93e69766f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -10,6 +10,9 @@ #include "intel_huc.h" #include "i915_drv.h" +#include +#include + /** * DOC: HuC * @@ -42,6 +45,164 @@ * HuC-specific commands. */ +/* + * MEI-GSC load is an async process. The probing of the exposed aux device + * (see intel_gsc.c) usually happens a few seconds after i915 probe, depending + * on when the kernel schedules it. Unless something goes terribly wrong, we're + * guaranteed for this to happen during boot, so the big timeout is a safety net + * that we never expect to need. + * MEI-PXP + HuC load usually takes ~300ms, but if the GSC needs to be resumed + * and/or reset, this can take longer. + */ +#define GSC_INIT_TIMEOUT_MS 1 +#define PXP_INIT_TIMEOUT_MS 2000 + +static int sw_fence_dummy_notify(struct i915_sw_fence *sf, +enum i915_sw_fence_notify state) +{ + return NOTIFY_DONE; +} + +static void __delayed_huc_load_complete(struct intel_huc *huc) +{ + if (!i915_sw_fence_done(>delayed_load.fence)) +
[PATCH v4 08/15] drm/i915/pxp: implement function for sending tee stream command
From: Vitaly Lubart Command to be sent via the stream interface are written to a local memory page, whose address is then provided to the GSC. The interface supports providing a full sg with multiple pages for both input and output messages, but since for now we only aim to support short and synchronous messages we can use a single page for both input and output. Note that the mei interface expects an sg of 4k pages, while our lmem pages are 64k. If we ever need to support more than 4k we'll need to convert. Added a TODO comment to the code to record this. Signed-off-by: Vitaly Lubart Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Rodrigo Vivi Cc: Alan Previn Reviewed-by: Alan Previn --- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 114 - drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 5 + drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 6 ++ 3 files changed, 124 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index 2c1fc49ecec1..e0d09455a92e 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -7,6 +7,7 @@ #include #include +#include "gem/i915_gem_region.h" #include "i915_drv.h" #include "intel_pxp.h" @@ -69,6 +70,47 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp, return ret; } +int intel_pxp_tee_stream_message(struct intel_pxp *pxp, +u8 client_id, u32 fence_id, +void *msg_in, size_t msg_in_len, +void *msg_out, size_t msg_out_len) +{ + /* TODO: for bigger objects we need to use a sg of 4k pages */ + const size_t max_msg_size = PAGE_SIZE; + struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915; + struct i915_pxp_component *pxp_component = pxp->pxp_component; + unsigned int offset = 0; + struct scatterlist *sg; + int ret; + + if (msg_in_len > max_msg_size || msg_out_len > max_msg_size) + return -ENOSPC; + + mutex_lock(>tee_mutex); + + if (unlikely(!pxp_component || !pxp_component->ops->gsc_command)) { + ret = -ENODEV; + goto unlock; + } + + GEM_BUG_ON(!pxp->stream_cmd.obj); + + sg = i915_gem_object_get_sg_dma(pxp->stream_cmd.obj, 0, ); + + memcpy(pxp->stream_cmd.vaddr, msg_in, msg_in_len); + + ret = pxp_component->ops->gsc_command(pxp_component->tee_dev, client_id, + fence_id, sg, msg_in_len, sg); + if (ret < 0) + drm_err(>drm, "Failed to send PXP TEE gsc command\n"); + else + memcpy(msg_out, pxp->stream_cmd.vaddr, msg_out_len); + +unlock: + mutex_unlock(>tee_mutex); + return ret; +} + /** * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee * @i915_kdev: pointer to i915 kernel device @@ -126,6 +168,66 @@ static const struct component_ops i915_pxp_tee_component_ops = { .unbind = i915_pxp_tee_component_unbind, }; +static int alloc_streaming_command(struct intel_pxp *pxp) +{ + struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915; + struct drm_i915_gem_object *obj = NULL; + void *cmd; + int err; + + pxp->stream_cmd.obj = NULL; + pxp->stream_cmd.vaddr = NULL; + + if (!IS_DGFX(i915)) + return 0; + + /* allocate lmem object of one page for PXP command memory and store it */ + obj = i915_gem_object_create_lmem(i915, PAGE_SIZE, I915_BO_ALLOC_CONTIGUOUS); + if (IS_ERR(obj)) { + drm_err(>drm, "Failed to allocate pxp streaming command!\n"); + return PTR_ERR(obj); + } + + err = i915_gem_object_pin_pages_unlocked(obj); + if (err) { + drm_err(>drm, "Failed to pin gsc message page!\n"); + goto out_put; + } + + /* map the lmem into the virtual memory pointer */ + cmd = i915_gem_object_pin_map_unlocked(obj, i915_coherent_map_type(i915, obj, true)); + if (IS_ERR(cmd)) { + drm_err(>drm, "Failed to map gsc message page!\n"); + err = PTR_ERR(cmd); + goto out_unpin; + } + + memset(cmd, 0, obj->base.size); + + pxp->stream_cmd.obj = obj; + pxp->stream_cmd.vaddr = cmd; + + return 0; + +out_unpin: + i915_gem_object_unpin_pages(obj); +out_put: + i915_gem_object_put(obj); + return err; +} + +static void free_streaming_command(struct intel_pxp *pxp) +{ + struct drm_i915_gem_object *obj = fetch_and_zero(>stream_cmd.obj); + + if (!obj) + return; + + i915_gem_object_unpin_map(obj); + i915_gem_object_unpin_pages(obj); + i915_gem_object_put(obj); +} + int intel_pxp_tee_component_init(struct intel_pxp *pxp) { int ret; @@ -134,16 +236,24 @@ int
[PATCH v4 04/15] mei: bus: extend bus API to support command streamer API
From: Vitaly Lubart Add mei bus API for sending gsc commands: mei_cldev_send_gsc_command() The GSC commands are originated in the graphics stack and are in form of SGL DMA buffers. The GSC commands are synchronous, the response is received in the same call on the out sg list buffers. The function setups pointers for in and out sg lists in the mei sgl extended header and sends it to the firmware. V2: 1. More detailed commit message 2. Fix typo in the comments Signed-off-by: Vitaly Lubart Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 125 + include/linux/mei_cl_bus.h | 6 ++ 2 files changed, 131 insertions(+) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 225f0b04c021..fc885ba94b36 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -838,6 +838,131 @@ int mei_cldev_disable(struct mei_cl_device *cldev) } EXPORT_SYMBOL_GPL(mei_cldev_disable); +/** + * mei_cldev_send_gsc_command - sends a gsc command, by sending + * a gsl mei message to gsc and receiving reply from gsc + * + * @cldev: me client device + * @client_id: client id to send the command to + * @fence_id: fence id to send the command to + * @sg_in: scatter gather list containing addresses for rx message buffer + * @total_in_len: total length of data in 'in' sg, can be less than the sum of buffers sizes + * @sg_out: scatter gather list containing addresses for tx message buffer + * + * Return: + * * written size in bytes + * * < 0 on error + */ +ssize_t mei_cldev_send_gsc_command(struct mei_cl_device *cldev, + u8 client_id, u32 fence_id, + struct scatterlist *sg_in, + size_t total_in_len, + struct scatterlist *sg_out) +{ + struct mei_cl *cl; + struct mei_device *bus; + ssize_t ret = 0; + + struct mei_ext_hdr_gsc_h2f *ext_hdr; + size_t buf_sz = sizeof(struct mei_ext_hdr_gsc_h2f); + int sg_out_nents, sg_in_nents; + int i; + struct scatterlist *sg; + struct mei_ext_hdr_gsc_f2h rx_msg; + unsigned int sg_len; + + if (!cldev || !sg_in || !sg_out) + return -EINVAL; + + cl = cldev->cl; + bus = cldev->bus; + + dev_dbg(bus->dev, "client_id %u, fence_id %u\n", client_id, fence_id); + + if (!bus->hbm_f_gsc_supported) + return -EOPNOTSUPP; + + sg_out_nents = sg_nents(sg_out); + sg_in_nents = sg_nents(sg_in); + /* at least one entry in tx and rx sgls must be present */ + if (sg_out_nents <= 0 || sg_in_nents <= 0) + return -EINVAL; + + buf_sz += (sg_out_nents + sg_in_nents) * sizeof(struct mei_gsc_sgl); + ext_hdr = kzalloc(buf_sz, GFP_KERNEL); + if (!ext_hdr) + return -ENOMEM; + + /* construct the GSC message */ + ext_hdr->hdr.type = MEI_EXT_HDR_GSC; + ext_hdr->hdr.length = buf_sz / sizeof(u32); /* length is in dw */ + + ext_hdr->client_id = client_id; + ext_hdr->addr_type = GSC_ADDRESS_TYPE_PHYSICAL_SGL; + ext_hdr->fence_id = fence_id; + ext_hdr->input_address_count = sg_in_nents; + ext_hdr->output_address_count = sg_out_nents; + ext_hdr->reserved[0] = 0; + ext_hdr->reserved[1] = 0; + + /* copy in-sgl to the message */ + for (i = 0, sg = sg_in; i < sg_in_nents; i++, sg++) { + ext_hdr->sgl[i].low = lower_32_bits(sg_dma_address(sg)); + ext_hdr->sgl[i].high = upper_32_bits(sg_dma_address(sg)); + sg_len = min_t(unsigned int, sg_dma_len(sg), PAGE_SIZE); + ext_hdr->sgl[i].length = (sg_len <= total_in_len) ? sg_len : total_in_len; + total_in_len -= ext_hdr->sgl[i].length; + } + + /* copy out-sgl to the message */ + for (i = sg_in_nents, sg = sg_out; i < sg_in_nents + sg_out_nents; i++, sg++) { + ext_hdr->sgl[i].low = lower_32_bits(sg_dma_address(sg)); + ext_hdr->sgl[i].high = upper_32_bits(sg_dma_address(sg)); + sg_len = min_t(unsigned int, sg_dma_len(sg), PAGE_SIZE); + ext_hdr->sgl[i].length = sg_len; + } + + /* send the message to GSC */ + ret = __mei_cl_send(cl, (u8 *)ext_hdr, buf_sz, 0, MEI_CL_IO_SGL); + if (ret < 0) { + dev_err(bus->dev, "__mei_cl_send failed, returned %zd\n", ret); + goto end; + } + if (ret != buf_sz) { + dev_err(bus->dev, "__mei_cl_send returned %zd instead of expected %zd\n", + ret, buf_sz); + ret = -EIO; + goto end; + } + + /* receive the reply from GSC, note that at this point sg_in should contain the reply */ + ret = __mei_cl_recv(cl, (u8 *)_msg, sizeof(rx_msg), NULL, MEI_CL_IO_SGL, 0); + + if (ret
[PATCH v4 01/15] mei: add support to GSC extended header
From: Tomas Winkler GSC extend header is of variable size and data is provided in a sgl list inside the header and not in the data buffers, need to enable the path. V2: 1. Add missing kdoc for mei_cl_cb 2. In mei_me_hbuf_write() use dev_err() when validationg parameters instead of WARN_ON() Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Vitaly Lubart Cc: Greg Kroah-Hartman --- drivers/misc/mei/client.c| 55 -- drivers/misc/mei/hbm.c | 13 drivers/misc/mei/hw-me.c | 7 - drivers/misc/mei/hw.h| 57 drivers/misc/mei/interrupt.c | 47 - drivers/misc/mei/mei_dev.h | 4 +++ 6 files changed, 160 insertions(+), 23 deletions(-) diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 0b2fbe1335a7..6c8b71ae32c8 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -322,6 +322,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb) list_del(>list); kfree(cb->buf.data); + kfree(cb->ext_hdr); kfree(cb); } @@ -401,6 +402,7 @@ static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, cb->buf_idx = 0; cb->fop_type = type; cb->vtag = 0; + cb->ext_hdr = NULL; return cb; } @@ -1740,6 +1742,17 @@ static inline u8 mei_ext_hdr_set_vtag(void *ext, u8 vtag) return vtag_hdr->hdr.length; } +static inline bool mei_ext_hdr_is_gsc(struct mei_ext_hdr *ext) +{ + return ext && ext->type == MEI_EXT_HDR_GSC; +} + +static inline u8 mei_ext_hdr_set_gsc(struct mei_ext_hdr *ext, struct mei_ext_hdr *gsc_hdr) +{ + memcpy(ext, gsc_hdr, mei_ext_hdr_len(gsc_hdr)); + return ext->length; +} + /** * mei_msg_hdr_init - allocate and initialize mei message header * @@ -1752,14 +1765,17 @@ static struct mei_msg_hdr *mei_msg_hdr_init(const struct mei_cl_cb *cb) size_t hdr_len; struct mei_ext_meta_hdr *meta; struct mei_msg_hdr *mei_hdr; - bool is_ext, is_vtag; + bool is_ext, is_hbm, is_gsc, is_vtag; + struct mei_ext_hdr *next_ext; if (!cb) return ERR_PTR(-EINVAL); /* Extended header for vtag is attached only on the first fragment */ is_vtag = (cb->vtag && cb->buf_idx == 0); - is_ext = is_vtag; + is_hbm = cb->cl->me_cl->client_id == 0; + is_gsc = ((!is_hbm) && cb->cl->dev->hbm_f_gsc_supported && mei_ext_hdr_is_gsc(cb->ext_hdr)); + is_ext = is_vtag || is_gsc; /* Compute extended header size */ hdr_len = sizeof(*mei_hdr); @@ -1771,6 +1787,9 @@ static struct mei_msg_hdr *mei_msg_hdr_init(const struct mei_cl_cb *cb) if (is_vtag) hdr_len += sizeof(struct mei_ext_hdr_vtag); + if (is_gsc) + hdr_len += mei_ext_hdr_len(cb->ext_hdr); + setup_hdr: mei_hdr = kzalloc(hdr_len, GFP_KERNEL); if (!mei_hdr) @@ -1785,10 +1804,20 @@ static struct mei_msg_hdr *mei_msg_hdr_init(const struct mei_cl_cb *cb) goto out; meta = (struct mei_ext_meta_hdr *)mei_hdr->extension; + meta->size = 0; + next_ext = (struct mei_ext_hdr *)meta->hdrs; if (is_vtag) { meta->count++; - meta->size += mei_ext_hdr_set_vtag(meta->hdrs, cb->vtag); + meta->size += mei_ext_hdr_set_vtag(next_ext, cb->vtag); + next_ext = mei_ext_next(next_ext); + } + + if (is_gsc) { + meta->count++; + meta->size += mei_ext_hdr_set_gsc(next_ext, cb->ext_hdr); + next_ext = mei_ext_next(next_ext); } + out: mei_hdr->length = hdr_len - sizeof(*mei_hdr); return mei_hdr; @@ -1812,14 +1841,14 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, struct mei_msg_hdr *mei_hdr = NULL; size_t hdr_len; size_t hbuf_len, dr_len; - size_t buf_len; + size_t buf_len = 0; size_t data_len; int hbuf_slots; u32 dr_slots; u32 dma_len; int rets; bool first_chunk; - const void *data; + const void *data = NULL; if (WARN_ON(!cl || !cl->dev)) return -ENODEV; @@ -1839,8 +1868,10 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, return 0; } - buf_len = buf->size - cb->buf_idx; - data = buf->data + cb->buf_idx; + if (buf->data) { + buf_len = buf->size - cb->buf_idx; + data = buf->data + cb->buf_idx; + } hbuf_slots = mei_hbuf_empty_slots(dev); if (hbuf_slots < 0) { rets = -EOVERFLOW; @@ -1858,9 +1889,6 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb, goto err; } - cl_dbg(dev, cl, "Extended Header %d vtag = %d\n", - mei_hdr->extended, cb->vtag); - hdr_len =
[PATCH v4 10/15] drm/i915/dg2: setup HuC loading via GSC
The GSC will perform both the load and the authentication, so we just need to check the auth bit after the GSC has replied. Since we require the PXP module to load the HuC, the earliest we can trigger the load is during the pxp_bind operation. Note that GSC-loaded HuC survives GT reset, so we need to just mark it as ready when we re-init the GT HW. V2: move setting of HuC fw error state to the failure path of the HuC auth function, so it covers both the legacy and new auth flows V4: 1. Fix typo in the commit message 2. style fix in intel_huc_wait_for_auth_complete() Signed-off-by: Daniele Ceraolo Spurio Signed-off-by: Vitaly Lubart Signed-off-by: Tomas Winkler Reviewed-by: Alan Previn #v2 --- drivers/gpu/drm/i915/gt/uc/intel_huc.c| 41 +++ drivers/gpu/drm/i915/gt/uc/intel_huc.h| 2 ++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 34 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 1 + drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 14 +++- 5 files changed, 77 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c index 3bb8838e325a..f0188931d8e4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c @@ -125,6 +125,28 @@ void intel_huc_fini(struct intel_huc *huc) intel_uc_fw_fini(>fw); } +int intel_huc_wait_for_auth_complete(struct intel_huc *huc) +{ + struct intel_gt *gt = huc_to_gt(huc); + int ret; + + ret = __intel_wait_for_register(gt->uncore, + huc->status.reg, + huc->status.mask, + huc->status.value, + 2, 50, NULL); + + if (ret) { + drm_err(>i915->drm, "HuC: Firmware not verified %d\n", ret); + intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_LOAD_FAIL); + return ret; + } + + intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_RUNNING); + drm_info(>i915->drm, "HuC authenticated\n"); + return 0; +} + /** * intel_huc_auth() - Authenticate HuC uCode * @huc: intel_huc structure @@ -161,27 +183,18 @@ int intel_huc_auth(struct intel_huc *huc) } /* Check authentication status, it should be done by now */ - ret = __intel_wait_for_register(gt->uncore, - huc->status.reg, - huc->status.mask, - huc->status.value, - 2, 50, NULL); - if (ret) { - DRM_ERROR("HuC: Firmware not verified %d\n", ret); + ret = intel_huc_wait_for_auth_complete(huc); + if (ret) goto fail; - } - intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_RUNNING); - drm_info(>i915->drm, "HuC authenticated\n"); return 0; fail: i915_probe_error(gt->i915, "HuC: Authentication failed %d\n", ret); - intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_LOAD_FAIL); return ret; } -static bool huc_is_authenticated(struct intel_huc *huc) +bool intel_huc_is_authenticated(struct intel_huc *huc) { struct intel_gt *gt = huc_to_gt(huc); intel_wakeref_t wakeref; @@ -223,7 +236,7 @@ int intel_huc_check_status(struct intel_huc *huc) break; } - return huc_is_authenticated(huc); + return intel_huc_is_authenticated(huc); } void intel_huc_update_auth_status(struct intel_huc *huc) @@ -231,7 +244,7 @@ void intel_huc_update_auth_status(struct intel_huc *huc) if (!intel_uc_fw_is_loadable(>fw)) return; - if (huc_is_authenticated(huc)) + if (intel_huc_is_authenticated(huc)) intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_RUNNING); } diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h index d7e25b6e879e..51f9d96a3ca3 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h @@ -26,8 +26,10 @@ void intel_huc_init_early(struct intel_huc *huc); int intel_huc_init(struct intel_huc *huc); void intel_huc_fini(struct intel_huc *huc); int intel_huc_auth(struct intel_huc *huc); +int intel_huc_wait_for_auth_complete(struct intel_huc *huc); int intel_huc_check_status(struct intel_huc *huc); void intel_huc_update_auth_status(struct intel_huc *huc); +bool intel_huc_is_authenticated(struct intel_huc *huc); static inline int intel_huc_sanitize(struct intel_huc *huc) { diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c index 9d6ab1e01639..4f246416db17 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c @@ -3,9 +3,43 @@ * Copyright © 2014-2019 Intel Corporation */
[PATCH v4 02/15] mei: bus: enable sending gsc commands
From: Tomas Winkler GSC command is and extended header containing a scatter gather list and without a data buffer. Using MEI_CL_IO_SGL flag, the caller send the GSC command as a data and the function internally moves it to the extended header. Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Vitaly Lubart Cc: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 20 ++-- drivers/misc/mei/mei_dev.h | 4 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 46aa3554e97b..225f0b04c021 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -100,9 +100,18 @@ ssize_t __mei_cl_send(struct mei_cl *cl, const u8 *buf, size_t length, u8 vtag, cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL); cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING); memcpy(cb->buf.data, buf, length); + /* hack we point data to header */ + if (mode & MEI_CL_IO_SGL) { + cb->ext_hdr = (struct mei_ext_hdr *)cb->buf.data; + cb->buf.data = NULL; + cb->buf.size = 0; + } rets = mei_cl_write(cl, cb); + if (mode & MEI_CL_IO_SGL && rets == 0) + rets = length; + out: mutex_unlock(>device_lock); @@ -205,9 +214,16 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, goto free; } - r_length = min_t(size_t, length, cb->buf_idx); - memcpy(buf, cb->buf.data, r_length); + /* for the GSC type - copy the extended header to the buffer */ + if (cb->ext_hdr && cb->ext_hdr->type == MEI_EXT_HDR_GSC) { + r_length = min_t(size_t, length, cb->ext_hdr->length * sizeof(u32)); + memcpy(buf, cb->ext_hdr, r_length); + } else { + r_length = min_t(size_t, length, cb->buf_idx); + memcpy(buf, cb->buf.data, r_length); + } rets = r_length; + if (vtag) *vtag = cb->vtag; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 31784bbc2d2a..8d8018428d9d 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -116,12 +116,16 @@ enum mei_cb_file_ops { * @MEI_CL_IO_TX_INTERNAL: internal communication between driver and FW * * @MEI_CL_IO_RX_NONBLOCK: recv is non-blocking + * + * @MEI_CL_IO_SGL: send command with sgl list. */ enum mei_cl_io_mode { MEI_CL_IO_TX_BLOCKING = BIT(0), MEI_CL_IO_TX_INTERNAL = BIT(1), MEI_CL_IO_RX_NONBLOCK = BIT(2), + + MEI_CL_IO_SGL = BIT(3), }; /* -- 2.37.2
[PATCH v4 03/15] mei: adjust extended header kdocs
From: Tomas Winkler Fix kdoc for struct mei_ext_hdr and mei_ext_begin(). V4: New in the series Signed-off-by: Tomas Winkler Signed-off-by: Daniele Ceraolo Spurio Cc: Greg Kroah-Hartman --- drivers/misc/mei/hw.h | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 14f89d96216b..25bfdd28cf3f 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -247,8 +247,7 @@ enum mei_ext_hdr_type { * struct mei_ext_hdr - extend header descriptor (TLV) * @type: enum mei_ext_hdr_type * @length: length excluding descriptor - * @ext_payload: payload of the specific extended header - * @hdr: place holder for actual header + * @data: the extended header payload */ struct mei_ext_hdr { u8 type; @@ -287,12 +286,11 @@ struct mei_ext_hdr_vtag { * Extended header iterator functions */ /** - * mei_ext_hdr - extended header iterator begin + * mei_ext_begin - extended header iterator begin * * @meta: meta header of the extended header list * - * Return: - * The first extended header + * Return: The first extended header */ static inline struct mei_ext_hdr *mei_ext_begin(struct mei_ext_meta_hdr *meta) { -- 2.37.2
[PATCH v4 00/15] drm/i915: HuC loading for DG2
On DG2, HuC loading is performed by the GSC, via a PXP command. The load operation itself is relatively simple (just send a message to the GSC with the physical address of the HuC in LMEM), but there are timing changes that requires special attention. In particular, to send a PXP command we need to first export the GSC as an aux device and then wait for the mei-gsc and mei-pxp modules to start, which means that HuC load will complete after i915 load is complete. This means that there is a small window of time after i915 is registered and before HuC is loaded during which userspace could submit and/or check the HuC load status, although this is quite unlikely to happen (HuC is usually loaded before kernel init/resume completes). We've consulted with the media team in regards to how to handle this and they've asked us to stall all userspace VCS submission until HuC is loaded. Stalls are expected to be very rare (if any), due to the fact that HuC is usually loaded before kernel init/resume is completed. Timeouts are in place to ensure all submissions are unlocked in case something goes wrong. Since we need to monitor the status of the mei driver to know what's happening and when to time out, a notifier has been added so we get a callback when the status of the mei driver changes. Note that this series includes several mei patches that add support for sending the HuC loading command via mei-gsc. We plan to merge those patches through the drm tree because i915 is the sole user. v2: address review comments, Reporting HuC loading still in progress while we wait for mei-gsc init to complete, rebase on latest mei-gsc series. v3: fix cc list in mei patches. v4: update mei patches, fix includes, rebase on new FW fetch logic and merged mei-gsc support. Test-with: 20220818224216.3920822-1-daniele.ceraolospu...@intel.com Cc: Alan Previn Cc: Tony Ye Cc: Alexander Usyskin Cc: Tomas Winkler Cc: Greg Kroah-Hartman Daniele Ceraolo Spurio (7): drm/i915/pxp: load the pxp module when we have a gsc-loaded huc drm/i915/dg2: setup HuC loading via GSC drm/i915/huc: track delayed HuC load with a fence drm/i915/huc: stall media submission until HuC is loaded drm/i915/huc: better define HuC status getparam possible return values. drm/i915/huc: define gsc-compatible HuC fw for DG2 HAX: drm/i915: force INTEL_MEI_GSC and INTEL_MEI_PXP on for CI Tomas Winkler (5): mei: add support to GSC extended header mei: bus: enable sending gsc commands mei: adjust extended header kdocs mei: pxp: support matching with a gfx discrete card drm/i915/pxp: add huc authentication and loading command Vitaly Lubart (3): mei: bus: extend bus API to support command streamer API mei: pxp: add command streamer API to the PXP driver drm/i915/pxp: implement function for sending tee stream command drivers/gpu/drm/i915/Kconfig.debug| 2 + drivers/gpu/drm/i915/Makefile | 11 +- drivers/gpu/drm/i915/gt/intel_gsc.c | 22 +- drivers/gpu/drm/i915/gt/uc/intel_guc.c| 1 + drivers/gpu/drm/i915/gt/uc/intel_huc.c| 254 -- drivers/gpu/drm/i915/gt/uc/intel_huc.h| 31 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 34 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 1 + drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 24 +- drivers/gpu/drm/i915/i915_request.c | 24 ++ drivers/gpu/drm/i915/pxp/intel_pxp.c | 32 ++- drivers/gpu/drm/i915/pxp/intel_pxp.h | 32 --- drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 69 + drivers/gpu/drm/i915/pxp/intel_pxp_huc.h | 13 + drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 8 + drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 8 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 11 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 138 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 5 + .../drm/i915/pxp/intel_pxp_tee_interface.h| 23 +- drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 6 + drivers/misc/mei/bus.c| 145 +- drivers/misc/mei/client.c | 55 ++-- drivers/misc/mei/hbm.c| 13 + drivers/misc/mei/hw-me.c | 7 +- drivers/misc/mei/hw.h | 65 - drivers/misc/mei/interrupt.c | 47 +++- drivers/misc/mei/mei_dev.h| 8 + drivers/misc/mei/pxp/mei_pxp.c| 41 ++- include/drm/i915_pxp_tee_interface.h | 5 + include/linux/mei_cl_bus.h| 6 + include/uapi/drm/i915_drm.h | 16 ++ 32 files changed, 1035 insertions(+), 122 deletions(-) create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.h -- 2.37.2
Re: [PATCH v4 00/15]
Please ignore this cover letter, I've only realized I was missing a title and aborted the git-send after sending it. Proper series coming in a couple of mins. Daniele On 9/8/2022 5:10 PM, Daniele Ceraolo Spurio wrote: On DG2, HuC loading is performed by the GSC, via a PXP command. The load operation itself is relatively simple (just send a message to the GSC with the physical address of the HuC in LMEM), but there are timing changes that requires special attention. In particular, to send a PXP command we need to first export the GSC as an aux device and then wait for the mei-gsc and mei-pxp modules to start, which means that HuC load will complete after i915 load is complete. This means that there is a small window of time after i915 is registered and before HuC is loaded during which userspace could submit and/or check the HuC load status, although this is quite unlikely to happen (HuC is usually loaded before kernel init/resume completes). We've consulted with the media team in regards to how to handle this and they've asked us to stall all userspace VCS submission until HuC is loaded. Stalls are expected to be very rare (if any), due to the fact that HuC is usually loaded before kernel init/resume is completed. Timeouts are in place to ensure all submissions are unlocked in case something goes wrong. Since we need to monitor the status of the mei driver to know what's happening and when to time out, a notifier has been added so we get a callback when the status of the mei driver changes. Note that this series includes several mei patches that add support for sending the HuC loading command via mei-gsc. We plan to merge those patches through the drm tree because i915 is the sole user. v2: address review comments, Reporting HuC loading still in progress while we wait for mei-gsc init to complete, rebase on latest mei-gsc series. v3: fix cc list in mei patches. v4: update mei patches, fix includes, rebase on new FW fetch logic and merged mei-gsc support. Test-with: 20220818224216.3920822-1-daniele.ceraolospu...@intel.com Cc: Alan Previn Cc: Tony Ye Cc: Alexander Usyskin Cc: Tomas Winkler Cc: Greg Kroah-Hartman Daniele Ceraolo Spurio (7): drm/i915/pxp: load the pxp module when we have a gsc-loaded huc drm/i915/dg2: setup HuC loading via GSC drm/i915/huc: track delayed HuC load with a fence drm/i915/huc: stall media submission until HuC is loaded drm/i915/huc: better define HuC status getparam possible return values. drm/i915/huc: define gsc-compatible HuC fw for DG2 HAX: drm/i915: force INTEL_MEI_GSC and INTEL_MEI_PXP on for CI Tomas Winkler (5): mei: add support to GSC extended header mei: bus: enable sending gsc commands mei: adjust extended header kdocs mei: pxp: support matching with a gfx discrete card drm/i915/pxp: add huc authentication and loading command Vitaly Lubart (3): mei: bus: extend bus API to support command streamer API mei: pxp: add command streamer API to the PXP driver drm/i915/pxp: implement function for sending tee stream command drivers/gpu/drm/i915/Kconfig.debug| 2 + drivers/gpu/drm/i915/Makefile | 11 +- drivers/gpu/drm/i915/gt/intel_gsc.c | 22 +- drivers/gpu/drm/i915/gt/uc/intel_guc.c| 1 + drivers/gpu/drm/i915/gt/uc/intel_huc.c| 254 -- drivers/gpu/drm/i915/gt/uc/intel_huc.h| 31 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 34 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 1 + drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 24 +- drivers/gpu/drm/i915/i915_request.c | 24 ++ drivers/gpu/drm/i915/pxp/intel_pxp.c | 32 ++- drivers/gpu/drm/i915/pxp/intel_pxp.h | 32 --- drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 69 + drivers/gpu/drm/i915/pxp/intel_pxp_huc.h | 13 + drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 8 + drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 8 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 11 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 138 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 5 + .../drm/i915/pxp/intel_pxp_tee_interface.h| 23 +- drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 6 + drivers/misc/mei/bus.c| 145 +- drivers/misc/mei/client.c | 55 ++-- drivers/misc/mei/hbm.c| 13 + drivers/misc/mei/hw-me.c | 7 +- drivers/misc/mei/hw.h | 65 - drivers/misc/mei/interrupt.c | 47 +++- drivers/misc/mei/mei_dev.h| 8 + drivers/misc/mei/pxp/mei_pxp.c| 41 ++- include/drm/i915_pxp_tee_interface.h | 5 + include/linux/mei_cl_bus.h| 6 + include/uapi/drm/i915_drm.h | 16 ++ 32 files changed, 1035 insertions(+), 122 deletions(-)
[PATCH v4 00/15]
On DG2, HuC loading is performed by the GSC, via a PXP command. The load operation itself is relatively simple (just send a message to the GSC with the physical address of the HuC in LMEM), but there are timing changes that requires special attention. In particular, to send a PXP command we need to first export the GSC as an aux device and then wait for the mei-gsc and mei-pxp modules to start, which means that HuC load will complete after i915 load is complete. This means that there is a small window of time after i915 is registered and before HuC is loaded during which userspace could submit and/or check the HuC load status, although this is quite unlikely to happen (HuC is usually loaded before kernel init/resume completes). We've consulted with the media team in regards to how to handle this and they've asked us to stall all userspace VCS submission until HuC is loaded. Stalls are expected to be very rare (if any), due to the fact that HuC is usually loaded before kernel init/resume is completed. Timeouts are in place to ensure all submissions are unlocked in case something goes wrong. Since we need to monitor the status of the mei driver to know what's happening and when to time out, a notifier has been added so we get a callback when the status of the mei driver changes. Note that this series includes several mei patches that add support for sending the HuC loading command via mei-gsc. We plan to merge those patches through the drm tree because i915 is the sole user. v2: address review comments, Reporting HuC loading still in progress while we wait for mei-gsc init to complete, rebase on latest mei-gsc series. v3: fix cc list in mei patches. v4: update mei patches, fix includes, rebase on new FW fetch logic and merged mei-gsc support. Test-with: 20220818224216.3920822-1-daniele.ceraolospu...@intel.com Cc: Alan Previn Cc: Tony Ye Cc: Alexander Usyskin Cc: Tomas Winkler Cc: Greg Kroah-Hartman Daniele Ceraolo Spurio (7): drm/i915/pxp: load the pxp module when we have a gsc-loaded huc drm/i915/dg2: setup HuC loading via GSC drm/i915/huc: track delayed HuC load with a fence drm/i915/huc: stall media submission until HuC is loaded drm/i915/huc: better define HuC status getparam possible return values. drm/i915/huc: define gsc-compatible HuC fw for DG2 HAX: drm/i915: force INTEL_MEI_GSC and INTEL_MEI_PXP on for CI Tomas Winkler (5): mei: add support to GSC extended header mei: bus: enable sending gsc commands mei: adjust extended header kdocs mei: pxp: support matching with a gfx discrete card drm/i915/pxp: add huc authentication and loading command Vitaly Lubart (3): mei: bus: extend bus API to support command streamer API mei: pxp: add command streamer API to the PXP driver drm/i915/pxp: implement function for sending tee stream command drivers/gpu/drm/i915/Kconfig.debug| 2 + drivers/gpu/drm/i915/Makefile | 11 +- drivers/gpu/drm/i915/gt/intel_gsc.c | 22 +- drivers/gpu/drm/i915/gt/uc/intel_guc.c| 1 + drivers/gpu/drm/i915/gt/uc/intel_huc.c| 254 -- drivers/gpu/drm/i915/gt/uc/intel_huc.h| 31 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.c | 34 +++ drivers/gpu/drm/i915/gt/uc/intel_huc_fw.h | 1 + drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 24 +- drivers/gpu/drm/i915/i915_request.c | 24 ++ drivers/gpu/drm/i915/pxp/intel_pxp.c | 32 ++- drivers/gpu/drm/i915/pxp/intel_pxp.h | 32 --- drivers/gpu/drm/i915/pxp/intel_pxp_huc.c | 69 + drivers/gpu/drm/i915/pxp/intel_pxp_huc.h | 13 + drivers/gpu/drm/i915/pxp/intel_pxp_irq.h | 8 + drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 8 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.h | 11 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 138 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.h | 5 + .../drm/i915/pxp/intel_pxp_tee_interface.h| 23 +- drivers/gpu/drm/i915/pxp/intel_pxp_types.h| 6 + drivers/misc/mei/bus.c| 145 +- drivers/misc/mei/client.c | 55 ++-- drivers/misc/mei/hbm.c| 13 + drivers/misc/mei/hw-me.c | 7 +- drivers/misc/mei/hw.h | 65 - drivers/misc/mei/interrupt.c | 47 +++- drivers/misc/mei/mei_dev.h| 8 + drivers/misc/mei/pxp/mei_pxp.c| 41 ++- include/drm/i915_pxp_tee_interface.h | 5 + include/linux/mei_cl_bus.h| 6 + include/uapi/drm/i915_drm.h | 16 ++ 32 files changed, 1035 insertions(+), 122 deletions(-) create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.c create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_huc.h -- 2.37.2
Re: [PATCH v3.1 10/14] drm/i915/uncore: Add GSI offset to uncore
On 9/8/2022 3:45 PM, Matt Roper wrote: GT non-engine registers (referred to as "GSI" registers by the spec) have the same relative offsets on standalone media as they do on the primary GT, just with an additional "GSI offset" added to their MMIO address. If we store this GSI offset in the standalone media's intel_uncore structure, it can be automatically applied to all GSI reg reads/writes that happen on that GT, allowing us to re-use our existing GT code with minimal changes. Forcewake and shadowed register tables for the media GT (which will be added in a future patch) are listed as final addresses that already include the GSI offset, so we also need to add the GSI offset before doing lookups of registers in one of those tables. v2: - Add comment on raw_reg_*() macros explaining why we don't bother with GSI offsets in them. (Daniele) Cc: Daniele Ceraolo Spurio Signed-off-by: Matt Roper Reviewed-by: Daniele Ceraolo Spurio Daniele --- drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 + drivers/gpu/drm/i915/intel_uncore.c | 10 +-- drivers/gpu/drm/i915/intel_uncore.h | 34 ++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h index 0e139f7d75ed..82dc28643572 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -274,6 +274,7 @@ struct intel_gt_definition { enum intel_gt_type type; char *name; u32 mapping_base; + u32 gsi_offset; intel_engine_mask_t engine_mask; }; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 452b3a31e965..5cd423c7b646 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -928,6 +928,9 @@ find_fw_domain(struct intel_uncore *uncore, u32 offset) { const struct intel_forcewake_range *entry; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + entry = BSEARCH(offset, uncore->fw_domains_table, uncore->fw_domains_table_entries, @@ -1143,6 +1146,9 @@ static bool is_shadowed(struct intel_uncore *uncore, u32 offset) if (drm_WARN_ON(>i915->drm, !uncore->shadowed_reg_table)) return false; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + return BSEARCH(offset, uncore->shadowed_reg_table, uncore->shadowed_reg_table_entries, @@ -1995,8 +2001,8 @@ static int __fw_domain_init(struct intel_uncore *uncore, d->uncore = uncore; d->wake_count = 0; - d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set); - d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack); + d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set) + uncore->gsi_offset; + d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack) + uncore->gsi_offset; d->id = domain_id; diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 4acb78a03233..5022bac80b67 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -136,6 +136,16 @@ struct intel_uncore { spinlock_t lock; /** lock is also taken in irq contexts. */ + /* +* Do we need to apply an additional offset to reach the beginning +* of the basic non-engine GT registers (referred to as "GSI" on +* newer platforms, or "GT block" on older platforms)? If so, we'll +* track that here and apply it transparently to registers in the +* appropriate range to maintain compatibility with our existing +* register definitions and GT code. +*/ + u32 gsi_offset; + unsigned int flags; #define UNCORE_HAS_FORCEWAKE BIT(0) #define UNCORE_HAS_FPGA_DBG_UNCLAIMED BIT(1) @@ -294,19 +304,27 @@ intel_wait_for_register_fw(struct intel_uncore *uncore, 2, timeout_ms, NULL); } +#define IS_GSI_REG(reg) ((reg) < 0x4) + /* register access functions */ #define __raw_read(x__, s__) \ static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore *uncore, \ i915_reg_t reg) \ { \ - return read##s__(uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if (IS_GSI_REG(offset)) \ + offset += uncore->gsi_offset; \ + return read##s__(uncore->regs + offset); \ } #define __raw_write(x__, s__) \ static inline void __raw_uncore_write##x__(const struct intel_uncore *uncore, \ i915_reg_t reg, u##x__ val) \ { \ - write##s__(val, uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if
[PATCH v3.1 10/14] drm/i915/uncore: Add GSI offset to uncore
GT non-engine registers (referred to as "GSI" registers by the spec) have the same relative offsets on standalone media as they do on the primary GT, just with an additional "GSI offset" added to their MMIO address. If we store this GSI offset in the standalone media's intel_uncore structure, it can be automatically applied to all GSI reg reads/writes that happen on that GT, allowing us to re-use our existing GT code with minimal changes. Forcewake and shadowed register tables for the media GT (which will be added in a future patch) are listed as final addresses that already include the GSI offset, so we also need to add the GSI offset before doing lookups of registers in one of those tables. v2: - Add comment on raw_reg_*() macros explaining why we don't bother with GSI offsets in them. (Daniele) Cc: Daniele Ceraolo Spurio Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 + drivers/gpu/drm/i915/intel_uncore.c | 10 +-- drivers/gpu/drm/i915/intel_uncore.h | 34 ++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h index 0e139f7d75ed..82dc28643572 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -274,6 +274,7 @@ struct intel_gt_definition { enum intel_gt_type type; char *name; u32 mapping_base; + u32 gsi_offset; intel_engine_mask_t engine_mask; }; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 452b3a31e965..5cd423c7b646 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -928,6 +928,9 @@ find_fw_domain(struct intel_uncore *uncore, u32 offset) { const struct intel_forcewake_range *entry; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + entry = BSEARCH(offset, uncore->fw_domains_table, uncore->fw_domains_table_entries, @@ -1143,6 +1146,9 @@ static bool is_shadowed(struct intel_uncore *uncore, u32 offset) if (drm_WARN_ON(>i915->drm, !uncore->shadowed_reg_table)) return false; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + return BSEARCH(offset, uncore->shadowed_reg_table, uncore->shadowed_reg_table_entries, @@ -1995,8 +2001,8 @@ static int __fw_domain_init(struct intel_uncore *uncore, d->uncore = uncore; d->wake_count = 0; - d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set); - d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack); + d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set) + uncore->gsi_offset; + d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack) + uncore->gsi_offset; d->id = domain_id; diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 4acb78a03233..5022bac80b67 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -136,6 +136,16 @@ struct intel_uncore { spinlock_t lock; /** lock is also taken in irq contexts. */ + /* +* Do we need to apply an additional offset to reach the beginning +* of the basic non-engine GT registers (referred to as "GSI" on +* newer platforms, or "GT block" on older platforms)? If so, we'll +* track that here and apply it transparently to registers in the +* appropriate range to maintain compatibility with our existing +* register definitions and GT code. +*/ + u32 gsi_offset; + unsigned int flags; #define UNCORE_HAS_FORCEWAKE BIT(0) #define UNCORE_HAS_FPGA_DBG_UNCLAIMED BIT(1) @@ -294,19 +304,27 @@ intel_wait_for_register_fw(struct intel_uncore *uncore, 2, timeout_ms, NULL); } +#define IS_GSI_REG(reg) ((reg) < 0x4) + /* register access functions */ #define __raw_read(x__, s__) \ static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore *uncore, \ i915_reg_t reg) \ { \ - return read##s__(uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if (IS_GSI_REG(offset)) \ + offset += uncore->gsi_offset; \ + return read##s__(uncore->regs + offset); \ } #define __raw_write(x__, s__) \ static inline void __raw_uncore_write##x__(const struct intel_uncore *uncore, \ i915_reg_t reg, u##x__ val) \ { \ - write##s__(val, uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if (IS_GSI_REG(offset)) \ + offset += uncore->gsi_offset; \ + write##s__(val, uncore->regs
[linux-next:master] BUILD REGRESSION 47c191411b68a771261be3dc0bd6f68394cef358
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: 47c191411b68a771261be3dc0bd6f68394cef358 Add linux-next specific files for 20220908 Error/Warning reports: https://lore.kernel.org/linux-mm/202209042337.fqi69rlv-...@intel.com https://lore.kernel.org/linux-mm/202209080718.y5qmlnkh-...@intel.com https://lore.kernel.org/llvm/202209090343.jpafjt74-...@intel.com Error/Warning: (recently discovered and may have been fixed) ERROR: modpost: "__divdi3" [drivers/gpu/drm/vkms/vkms.ko] undefined! ERROR: modpost: "__udivdi3" [drivers/gpu/drm/vkms/vkms.ko] undefined! arm-linux-gnueabi-ld: vkms_formats.c:(.text+0x824): undefined reference to `__aeabi_ldivmod' drivers/base/regmap/regmap-mmio.c:222:17: error: implicit declaration of function 'writesb'; did you mean 'writeb'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:225:17: error: implicit declaration of function 'writesw'; did you mean 'writew'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:228:17: error: implicit declaration of function 'writesl'; did you mean 'writel'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:232:17: error: implicit declaration of function 'writesq'; did you mean 'writeq'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:232:17: error: implicit declaration of function 'writesq'; did you mean 'writesl'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:358:17: error: implicit declaration of function 'readsb'; did you mean 'readb'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:361:17: error: implicit declaration of function 'readsw'; did you mean 'readw'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:364:17: error: implicit declaration of function 'readsl'; did you mean 'readl'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:368:17: error: implicit declaration of function 'readsq'; did you mean 'readq'? [-Werror=implicit-function-declaration] drivers/base/regmap/regmap-mmio.c:368:17: error: implicit declaration of function 'readsq'; did you mean 'readsl'? [-Werror=implicit-function-declaration] drivers/crypto/aspeed/aspeed-hace.c:133 aspeed_hace_probe() warn: platform_get_irq() does not return zero drivers/gpu/drm/amd/amdgpu/imu_v11_0_3.c:139:6: warning: no previous prototype for 'imu_v11_0_3_program_rlc_ram' [-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/gpu/drm/vkms/vkms_formats.c:259: undefined reference to `__divdi3' drivers/pinctrl/pinctrl-amd.c:288 amd_gpio_dbg_show() warn: format string contains non-ascii character '\x9a' drivers/pinctrl/pinctrl-amd.c:288 amd_gpio_dbg_show() warn: format string contains non-ascii character '\xa1' drivers/pinctrl/pinctrl-amd.c:370 amd_gpio_dbg_show() warn: format string contains non-ascii character '\x95' 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] fs/btrfs/volumes.c:6549 __btrfs_map_block() error: we previously assumed 'mirror_num_ret' could be null (see line 6376) ld: drivers/gpu/drm/vkms/vkms_formats.c:260: undefined reference to `__divdi3' ld: vkms_formats.c:(.text+0x362): undefined reference to `__divdi3' ld: vkms_formats.c:(.text+0x3b2): undefined reference to `__divdi3' ld: vkms_formats.c:(.text+0x3ba): undefined reference to `__divdi3' ld: vkms_formats.c:(.text+0x47f): undefined reference to `__divdi3' mips-linux-ld: vkms_formats.c:(.text.argb_u16_to_RGB565+0xd0): undefined reference to `__divdi3' mm/kasan/kasan_test_module.c:90:26: sparse:struct kasan_rcu_info * mm/kasan/kasan_test_module.c:90:26: sparse:struct kasan_rcu_info [noderef] __rcu * sound/soc/codecs/tas2562.c:442:13: warning: variable 'ret' set but not used [-Wunused-but-set-variable] vkms_formats.c:(.text+0x266): undefined reference to `__divdi3' vkms_formats.c:(.text+0x338): undefined reference to `__divdi3' vkms_formats.c:(.text+0x388): undefined reference to `__divdi3' vkms_formats.c:(.text+0x390): undefined reference to `__divdi3' vkms_formats.c:(.text+0x455): undefined reference to `__divdi3' vkms_formats.c:(.text+0x804): undefined reference to `__aeabi_ldivmod' vkms_formats.c:(.text.argb_u16_to_RGB565+0xb0): undefined reference to `__divdi3' Error/Warning ids grouped by kconfigs: gcc_recent_errors |-
Re: [PATCH v3 10/14] drm/i915/uncore: Add GSI offset to uncore
On Thu, Sep 08, 2022 at 02:16:27PM -0700, Ceraolo Spurio, Daniele wrote: > > > On 9/6/2022 4:49 PM, Matt Roper wrote: > > GT non-engine registers (referred to as "GSI" registers by the spec) > > have the same relative offsets on standalone media as they do on the > > primary GT, just with an additional "GSI offset" added to their MMIO > > address. If we store this GSI offset in the standalone media's > > intel_uncore structure, it can be automatically applied to all GSI reg > > reads/writes that happen on that GT, allowing us to re-use our existing > > GT code with minimal changes. > > > > Forcewake and shadowed register tables for the media GT (which will be > > added in a future patch) are listed as final addresses that already > > include the GSI offset, so we also need to add the GSI offset before > > doing lookups of registers in one of those tables. > > > > Cc: Daniele Ceraolo Spurio > > Signed-off-by: Matt Roper > > --- > > drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 + > > drivers/gpu/drm/i915/intel_uncore.c | 10 -- > > drivers/gpu/drm/i915/intel_uncore.h | 22 -- > > 3 files changed, 29 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h > > b/drivers/gpu/drm/i915/gt/intel_gt_types.h > > index 0e139f7d75ed..82dc28643572 100644 > > --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h > > +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h > > @@ -274,6 +274,7 @@ struct intel_gt_definition { > > enum intel_gt_type type; > > char *name; > > u32 mapping_base; > > + u32 gsi_offset; > > intel_engine_mask_t engine_mask; > > }; > > diff --git a/drivers/gpu/drm/i915/intel_uncore.c > > b/drivers/gpu/drm/i915/intel_uncore.c > > index 452b3a31e965..5cd423c7b646 100644 > > --- a/drivers/gpu/drm/i915/intel_uncore.c > > +++ b/drivers/gpu/drm/i915/intel_uncore.c > > @@ -928,6 +928,9 @@ find_fw_domain(struct intel_uncore *uncore, u32 offset) > > { > > const struct intel_forcewake_range *entry; > > + if (IS_GSI_REG(offset)) > > + offset += uncore->gsi_offset; > > + > > entry = BSEARCH(offset, > > uncore->fw_domains_table, > > uncore->fw_domains_table_entries, > > @@ -1143,6 +1146,9 @@ static bool is_shadowed(struct intel_uncore *uncore, > > u32 offset) > > if (drm_WARN_ON(>i915->drm, !uncore->shadowed_reg_table)) > > return false; > > + if (IS_GSI_REG(offset)) > > + offset += uncore->gsi_offset; > > + > > return BSEARCH(offset, > >uncore->shadowed_reg_table, > >uncore->shadowed_reg_table_entries, > > @@ -1995,8 +2001,8 @@ static int __fw_domain_init(struct intel_uncore > > *uncore, > > d->uncore = uncore; > > d->wake_count = 0; > > - d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set); > > - d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack); > > + d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set) + > > uncore->gsi_offset; > > + d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack) + > > uncore->gsi_offset; > > d->id = domain_id; > > diff --git a/drivers/gpu/drm/i915/intel_uncore.h > > b/drivers/gpu/drm/i915/intel_uncore.h > > index 4acb78a03233..7f1d7903a8f3 100644 > > --- a/drivers/gpu/drm/i915/intel_uncore.h > > +++ b/drivers/gpu/drm/i915/intel_uncore.h > > @@ -136,6 +136,16 @@ struct intel_uncore { > > spinlock_t lock; /** lock is also taken in irq contexts. */ > > + /* > > +* Do we need to apply an additional offset to reach the beginning > > +* of the basic non-engine GT registers (referred to as "GSI" on > > +* newer platforms, or "GT block" on older platforms)? If so, we'll > > +* track that here and apply it transparently to registers in the > > +* appropriate range to maintain compatibility with our existing > > +* register definitions and GT code. > > +*/ > > + u32 gsi_offset; > > + > > unsigned int flags; > > #define UNCORE_HAS_FORCEWAKE BIT(0) > > #define UNCORE_HAS_FPGA_DBG_UNCLAIMED BIT(1) > > @@ -294,19 +304,27 @@ intel_wait_for_register_fw(struct intel_uncore > > *uncore, > > 2, timeout_ms, NULL); > > } > > +#define IS_GSI_REG(reg) ((reg) < 0x4) > > + > > /* register access functions */ > > #define __raw_read(x__, s__) \ > > static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore > > *uncore, \ > > i915_reg_t reg) \ > > { \ > > - return read##s__(uncore->regs + i915_mmio_reg_offset(reg)); \ > > + u32 offset = i915_mmio_reg_offset(reg); \ > > + if (IS_GSI_REG(offset)) \ > > + offset += uncore->gsi_offset; \ > > + return read##s__(uncore->regs + offset); \ > > } > > #define __raw_write(x__, s__) \ > > static inline void __raw_uncore_write##x__(const struct intel_uncore > > *uncore, \ > >
Re: [PATCH v4 2/2] drm/msm/dp: retry 3 times if set sink to D0 poweer state failed
On Fri, 9 Sept 2022 at 00:18, Kuogee Hsieh wrote: > > Bring sink out of D3 (power down) mode into D0 (normal operation) mode > by setting DP_SET_POWER_D0 bit to DP_SET_POWER dpcd register. This > patch will retry 3 times if written to DP_SET_POWER register failed. > > Changes in v4: > -- split into two patches > > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/dp/dp_link.c | 21 - > 1 file changed, 12 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_link.c > b/drivers/gpu/drm/msm/dp/dp_link.c > index 36f0af0..7b5ecf5 100644 > --- a/drivers/gpu/drm/msm/dp/dp_link.c > +++ b/drivers/gpu/drm/msm/dp/dp_link.c > @@ -49,23 +49,26 @@ static int dp_aux_link_power_up(struct drm_dp_aux *aux, > struct dp_link_info *link) > { > u8 value; > - int err; > + ssize_t len; > + int i; > > if (link->revision < 0x11) > return 0; > > - err = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); > - if (err < 0) > - return err; > + len = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); > + if (len < 0) > + return len; This is a separate patch. > > value &= ~DP_SET_POWER_MASK; > value |= DP_SET_POWER_D0; > > - err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); > - if (err < 0) > - return err; > - > - usleep_range(1000, 2000); > + /* retry for 1ms to give the sink time to wake up */ > + for (i = 0; i < 3; i++) { > + len = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); > + usleep_range(1000, 2000); > + if (len == 1) > + break; > + } > > return 0; > } > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project > -- With best wishes Dmitry
RE: [PATCH v3 02/15] mei: add support to GSC extended header
> > On Fri, Aug 19, 2022 at 03:53:22PM -0700, Daniele Ceraolo Spurio wrote: > > --- a/drivers/misc/mei/hw-me.c > > +++ b/drivers/misc/mei/hw-me.c > > @@ -590,7 +590,10 @@ static int mei_me_hbuf_write(struct mei_device > *dev, > > u32 dw_cnt; > > int empty_slots; > > > > - if (WARN_ON(!hdr || !data || hdr_len & 0x3)) > > + if (WARN_ON(!hdr || hdr_len & 0x3)) > > + return -EINVAL; > > + > > + if (WARN_ON(!data && data_len)) > > Do not add more WARN_ON() calls, please just handle this properly and do > not reboot people's machines for a coding error :( As far as I understand WARN_ON() will produce solely a backtrace , This particular condition should never ever happen in theory, anyhow we can use dev_err() here as well. Thanks Tomas
Re: [PATCH v3 13/14] drm/i915/mtl: Use primary GT's irq lock for media GT
On 9/6/2022 4:49 PM, Matt Roper wrote: When we hook up interrupts (in the next patch), interrupts for the media GT are still processed as part of the primary GT's interrupt flow. As such, we should share the same IRQ lock with the primary GT. Let's convert gt->irq_lock into a pointer and just point the media GT's instance at the same lock the primary GT is using. v2: - Point media's gt->irq_lock at the primary GT lock properly. (Daniele) - Fix jump target for intel_root_gt_init_early errors. (Daniele) Cc: Daniele Ceraolo Spurio Signed-off-by: Matt Roper Reviewed-by: Daniele Ceraolo Spurio Daniele --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 8 +++--- drivers/gpu/drm/i915/gt/intel_gt.c| 15 +-- drivers/gpu/drm/i915/gt/intel_gt.h| 2 +- drivers/gpu/drm/i915/gt/intel_gt_irq.c| 16 ++-- drivers/gpu/drm/i915/gt/intel_gt_pm_irq.c | 8 +++--- drivers/gpu/drm/i915/gt/intel_gt_types.h | 2 +- drivers/gpu/drm/i915/gt/intel_rps.c | 26 +-- drivers/gpu/drm/i915/gt/intel_sa_media.c | 1 + drivers/gpu/drm/i915/gt/uc/intel_guc.c| 24 - .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 +-- drivers/gpu/drm/i915/gt/uc/intel_uc.c | 4 +-- drivers/gpu/drm/i915/i915_driver.c| 5 +++- drivers/gpu/drm/i915/i915_irq.c | 4 +-- drivers/gpu/drm/i915/pxp/intel_pxp.c | 4 +-- drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c | 4 +-- drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 14 +- drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 4 +-- 17 files changed, 80 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 41acc285e8bf..6e0122b3dca2 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1688,9 +1688,9 @@ bool intel_engine_irq_enable(struct intel_engine_cs *engine) return false; /* Caller disables interrupts */ - spin_lock(>gt->irq_lock); + spin_lock(engine->gt->irq_lock); engine->irq_enable(engine); - spin_unlock(>gt->irq_lock); + spin_unlock(engine->gt->irq_lock); return true; } @@ -1701,9 +1701,9 @@ void intel_engine_irq_disable(struct intel_engine_cs *engine) return; /* Caller disables interrupts */ - spin_lock(>gt->irq_lock); + spin_lock(engine->gt->irq_lock); engine->irq_disable(engine); - spin_unlock(>gt->irq_lock); + spin_unlock(engine->gt->irq_lock); } void intel_engines_reset_default_submission(struct intel_gt *gt) diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 9b9c0ea73b7f..b59fb03ed274 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -38,7 +38,7 @@ void intel_gt_common_init_early(struct intel_gt *gt) { - spin_lock_init(>irq_lock); + spin_lock_init(gt->irq_lock); INIT_LIST_HEAD(>closed_vma); spin_lock_init(>closed_lock); @@ -59,14 +59,19 @@ void intel_gt_common_init_early(struct intel_gt *gt) } /* Preliminary initialization of Tile 0 */ -void intel_root_gt_init_early(struct drm_i915_private *i915) +int intel_root_gt_init_early(struct drm_i915_private *i915) { struct intel_gt *gt = to_gt(i915); gt->i915 = i915; gt->uncore = >uncore; + gt->irq_lock = drmm_kzalloc(>drm, sizeof(*gt->irq_lock), GFP_KERNEL); + if (!gt->irq_lock) + return -ENOMEM; intel_gt_common_init_early(gt); + + return 0; } static int intel_gt_probe_lmem(struct intel_gt *gt) @@ -783,12 +788,18 @@ static int intel_gt_tile_setup(struct intel_gt *gt, phys_addr_t phys_addr) if (!gt_is_root(gt)) { struct intel_uncore *uncore; + spinlock_t *irq_lock; uncore = drmm_kzalloc(>i915->drm, sizeof(*uncore), GFP_KERNEL); if (!uncore) return -ENOMEM; + irq_lock = drmm_kzalloc(>i915->drm, sizeof(*irq_lock), GFP_KERNEL); + if (!irq_lock) + return -ENOMEM; + gt->uncore = uncore; + gt->irq_lock = irq_lock; intel_gt_common_init_early(gt); } diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h index c9a359f35d0f..2ee582e287c8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.h +++ b/drivers/gpu/drm/i915/gt/intel_gt.h @@ -45,7 +45,7 @@ static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc) } void intel_gt_common_init_early(struct intel_gt *gt); -void intel_root_gt_init_early(struct drm_i915_private *i915); +int intel_root_gt_init_early(struct drm_i915_private *i915); int intel_gt_assign_ggtt(struct intel_gt *gt); int intel_gt_init_mmio(struct intel_gt *gt); int __must_check
[PATCH v4 2/2] drm/msm/dp: retry 3 times if set sink to D0 poweer state failed
Bring sink out of D3 (power down) mode into D0 (normal operation) mode by setting DP_SET_POWER_D0 bit to DP_SET_POWER dpcd register. This patch will retry 3 times if written to DP_SET_POWER register failed. Changes in v4: -- split into two patches Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_link.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c index 36f0af0..7b5ecf5 100644 --- a/drivers/gpu/drm/msm/dp/dp_link.c +++ b/drivers/gpu/drm/msm/dp/dp_link.c @@ -49,23 +49,26 @@ static int dp_aux_link_power_up(struct drm_dp_aux *aux, struct dp_link_info *link) { u8 value; - int err; + ssize_t len; + int i; if (link->revision < 0x11) return 0; - err = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); - if (err < 0) - return err; + len = drm_dp_dpcd_readb(aux, DP_SET_POWER, ); + if (len < 0) + return len; value &= ~DP_SET_POWER_MASK; value |= DP_SET_POWER_D0; - err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); - if (err < 0) - return err; - - usleep_range(1000, 2000); + /* retry for 1ms to give the sink time to wake up */ + for (i = 0; i < 3; i++) { + len = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); + usleep_range(1000, 2000); + if (len == 1) + break; + } return 0; } -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v4 1/2] drm/msm/dp: cleared DP_DOWNSPREAD_CTRL register before start link training
DOWNSPREAD_CTRL (0x107) shall be cleared to 0 upon power-on reset or an upstream device disconnect. This patch will enforce this rule by always cleared DOWNSPREAD_CTRL register to 0 before start link training. At rare case that DP MSA timing parameters may be mis-interpreted by the sink which causes audio sampling rate be calculated wrongly and cause audio did not work at sink if DOWNSPREAD_CTRL register is not cleared to 0. Changes in v2: 1) fix spelling at commit text 2) merge ssc variable into encoding[0] Changes in v3: -- correct spelling of DOWNSPREAD_CTRL -- replace err with len of ssize_t Changes in v4: -- split into 2 patches Fixes: 154b5a7da0fd ("drm/msm/dp: add displayPort driver support") Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index ab6aa13..2c74c59 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -1245,8 +1245,7 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, { int ret = 0; const u8 *dpcd = ctrl->panel->dpcd; - u8 encoding = DP_SET_ANSI_8B10B; - u8 ssc; + u8 encoding[] = { 0, DP_SET_ANSI_8B10B }; u8 assr; struct dp_link_info link_info = {0}; @@ -1258,13 +1257,11 @@ static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl, dp_aux_link_configure(ctrl->aux, _info); - if (drm_dp_max_downspread(dpcd)) { - ssc = DP_SPREAD_AMP_0_5; - drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, , 1); - } + if (drm_dp_max_downspread(dpcd)) + encoding[0] |= DP_SPREAD_AMP_0_5; - drm_dp_dpcd_write(ctrl->aux, DP_MAIN_LINK_CHANNEL_CODING_SET, - , 1); + /* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */ + drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2); if (drm_dp_alternate_scrambler_reset_cap(dpcd)) { assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH v4 0/2] cleared DP_DOWNSPREAD_CTRL register
cleared DP_DOWNSPREAD_CTRL register before start link training Kuogee Hsieh (2): drm/msm/dp: cleared DP_DOWNSPREAD_CTRL register before start link training drm/msm/dp: retry 3 times if set sink to D0 poweer state failed drivers/gpu/drm/msm/dp/dp_ctrl.c | 13 + drivers/gpu/drm/msm/dp/dp_link.c | 21 - 2 files changed, 17 insertions(+), 17 deletions(-) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v3 10/14] drm/i915/uncore: Add GSI offset to uncore
On 9/6/2022 4:49 PM, Matt Roper wrote: GT non-engine registers (referred to as "GSI" registers by the spec) have the same relative offsets on standalone media as they do on the primary GT, just with an additional "GSI offset" added to their MMIO address. If we store this GSI offset in the standalone media's intel_uncore structure, it can be automatically applied to all GSI reg reads/writes that happen on that GT, allowing us to re-use our existing GT code with minimal changes. Forcewake and shadowed register tables for the media GT (which will be added in a future patch) are listed as final addresses that already include the GSI offset, so we also need to add the GSI offset before doing lookups of registers in one of those tables. Cc: Daniele Ceraolo Spurio Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 + drivers/gpu/drm/i915/intel_uncore.c | 10 -- drivers/gpu/drm/i915/intel_uncore.h | 22 -- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h index 0e139f7d75ed..82dc28643572 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -274,6 +274,7 @@ struct intel_gt_definition { enum intel_gt_type type; char *name; u32 mapping_base; + u32 gsi_offset; intel_engine_mask_t engine_mask; }; diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 452b3a31e965..5cd423c7b646 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -928,6 +928,9 @@ find_fw_domain(struct intel_uncore *uncore, u32 offset) { const struct intel_forcewake_range *entry; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + entry = BSEARCH(offset, uncore->fw_domains_table, uncore->fw_domains_table_entries, @@ -1143,6 +1146,9 @@ static bool is_shadowed(struct intel_uncore *uncore, u32 offset) if (drm_WARN_ON(>i915->drm, !uncore->shadowed_reg_table)) return false; + if (IS_GSI_REG(offset)) + offset += uncore->gsi_offset; + return BSEARCH(offset, uncore->shadowed_reg_table, uncore->shadowed_reg_table_entries, @@ -1995,8 +2001,8 @@ static int __fw_domain_init(struct intel_uncore *uncore, d->uncore = uncore; d->wake_count = 0; - d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set); - d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack); + d->reg_set = uncore->regs + i915_mmio_reg_offset(reg_set) + uncore->gsi_offset; + d->reg_ack = uncore->regs + i915_mmio_reg_offset(reg_ack) + uncore->gsi_offset; d->id = domain_id; diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 4acb78a03233..7f1d7903a8f3 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -136,6 +136,16 @@ struct intel_uncore { spinlock_t lock; /** lock is also taken in irq contexts. */ + /* +* Do we need to apply an additional offset to reach the beginning +* of the basic non-engine GT registers (referred to as "GSI" on +* newer platforms, or "GT block" on older platforms)? If so, we'll +* track that here and apply it transparently to registers in the +* appropriate range to maintain compatibility with our existing +* register definitions and GT code. +*/ + u32 gsi_offset; + unsigned int flags; #define UNCORE_HAS_FORCEWAKE BIT(0) #define UNCORE_HAS_FPGA_DBG_UNCLAIMED BIT(1) @@ -294,19 +304,27 @@ intel_wait_for_register_fw(struct intel_uncore *uncore, 2, timeout_ms, NULL); } +#define IS_GSI_REG(reg) ((reg) < 0x4) + /* register access functions */ #define __raw_read(x__, s__) \ static inline u##x__ __raw_uncore_read##x__(const struct intel_uncore *uncore, \ i915_reg_t reg) \ { \ - return read##s__(uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if (IS_GSI_REG(offset)) \ + offset += uncore->gsi_offset; \ + return read##s__(uncore->regs + offset); \ } #define __raw_write(x__, s__) \ static inline void __raw_uncore_write##x__(const struct intel_uncore *uncore, \ i915_reg_t reg, u##x__ val) \ { \ - write##s__(val, uncore->regs + i915_mmio_reg_offset(reg)); \ + u32 offset = i915_mmio_reg_offset(reg); \ + if (IS_GSI_REG(offset)) \ + offset += uncore->gsi_offset; \ + write##s__(val, uncore->regs + offset); \ } __raw_read(8, b) __raw_read(16, w) Do we also
Re: [PATCH v3 09/14] drm/i915: Handle each GT on init/release and suspend/resume
On 9/6/2022 4:49 PM, Matt Roper wrote: In preparation for enabling a second GT, there are a number of GT/uncore operations that happen during initialization or suspend flows that need to be performed on each GT, not just the primary, Cc: Daniele Ceraolo Spurio Signed-off-by: Matt Roper Reviewed-by: Daniele Ceraolo Spurio Daniele --- drivers/gpu/drm/i915/i915_driver.c | 59 +- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index bb9ba1aed1bb..e5c3cf5045d4 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -310,8 +310,13 @@ static void intel_detect_preproduction_hw(struct drm_i915_private *dev_priv) static void sanitize_gpu(struct drm_i915_private *i915) { - if (!INTEL_INFO(i915)->gpu_reset_clobbers_display) - __intel_gt_reset(to_gt(i915), ALL_ENGINES); + if (!INTEL_INFO(i915)->gpu_reset_clobbers_display) { + struct intel_gt *gt; + unsigned int i; + + for_each_gt(gt, i915, i) + __intel_gt_reset(gt, ALL_ENGINES); + } } /** @@ -730,6 +735,8 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) static void i915_driver_register(struct drm_i915_private *dev_priv) { struct drm_device *dev = _priv->drm; + struct intel_gt *gt; + unsigned int i; i915_gem_driver_register(dev_priv); i915_pmu_register(dev_priv); @@ -749,7 +756,8 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) /* Depends on sysfs having been initialized */ i915_perf_register(dev_priv); - intel_gt_driver_register(to_gt(dev_priv)); + for_each_gt(gt, dev_priv, i) + intel_gt_driver_register(gt); intel_display_driver_register(dev_priv); @@ -768,6 +776,9 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) */ static void i915_driver_unregister(struct drm_i915_private *dev_priv) { + struct intel_gt *gt; + unsigned int i; + i915_switcheroo_unregister(dev_priv); intel_unregister_dsm_handler(); @@ -777,7 +788,8 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) intel_display_driver_unregister(dev_priv); - intel_gt_driver_unregister(to_gt(dev_priv)); + for_each_gt(gt, dev_priv, i) + intel_gt_driver_unregister(gt); i915_perf_unregister(dev_priv); i915_pmu_unregister(dev_priv); @@ -799,6 +811,8 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) { if (drm_debug_enabled(DRM_UT_DRIVER)) { struct drm_printer p = drm_debug_printer("i915 device info:"); + struct intel_gt *gt; + unsigned int i; drm_printf(, "pciid=0x%04x rev=0x%02x platform=%s (subplatform=0x%x) gen=%i\n", INTEL_DEVID(dev_priv), @@ -811,7 +825,8 @@ static void i915_welcome_messages(struct drm_i915_private *dev_priv) intel_device_info_print(INTEL_INFO(dev_priv), RUNTIME_INFO(dev_priv), ); i915_print_iommu_status(dev_priv, ); - intel_gt_info_print(_gt(dev_priv)->info, ); + for_each_gt(gt, dev_priv, i) + intel_gt_info_print(>info, ); } if (IS_ENABLED(CONFIG_DRM_I915_DEBUG)) @@ -1230,13 +1245,15 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) struct drm_i915_private *dev_priv = to_i915(dev); struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); struct intel_runtime_pm *rpm = _priv->runtime_pm; - int ret; + struct intel_gt *gt; + int ret, i; disable_rpm_wakeref_asserts(rpm); i915_gem_suspend_late(dev_priv); - intel_uncore_suspend(_priv->uncore); + for_each_gt(gt, dev_priv, i) + intel_uncore_suspend(gt->uncore); intel_power_domains_suspend(dev_priv, get_suspend_mode(dev_priv, hibernation)); @@ -1368,7 +1385,8 @@ static int i915_drm_resume_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - int ret; + struct intel_gt *gt; + int ret, i; /* * We have a resume ordering issue with the snd-hda driver also @@ -1422,9 +1440,10 @@ static int i915_drm_resume_early(struct drm_device *dev) drm_err(_priv->drm, "Resume prepare failed: %d, continuing anyway\n", ret); - intel_uncore_resume_early(_priv->uncore); - - intel_gt_check_and_clear_faults(to_gt(dev_priv)); + for_each_gt(gt, dev_priv, i) { + intel_uncore_resume_early(gt->uncore); + intel_gt_check_and_clear_faults(gt); + }
Re: [PATCH v3 08/14] drm/i915: Initialize MMIO access for each GT
On 9/6/2022 4:49 PM, Matt Roper wrote: In a multi-GT system we need to initialize MMIO access for each GT, not just the primary GT. Cc: Daniele Ceraolo Spurio Reviewed-by: Daniele Ceraolo Spurio Daniele Signed-off-by: Matt Roper --- drivers/gpu/drm/i915/i915_driver.c | 27 ++- drivers/gpu/drm/i915/intel_uncore.c | 5 - drivers/gpu/drm/i915/intel_uncore.h | 3 ++- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 1f46dd1ffaf7..bb9ba1aed1bb 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -431,7 +431,8 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) */ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv) { - int ret; + struct intel_gt *gt; + int ret, i; if (i915_inject_probe_failure(dev_priv)) return -ENODEV; @@ -440,17 +441,27 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv) if (ret < 0) return ret; - ret = intel_uncore_init_mmio(_priv->uncore); - if (ret) - return ret; + for_each_gt(gt, dev_priv, i) { + ret = intel_uncore_init_mmio(gt->uncore); + if (ret) + return ret; + + ret = drmm_add_action_or_reset(_priv->drm, + intel_uncore_fini_mmio, + gt->uncore); + if (ret) + return ret; + } /* Try to make sure MCHBAR is enabled before poking at it */ intel_setup_mchbar(dev_priv); intel_device_info_runtime_init(dev_priv); - ret = intel_gt_init_mmio(to_gt(dev_priv)); - if (ret) - goto err_uncore; + for_each_gt(gt, dev_priv, i) { + ret = intel_gt_init_mmio(gt); + if (ret) + goto err_uncore; + } /* As early as possible, scrub existing GPU state before clobbering */ sanitize_gpu(dev_priv); @@ -459,7 +470,6 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv) err_uncore: intel_teardown_mchbar(dev_priv); - intel_uncore_fini_mmio(_priv->uncore); return ret; } @@ -471,7 +481,6 @@ static int i915_driver_mmio_probe(struct drm_i915_private *dev_priv) static void i915_driver_mmio_release(struct drm_i915_private *dev_priv) { intel_teardown_mchbar(dev_priv); - intel_uncore_fini_mmio(_priv->uncore); } /** diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index 2a32f8a65f34..452b3a31e965 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2455,8 +2455,11 @@ void intel_uncore_prune_engine_fw_domains(struct intel_uncore *uncore, } } -void intel_uncore_fini_mmio(struct intel_uncore *uncore) +/* Called via drm-managed action */ +void intel_uncore_fini_mmio(struct drm_device *dev, void *data) { + struct intel_uncore *uncore = data; + if (intel_uncore_has_forcewake(uncore)) { iosf_mbi_punit_acquire(); iosf_mbi_unregister_pmic_bus_access_notifier_unlocked( diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h index 6100d0f4498a..4acb78a03233 100644 --- a/drivers/gpu/drm/i915/intel_uncore.h +++ b/drivers/gpu/drm/i915/intel_uncore.h @@ -33,6 +33,7 @@ #include "i915_reg_defs.h" +struct drm_device; struct drm_i915_private; struct intel_runtime_pm; struct intel_uncore; @@ -220,7 +221,7 @@ void intel_uncore_prune_engine_fw_domains(struct intel_uncore *uncore, bool intel_uncore_unclaimed_mmio(struct intel_uncore *uncore); bool intel_uncore_arm_unclaimed_mmio_detection(struct intel_uncore *uncore); void intel_uncore_cleanup_mmio(struct intel_uncore *uncore); -void intel_uncore_fini_mmio(struct intel_uncore *uncore); +void intel_uncore_fini_mmio(struct drm_device *dev, void *data); void intel_uncore_suspend(struct intel_uncore *uncore); void intel_uncore_resume_early(struct intel_uncore *uncore); void intel_uncore_runtime_resume(struct intel_uncore *uncore);
Re: [PATCH v2 13/15] vfio/ccw: Use the new device life cycle helpers
On Thu, 2022-09-08 at 07:19 +, Tian, Kevin wrote: > ping @Eric Farman. > > ccw is the only tricky player in this series. Please help take a look > in case of > any oversight here. Apologies, I had started looking at v1 before I left on holiday, and only returned today. > > > From: Tian, Kevin > > Sent: Thursday, September 1, 2022 10:38 PM > > > > 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. I did start looking at the above, while the mdev series is outstanding. Will try to get back to that sooner rather than later, but for the purposes of this series this patch looks/works fine to me. Reviewed-by: Eric Farman > > > > Remove vfio_init/uninit_group_dev() as no user now. > > > > Suggested-by: Jason Gunthorpe > > Signed-off-by: Kevin Tian > > Reviewed-by: Jason Gunthorpe > > --- > > 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); > >
[drm-misc:drm-misc-next 1/1] drivers/gpu/drm/sun4i/sun4i_tv.c:356:17: error: implicit declaration of function 'drm_atomic_get_new_crtc_state'; did you mean 'drm_atomic_helper_swap_state'?
tree: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next head: 5d832b6694e094b176627ed9918a1b21c56fb742 commit: ec491291dc94914cf962dcd399c3e9b43b00a770 [1/1] drm/sun4i: tv: Merge mode_set into atomic_enable config: parisc-randconfig-r003-20220907 (https://download.01.org/0day-ci/archive/20220909/202209090435.nc6iroru-...@intel.com/config) compiler: hppa-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git remote add drm-misc git://anongit.freedesktop.org/drm/drm-misc git fetch --no-tags drm-misc drm-misc-next git checkout ec491291dc94914cf962dcd399c3e9b43b00a770 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=parisc SHELL=/bin/bash drivers/gpu/drm/sun4i/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot All error/warnings (new ones prefixed by >>): drivers/gpu/drm/sun4i/sun4i_tv.c: In function 'sun4i_tv_enable': >> drivers/gpu/drm/sun4i/sun4i_tv.c:356:17: error: implicit declaration of >> function 'drm_atomic_get_new_crtc_state'; did you mean >> 'drm_atomic_helper_swap_state'? [-Werror=implicit-function-declaration] 356 | drm_atomic_get_new_crtc_state(state, encoder->crtc); | ^ | drm_atomic_helper_swap_state >> drivers/gpu/drm/sun4i/sun4i_tv.c:356:17: warning: initialization of 'struct >> drm_crtc_state *' from 'int' makes pointer from integer without a cast >> [-Wint-conversion] cc1: some warnings being treated as errors vim +356 drivers/gpu/drm/sun4i/sun4i_tv.c 349 350 static void sun4i_tv_enable(struct drm_encoder *encoder, 351 struct drm_atomic_state *state) 352 { 353 struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder); 354 struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc); 355 struct drm_crtc_state *crtc_state = > 356 drm_atomic_get_new_crtc_state(state, encoder->crtc); 357 struct drm_display_mode *mode = _state->mode; 358 const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode); 359 360 DRM_DEBUG_DRIVER("Enabling the TV Output\n"); 361 362 /* Enable and map the DAC to the output */ 363 regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG, 364 SUN4I_TVE_EN_DAC_MAP_MASK, 365 SUN4I_TVE_EN_DAC_MAP(0, 1) | 366 SUN4I_TVE_EN_DAC_MAP(1, 2) | 367 SUN4I_TVE_EN_DAC_MAP(2, 3) | 368 SUN4I_TVE_EN_DAC_MAP(3, 4)); 369 370 /* Set PAL settings */ 371 regmap_write(tv->regs, SUN4I_TVE_CFG0_REG, 372 tv_mode->mode | 373 (tv_mode->yc_en ? SUN4I_TVE_CFG0_YC_EN : 0) | 374 SUN4I_TVE_CFG0_COMP_EN | 375 SUN4I_TVE_CFG0_DAC_CONTROL_54M | 376 SUN4I_TVE_CFG0_CORE_DATAPATH_54M | 377 SUN4I_TVE_CFG0_CORE_CONTROL_54M); 378 379 /* Configure the DAC for a composite output */ 380 regmap_write(tv->regs, SUN4I_TVE_DAC0_REG, 381 SUN4I_TVE_DAC0_DAC_EN(0) | 382 (tv_mode->dac3_en ? SUN4I_TVE_DAC0_DAC_EN(3) : 0) | 383 SUN4I_TVE_DAC0_INTERNAL_DAC_37_5_OHMS | 384 SUN4I_TVE_DAC0_CHROMA_0_75 | 385 SUN4I_TVE_DAC0_LUMA_0_4 | 386 SUN4I_TVE_DAC0_CLOCK_INVERT | 387 (tv_mode->dac_bit25_en ? BIT(25) : 0) | 388 BIT(30)); 389 390 /* Configure the sample delay between DAC0 and the other DAC */ 391 regmap_write(tv->regs, SUN4I_TVE_NOTCH_REG, 392 SUN4I_TVE_NOTCH_DAC0_TO_DAC_DLY(1, 0) | 393 SUN4I_TVE_NOTCH_DAC0_TO_DAC_DLY(2, 0)); 394 395 regmap_write(tv->regs, SUN4I_TVE_CHROMA_FREQ_REG, 396 tv_mode->chroma_freq); 397 398 /* Set the front and back porch */ 399 regmap_write(tv->regs, SUN4I_TVE_PORCH_REG, 400 SUN4I_TVE_PORCH_BACK(tv_mode->back_porch) | 401 SUN4I_TVE_PORCH_FRONT(tv_mode->front_porch)); 402 403 /* Set the lines setup */ 404 regmap_write(tv->regs, SUN4I_TVE_LINE_REG, 405 SUN4I_TVE_LINE_FIRST(22) | 406 SUN4I_TVE_LINE_NUMBER(tv_mode->line_number)); 407 408
Re: [PATCH v4 10/11] drm/i915/mtl: Update CHICKEN_TRANS* register addresses
On Thu, Sep 01, 2022 at 11:03:41PM -0700, Radhakrishna Sripada wrote: > From: Madhumitha Tolakanahalli Pradeep > > > In Display version 14, Transcoder Chicken Registers have updated address. > This patch performs checks to use the right register when required. > > v2: Omit display version check in i915_reg.h(Jani) > > Bspec: 34387, 50054 > Cc: Jani Nikula > Signed-off-by: Madhumitha Tolakanahalli Pradeep > > Signed-off-by: Radhakrishna Sripada > --- > drivers/gpu/drm/i915/display/intel_display.c | 14 --- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +++- > drivers/gpu/drm/i915/display/intel_psr.c | 6 +++-- > drivers/gpu/drm/i915/i915_reg.h | 25 +++- > 4 files changed, 38 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c > b/drivers/gpu/drm/i915/display/intel_display.c > index be7cff722196..a3d0d12084a9 100644 > --- a/drivers/gpu/drm/i915/display/intel_display.c > +++ b/drivers/gpu/drm/i915/display/intel_display.c > @@ -618,7 +618,10 @@ void intel_disable_transcoder(const struct > intel_crtc_state *old_crtc_state) > if (!IS_I830(dev_priv)) > val &= ~PIPECONF_ENABLE; > > - if (DISPLAY_VER(dev_priv) >= 12) > + if (DISPLAY_VER(dev_priv) >= 14) > + intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(cpu_transcoder), > + FECSTALL_DIS_DPTSTREAM_DPTTG, 0); > + else if (DISPLAY_VER(dev_priv) >= 12) > intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), >FECSTALL_DIS_DPTSTREAM_DPTTG, 0); > > @@ -1838,7 +1841,9 @@ static void hsw_set_frame_start_delay(const struct > intel_crtc_state *crtc_state) > { > struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > - i915_reg_t reg = CHICKEN_TRANS(crtc_state->cpu_transcoder); > + enum transcoder transcoder = crtc_state->cpu_transcoder; > + i915_reg_t reg = DISPLAY_VER(dev_priv) >= 14 ? > MTL_CHICKEN_TRANS(transcoder) : > + CHICKEN_TRANS(transcoder); > u32 val; > > val = intel_de_read(dev_priv, reg); > @@ -4033,6 +4038,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, > { > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > struct intel_display_power_domain_set power_domain_set = { }; > + i915_reg_t reg; > bool active; > u32 tmp; > > @@ -4124,7 +4130,9 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, > } > > if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) { > - tmp = intel_de_read(dev_priv, > CHICKEN_TRANS(pipe_config->cpu_transcoder)); > + reg = DISPLAY_VER(dev_priv) >= 14 ? > MTL_CHICKEN_TRANS(pipe_config->cpu_transcoder) : > + CHICKEN_TRANS(pipe_config->cpu_transcoder); > + tmp = intel_de_read(dev_priv, reg); > > pipe_config->framestart_delay = > REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1; > } else { > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c > b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index 13abe2b2170e..298004cae5a5 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -568,7 +568,10 @@ static void intel_mst_enable_dp(struct > intel_atomic_state *state, > drm_dp_add_payload_part2(_dp->mst_mgr, >base, >drm_atomic_get_mst_payload_state(mst_state, > connector->port)); > > - if (DISPLAY_VER(dev_priv) >= 12 && pipe_config->fec_enable) > + if (DISPLAY_VER(dev_priv) >= 14 && pipe_config->fec_enable) > + intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(trans), 0, > + FECSTALL_DIS_DPTSTREAM_DPTTG); > + else if (DISPLAY_VER(dev_priv) >= 12 && pipe_config->fec_enable) > intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0, >FECSTALL_DIS_DPTSTREAM_DPTTG); > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c > b/drivers/gpu/drm/i915/display/intel_psr.c > index 079b7d3d0c53..da2d0661b630 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -1139,7 +1139,8 @@ static void intel_psr_enable_source(struct intel_dp > *intel_dp, > > if (intel_dp->psr.psr2_enabled) { > if (DISPLAY_VER(dev_priv) == 9) > - intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder), 0, > + intel_de_rmw(dev_priv, > + CHICKEN_TRANS(cpu_transcoder), 0, This whitespace-only change on a non-MTL codepath doesn't look necessary. >PSR2_VSC_ENABLE_PROG_HEADER | >PSR2_ADD_VERTICAL_LINE_COUNT); > > @@ -1149,7 +1150,8 @@ static void intel_psr_enable_source(struct intel_dp > *intel_dp,
Re: [PATCH v6 01/12] dt-bindings: display/msm: split qcom,mdss bindings
On 08/09/2022 22:37, Rob Herring wrote: On Thu, Sep 08, 2022 at 03:37:38PM +0200, Krzysztof Kozlowski wrote: On 01/09/2022 12:23, Dmitry Baryshkov wrote: Split Mobile Display SubSystem (MDSS) root node bindings to the separate yaml file. Changes to the existing (txt) schema: - Added optional "vbif_nrt_phys" region used by msm8996 - Made "bus" and "vsync" clocks optional (they are not used by some platforms) - Added (optional) "core" clock added recently to the mdss driver - Added optional resets property referencing MDSS reset - Defined child nodes pointing to corresponding reference schema. - Dropped the "lut" clock. It was added to the schema by mistake (it is a part of mdp4 schema, not the mdss). Signed-off-by: Dmitry Baryshkov --- .../devicetree/bindings/display/msm/mdp5.txt | 30 +--- .../devicetree/bindings/display/msm/mdss.yaml | 166 ++ 2 files changed, 167 insertions(+), 29 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/msm/mdss.yaml diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt b/Documentation/devicetree/bindings/display/msm/mdp5.txt index 43d11279c925..65d03c58dee6 100644 --- a/Documentation/devicetree/bindings/display/msm/mdp5.txt +++ b/Documentation/devicetree/bindings/display/msm/mdp5.txt @@ -2,37 +2,9 @@ Qualcomm adreno/snapdragon MDP5 display controller Description: -This is the bindings documentation for the Mobile Display Subsytem(MDSS) that -encapsulates sub-blocks like MDP5, DSI, HDMI, eDP etc, and the MDP5 display +This is the bindings documentation for the MDP5 display controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and MSM8996. -MDSS: -Required properties: -- compatible: - * "qcom,mdss" - MDSS -- reg: Physical base address and length of the controller's registers. -- reg-names: The names of register regions. The following regions are required: - * "mdss_phys" - * "vbif_phys" -- interrupts: The interrupt signal from MDSS. -- interrupt-controller: identifies the node as an interrupt controller. -- #interrupt-cells: specifies the number of cells needed to encode an interrupt - source, should be 1. -- power-domains: a power domain consumer specifier according to - Documentation/devicetree/bindings/power/power_domain.txt -- clocks: device clocks. See ../clocks/clock-bindings.txt for details. -- clock-names: the following clocks are required. - * "iface" - * "bus" - * "vsync" -- #address-cells: number of address cells for the MDSS children. Should be 1. -- #size-cells: Should be 1. -- ranges: parent bus address space is the same as the child bus address space. - -Optional properties: -- clock-names: the following clocks are optional: - * "lut" - MDP5: Required properties: - compatible: diff --git a/Documentation/devicetree/bindings/display/msm/mdss.yaml b/Documentation/devicetree/bindings/display/msm/mdss.yaml new file mode 100644 index ..8860fc55cca5 --- /dev/null +++ b/Documentation/devicetree/bindings/display/msm/mdss.yaml @@ -0,0 +1,166 @@ +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/msm/mdss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Mobile Display SubSystem (MDSS) + +maintainers: + - Dmitry Baryshkov + - Rob Clark + +description: + This is the bindings documentation for the Mobile Display Subsytem(MDSS) that + encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc. + +properties: + compatible: +enum: + - qcom,mdss + + reg: +minItems: 2 +maxItems: 3 + + reg-names: +minItems: 2 +items: + - const: mdss_phys + - const: vbif_phys + - const: vbif_nrt_phys + + interrupts: +maxItems: 1 + + interrupt-controller: +true If there is going to be v7 - please make it one line. + + "#interrupt-cells": +const: 1 + + power-domains: +maxItems: 1 +description: | + The MDSS power domain provided by GCC + + clocks: +minItems: 1 +items: + - description: Display abh clock + - description: Display axi clock + - description: Display vsync clock + + clock-names: +minItems: 1 +items: + - const: iface + - const: bus + - const: vsync + + "#address-cells": +const: 1 + + "#size-cells": +const: 1 + + ranges: +true Ditto. + + resets: +items: + - description: MDSS_CORE reset + +required: + - compatible + - reg + - reg-names + - interrupts + - interrupt-controller + - "#interrupt-cells" + - power-domains + - clocks + - clock-names + - "#address-cells" + - "#size-cells" + - ranges + +patternProperties: + "^mdp@[1-9a-f][0-9a-f]*$": +type: object +properties: + compatible: +const: qcom,mdp5 + + "^dsi@[1-9a-f][0-9a-f]*$": +type: object +properties: + compatible: +const: qcom,mdss-dsi-ctrl This should be ref to dsi-controller-main.yaml... or
[PATCH v1 2/3] drm/i915/gt: Extract per-platform function for frequency read
Instead of calling read_clock_frequency() to walk the if/else ladder per platform, move the ladder to intel_gt_init_clock_frequency() and use one function per branch. With the new logic, it's now clear the call to gen9_get_crystal_clock_freq() was just dead code, as gen9 is handled by another function and there is no version 10. Remove that function and the caller. Cc: Ville Syrjälä Signed-off-by: Lucas De Marchi diff --git a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c index 93608c9349fd..ebddbf7542bc 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c @@ -26,26 +26,6 @@ static u32 read_reference_ts_freq(struct intel_uncore *uncore) return base_freq + frac_freq; } -static u32 gen9_get_crystal_clock_freq(struct intel_uncore *uncore, - u32 rpm_config_reg) -{ - u32 f19_2_mhz = 1920; - u32 f24_mhz = 2400; - u32 crystal_clock = - (rpm_config_reg & GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_MASK) >> - GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_SHIFT; - - switch (crystal_clock) { - case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_19_2_MHZ: - return f19_2_mhz; - case GEN9_RPM_CONFIG0_CRYSTAL_CLOCK_FREQ_24_MHZ: - return f24_mhz; - default: - MISSING_CASE(crystal_clock); - return 0; - } -} - static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore, u32 rpm_config_reg) { @@ -72,95 +52,101 @@ static u32 gen11_get_crystal_clock_freq(struct intel_uncore *uncore, } } -static u32 read_clock_frequency(struct intel_uncore *uncore) +static u32 gen11_read_clock_frequency(struct intel_uncore *uncore) { - u32 f12_5_mhz = 1250; - u32 f19_2_mhz = 1920; - u32 f24_mhz = 2400; + u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); + u32 freq = 0; - if (GRAPHICS_VER(uncore->i915) >= 11) { - u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); - u32 freq = 0; + /* +* Note that on gen11+, the clock frequency may be reconfigured. +* We do not, and we assume nobody else does. +* +* First figure out the reference frequency. There are 2 ways +* we can compute the frequency, either through the +* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE +* tells us which one we should use. +*/ + if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { + freq = read_reference_ts_freq(uncore); + } else { + u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); + + freq = gen11_get_crystal_clock_freq(uncore, c0); /* -* First figure out the reference frequency. There are 2 ways -* we can compute the frequency, either through the -* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE -* tells us which one we should use. -*/ - if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { - freq = read_reference_ts_freq(uncore); - } else { - u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); - - if (GRAPHICS_VER(uncore->i915) >= 11) - freq = gen11_get_crystal_clock_freq(uncore, c0); - else - freq = gen9_get_crystal_clock_freq(uncore, c0); - - /* -* Now figure out how the command stream's timestamp -* register increments from this frequency (it might -* increment only every few clock cycle). -*/ - freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> - GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); - } - - return freq; - } else if (GRAPHICS_VER(uncore->i915) >= 9) { - u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); - u32 freq = 0; - - if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { - freq = read_reference_ts_freq(uncore); - } else { - freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz; - - /* -* Now figure out how the command stream's timestamp -* register increments from this frequency (it might -* increment only every few clock cycle). -*/ - freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >> -
[PATCH v1 3/3] drm/i915: Invert if/else ladder for stolen init
Continue converting the driver to the convention of last version first, extending it to the future platforms. Now, any GRAPHICS_VER >= 11 will be handled by the first branch. 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 4f4c9461a23b..acc561c0f0aa 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -430,48 +430,29 @@ static int i915_gem_init_stolen(struct intel_memory_region *mem) reserved_base = stolen_top; reserved_size = 0; - switch (GRAPHICS_VER(i915)) { - case 2: - case 3: - break; - case 4: - if (!IS_G4X(i915)) - break; - fallthrough; - case 5: - g4x_get_stolen_reserved(i915, uncore, + if (GRAPHICS_VER(i915) >= 11) { + icl_get_stolen_reserved(i915, uncore, _base, _size); - break; - case 6: - gen6_get_stolen_reserved(i915, uncore, -_base, _size); - break; - case 7: - if (IS_VALLEYVIEW(i915)) - vlv_get_stolen_reserved(i915, uncore, - _base, _size); - else - gen7_get_stolen_reserved(i915, uncore, -_base, _size); - break; - case 8: - case 9: + } else if (GRAPHICS_VER(i915) >= 8) { if (IS_LP(i915)) chv_get_stolen_reserved(i915, uncore, _base, _size); else bdw_get_stolen_reserved(i915, uncore, _base, _size); - break; - default: - MISSING_CASE(GRAPHICS_VER(i915)); - fallthrough; - case 11: - case 12: - icl_get_stolen_reserved(i915, uncore, - _base, - _size); - break; + } else if (GRAPHICS_VER(i915) >= 7) { + if (IS_VALLEYVIEW(i915)) + vlv_get_stolen_reserved(i915, uncore, + _base, _size); + else + gen7_get_stolen_reserved(i915, uncore, +_base, _size); + } else if (GRAPHICS_VER(i915) >= 6) { + gen6_get_stolen_reserved(i915, uncore, +_base, _size); + } else if (GRAPHICS_VER(i915) >= 5 || IS_G4X(i915)) { + g4x_get_stolen_reserved(i915, uncore, + _base, _size); } /* -- b4 0.10.0-dev-df873
[PATCH v1 1/3] drm/i915: Invert if/else ladder for frequency read
Continue converting the driver to the convention of last version first, extending it to the future platforms. Now, any GRAPHICS_VER >= 11 will be handled by the first branch. With the new ranges it's easier to see what platform a branch started to be taken. Besides the >= 11 change, the branch taken for GRAPHICS_VER == 10 is also different, but currently there is no such platform in i915. Signed-off-by: Lucas De Marchi Reviewed-by: Matt Roper diff --git a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c index d5d1b04dbcad..93608c9349fd 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c @@ -78,77 +78,74 @@ static u32 read_clock_frequency(struct intel_uncore *uncore) u32 f19_2_mhz = 1920; u32 f24_mhz = 2400; - if (GRAPHICS_VER(uncore->i915) <= 4) { - /* -* PRMs say: -* -* "The value in this register increments once every 16 -* hclks." (through the “Clocking Configuration” -* (“CLKCFG”) MCHBAR register) -*/ - return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000 / 16; - } else if (GRAPHICS_VER(uncore->i915) <= 8) { - /* -* PRMs say: -* -* "The PCU TSC counts 10ns increments; this timestamp -* reflects bits 38:3 of the TSC (i.e. 80ns granularity, -* rolling over every 1.5 hours). -*/ - return f12_5_mhz; - } else if (GRAPHICS_VER(uncore->i915) <= 9) { + if (GRAPHICS_VER(uncore->i915) >= 11) { u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); u32 freq = 0; + /* +* First figure out the reference frequency. There are 2 ways +* we can compute the frequency, either through the +* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE +* tells us which one we should use. +*/ if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { freq = read_reference_ts_freq(uncore); } else { - freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz; + u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); + + if (GRAPHICS_VER(uncore->i915) >= 11) + freq = gen11_get_crystal_clock_freq(uncore, c0); + else + freq = gen9_get_crystal_clock_freq(uncore, c0); /* * Now figure out how the command stream's timestamp * register increments from this frequency (it might * increment only every few clock cycle). */ - freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >> - CTC_SHIFT_PARAMETER_SHIFT); + freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> + GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); } return freq; - } else if (GRAPHICS_VER(uncore->i915) <= 12) { + } else if (GRAPHICS_VER(uncore->i915) >= 9) { u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); u32 freq = 0; - /* -* First figure out the reference frequency. There are 2 ways -* we can compute the frequency, either through the -* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE -* tells us which one we should use. -*/ if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { freq = read_reference_ts_freq(uncore); } else { - u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); - - if (GRAPHICS_VER(uncore->i915) >= 11) - freq = gen11_get_crystal_clock_freq(uncore, c0); - else - freq = gen9_get_crystal_clock_freq(uncore, c0); + freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz; /* * Now figure out how the command stream's timestamp * register increments from this frequency (it might * increment only every few clock cycle). */ - freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> - GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); + freq >>= 3 -
[PATCH v1 0/3] drm/i915: A couple of if/else ladder refactors
Refactor code to follow the same convention as last platform first. This series includes one patch that had already been reviewed, for frequency read and 2 more refactors. Signed-off-by: Lucas De Marchi --- Lucas De Marchi (3): drm/i915: Invert if/else ladder for frequency read drm/i915/gt: Extract per-platform function for frequency read drm/i915: Invert if/else ladder for stolen init drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 51 +++- drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c | 171 +++-- 2 files changed, 93 insertions(+), 129 deletions(-) --- base-commit: adc57f2b82896fed07bc8e34956c15bb1448fca2 change-id: 20220908-if-ladder-df33a06d4f4e Best regards, -- Lucas De Marchi
Re: [PATCH v4 0/5] Allwinner H6 GPU devfreq
Dne torek, 06. september 2022 ob 17:30:29 CEST je Clément Péron napisal(a): > Hi, > > This is a refresh of previous patches sent to enable GPU Devfreq on H6 > Beelink GS1 but that wasn't stable at that time[0]. > > With the recent fix on GPU PLL from Roman Stratiienko I have retested > and everything seems stable and works as expected[1]. > > Regards, > Clement All patches except patch 4 pushed to sunxi tree. Thanks! Best regards, Jernej > > 0: > https://lore.kernel.org/lkml/CAJiuCce58Gaxf_Qg2cnMwvOgUqYU__eKb3MDX1Fe_+47h > tg...@mail.gmail.com/ 1: > https://lore.kernel.org/linux-arm-kernel/2562485.k3LOHGUjKi@kista/T/ > > Changes since v3: > - Try to be more explicit for panfrost OPP patch > - Fix typo > > Changes since v2: > - Fixes device-tree warnings > - Add panfrost fix to enable regulator > - Remove always-on regulator from device-tree > - Update cooling map from vendor kernel > > > Clément Péron (5): > arm64: defconfig: Enable devfreq cooling device > arm64: dts: allwinner: h6: Add cooling map for GPU > arm64: dts: allwinner: h6: Add GPU OPP table > drm/panfrost: devfreq: set opp to the recommended one to configure > regulator > arm64: dts: allwinner: beelink-gs1: Enable GPU OPP > > .../dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 + > .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++ > arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 51 ++- > arch/arm64/configs/defconfig | 1 + > drivers/gpu/drm/panfrost/panfrost_devfreq.c | 11 +++ > 5 files changed, 149 insertions(+), 2 deletions(-) > create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > -- > 2.34.1
Re: [PATCH v4 09/11] drm/i915/mtl: Update MBUS_DBOX credits
On Thu, Sep 01, 2022 at 11:03:40PM -0700, Radhakrishna Sripada wrote: > Display version 14 platforms have different credits values > compared to ADL-P. Update the credits based on pipe usage. > > v2: Simplify DBOX BW Credit definition(MattR) > > Bspec: 49213 > > Cc: Jose Roberto de Souza > Cc: Matt Roper > Original Author: Caz Yokoyama > Signed-off-by: José Roberto de Souza > Signed-off-by: Radhakrishna Sripada > --- > drivers/gpu/drm/i915/i915_reg.h | 4 +++ > drivers/gpu/drm/i915/intel_pm.c | 47 ++--- > 2 files changed, 47 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index d22fabe35a0c..f9237586ab4f 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -1125,8 +1125,12 @@ > #define MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN REG_BIT(16) /* tgl+ */ > #define MBUS_DBOX_BW_CREDIT_MASK REG_GENMASK(15, 14) > #define MBUS_DBOX_BW_CREDIT(x) > REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, x) > +#define MBUS_DBOX_BW_4CREDITS_MTL > REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x2) > +#define MBUS_DBOX_BW_8CREDITS_MTL > REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x3) > #define MBUS_DBOX_B_CREDIT_MASK REG_GENMASK(12, 8) > #define MBUS_DBOX_B_CREDIT(x) > REG_FIELD_PREP(MBUS_DBOX_B_CREDIT_MASK, x) > +#define MBUS_DBOX_I_CREDIT_MASK REG_GENMASK(7, 5) > +#define MBUS_DBOX_I_CREDIT(x) > REG_FIELD_PREP(MBUS_DBOX_I_CREDIT_MASK, x) > #define MBUS_DBOX_A_CREDIT_MASK REG_GENMASK(3, 0) > #define MBUS_DBOX_A_CREDIT(x) > REG_FIELD_PREP(MBUS_DBOX_A_CREDIT_MASK, x) > > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index ebce6171ccef..b19a1ecb010e 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -8448,6 +8448,27 @@ void intel_dbuf_post_plane_update(struct > intel_atomic_state *state) > new_dbuf_state->enabled_slices); > } > > +static bool xelpdp_is_one_pipe_per_dbuf_bank(enum pipe pipe, u8 active_pipes) Bikeshed: s/one/only/ might be slightly more clear? > +{ > + switch (pipe) { > + case PIPE_A: > + case PIPE_D: > + if (is_power_of_2(active_pipes & (BIT(PIPE_A) | BIT(PIPE_D Bikeshed: writing this with hweight might be more intuitive than power_of_2? Or even just a direct check of the other pipe like case PIPE_A: return !(active_pipes & BIT(PIPE_D)) case PIPE_D: return !(active_pipes & BIT(PIPE_A)) ... > + return true; > + break; > + case PIPE_B: > + case PIPE_C: > + if (is_power_of_2(active_pipes & (BIT(PIPE_B) | BIT(PIPE_C > + return true; > + break; > + default: /* to suppress compiler warning */ > + MISSING_CASE(pipe); > + break; > + } > + > + return false; > +} > + > void intel_mbus_dbox_update(struct intel_atomic_state *state) > { > struct drm_i915_private *i915 = to_i915(state->base.dev); > @@ -8467,20 +8488,28 @@ void intel_mbus_dbox_update(struct intel_atomic_state > *state) >new_dbuf_state->active_pipes == old_dbuf_state->active_pipes)) > return; > > + if (DISPLAY_VER(i915) >= 14) > + val |= MBUS_DBOX_I_CREDIT(2); > + > if (DISPLAY_VER(i915) >= 12) { > val |= MBUS_DBOX_B2B_TRANSACTIONS_MAX(16); > val |= MBUS_DBOX_B2B_TRANSACTIONS_DELAY(1); > val |= MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN; > } > > - /* Wa_22010947358:adl-p */ > - if (IS_ALDERLAKE_P(i915)) > + if (DISPLAY_VER(i915) >= 14) > + val |= new_dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(12) : > + MBUS_DBOX_A_CREDIT(8); > + else if (IS_ALDERLAKE_P(i915)) > + /* Wa_22010947358:adl-p */ > val |= new_dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(6) : >MBUS_DBOX_A_CREDIT(4); > else > val |= MBUS_DBOX_A_CREDIT(2); > > - if (IS_ALDERLAKE_P(i915)) { > + if (DISPLAY_VER(i915) >= 14) { > + val |= MBUS_DBOX_B_CREDIT(0xA); > + } else if (IS_ALDERLAKE_P(i915)) { > val |= MBUS_DBOX_BW_CREDIT(2); > val |= MBUS_DBOX_B_CREDIT(8); > } else if (DISPLAY_VER(i915) >= 12) { > @@ -8492,10 +8521,20 @@ void intel_mbus_dbox_update(struct intel_atomic_state > *state) > } > > for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { > + u32 pipe_val = val; > + > if (!new_crtc_state->hw.active || >
Re: [PATCH v6 01/12] dt-bindings: display/msm: split qcom,mdss bindings
On Thu, Sep 08, 2022 at 03:37:38PM +0200, Krzysztof Kozlowski wrote: > On 01/09/2022 12:23, Dmitry Baryshkov wrote: > > Split Mobile Display SubSystem (MDSS) root node bindings to the separate > > yaml file. Changes to the existing (txt) schema: > > - Added optional "vbif_nrt_phys" region used by msm8996 > > - Made "bus" and "vsync" clocks optional (they are not used by some > >platforms) > > - Added (optional) "core" clock added recently to the mdss driver > > - Added optional resets property referencing MDSS reset > > - Defined child nodes pointing to corresponding reference schema. > > - Dropped the "lut" clock. It was added to the schema by mistake (it is > >a part of mdp4 schema, not the mdss). > > > > Signed-off-by: Dmitry Baryshkov > > --- > > .../devicetree/bindings/display/msm/mdp5.txt | 30 +--- > > .../devicetree/bindings/display/msm/mdss.yaml | 166 ++ > > 2 files changed, 167 insertions(+), 29 deletions(-) > > create mode 100644 Documentation/devicetree/bindings/display/msm/mdss.yaml > > > > diff --git a/Documentation/devicetree/bindings/display/msm/mdp5.txt > > b/Documentation/devicetree/bindings/display/msm/mdp5.txt > > index 43d11279c925..65d03c58dee6 100644 > > --- a/Documentation/devicetree/bindings/display/msm/mdp5.txt > > +++ b/Documentation/devicetree/bindings/display/msm/mdp5.txt > > @@ -2,37 +2,9 @@ Qualcomm adreno/snapdragon MDP5 display controller > > > > Description: > > > > -This is the bindings documentation for the Mobile Display Subsytem(MDSS) > > that > > -encapsulates sub-blocks like MDP5, DSI, HDMI, eDP etc, and the MDP5 display > > +This is the bindings documentation for the MDP5 display > > controller found in SoCs like MSM8974, APQ8084, MSM8916, MSM8994 and > > MSM8996. > > > > -MDSS: > > -Required properties: > > -- compatible: > > - * "qcom,mdss" - MDSS > > -- reg: Physical base address and length of the controller's registers. > > -- reg-names: The names of register regions. The following regions are > > required: > > - * "mdss_phys" > > - * "vbif_phys" > > -- interrupts: The interrupt signal from MDSS. > > -- interrupt-controller: identifies the node as an interrupt controller. > > -- #interrupt-cells: specifies the number of cells needed to encode an > > interrupt > > - source, should be 1. > > -- power-domains: a power domain consumer specifier according to > > - Documentation/devicetree/bindings/power/power_domain.txt > > -- clocks: device clocks. See ../clocks/clock-bindings.txt for details. > > -- clock-names: the following clocks are required. > > - * "iface" > > - * "bus" > > - * "vsync" > > -- #address-cells: number of address cells for the MDSS children. Should be > > 1. > > -- #size-cells: Should be 1. > > -- ranges: parent bus address space is the same as the child bus address > > space. > > - > > -Optional properties: > > -- clock-names: the following clocks are optional: > > - * "lut" > > - > > MDP5: > > Required properties: > > - compatible: > > diff --git a/Documentation/devicetree/bindings/display/msm/mdss.yaml > > b/Documentation/devicetree/bindings/display/msm/mdss.yaml > > new file mode 100644 > > index ..8860fc55cca5 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/display/msm/mdss.yaml > > @@ -0,0 +1,166 @@ > > +# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/display/msm/mdss.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: Qualcomm Mobile Display SubSystem (MDSS) > > + > > +maintainers: > > + - Dmitry Baryshkov > > + - Rob Clark > > + > > +description: > > + This is the bindings documentation for the Mobile Display Subsytem(MDSS) > > that > > + encapsulates sub-blocks like MDP5, DSI, HDMI, eDP, etc. > > + > > +properties: > > + compatible: > > +enum: > > + - qcom,mdss > > + > > + reg: > > +minItems: 2 > > +maxItems: 3 > > + > > + reg-names: > > +minItems: 2 > > +items: > > + - const: mdss_phys > > + - const: vbif_phys > > + - const: vbif_nrt_phys > > + > > + interrupts: > > +maxItems: 1 > > + > > + interrupt-controller: > > +true > > If there is going to be v7 - please make it one line. > > > + > > + "#interrupt-cells": > > +const: 1 > > + > > + power-domains: > > +maxItems: 1 > > +description: | > > + The MDSS power domain provided by GCC > > + > > + clocks: > > +minItems: 1 > > +items: > > + - description: Display abh clock > > + - description: Display axi clock > > + - description: Display vsync clock > > + > > + clock-names: > > +minItems: 1 > > +items: > > + - const: iface > > + - const: bus > > + - const: vsync > > + > > + "#address-cells": > > +const: 1 > > + > > + "#size-cells": > > +const: 1 > > + > > + ranges: > > +true > > Ditto. > > > + > > + resets: > > +items: > > + - description:
Re: [RFC PATCH 2/3] drm/msm: filter out modes for DSI bridge having unsupported clock
Hi Dmitry On 9/8/2022 7:46 AM, Dmitry Baryshkov wrote: On 30/08/2022 06:33, Abhinav Kumar wrote: DSI interface used with a bridge chip connected to an external display is subject to the same pixel clock limits as one which is natively pluggable like DisplayPort. Hence filter out DSI modes having an unsupported pixel clock if its connected to a bridge which is pluggable. Ideally, this can be accommodated into msm_dsi_modeset_init() by passing an extra parameter but this will also affect non-dpu targets. Till we add the same logic for non-dpu chipsets, lets have this as a separate call. I think this makes DP/DSI depend too much on the DPU and DPU internals. Can we instead use clk_round_rate() in the .mode_valid in DSI/DP/HDMI drivers in order to check that the requested rate can be achieved? Just to update here what we discussed offline. Even if we do implement the clk_round_rate(), for the pixel clk it will trickle down to the PLL's limits. This is within the PLL's limits so it wont effectively filter out the 4k mode.
Re: [RFC PATCH 3/3] drm/msm: filter out modes for DP/eDP bridge having unsupported clock
On 9/7/2022 6:12 PM, Stephen Boyd wrote: Quoting Abhinav Kumar (2022-08-29 20:33:09) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index bfd0aeff3f0d..8b91d8adf921 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -117,6 +117,7 @@ struct dp_display_private { bool wide_bus_en; + int max_ext_pclk; Same signed comment as before. This is in Khz. It cannot be negative. I was also thinking of an unsigned int for this but the drm_display_mode's clock is an int so i also kept it like this. 227 struct drm_display_mode { 228 /** 229 * @clock: 230 * 231 * Pixel clock in kHz. 232 */ 233 int clock;/* in kHz */ 234 u16 hdisplay; struct dp_audio *audio; }; @@ -986,8 +987,15 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge, if (dp->is_edp) return MODE_OK; - if (mode->clock > DP_MAX_PIXEL_CLK_KHZ) - return MODE_CLOCK_HIGH; + /* +* If DP/eDP supports HPD natively or through a bridge, need to make +* sure that we filter out the modes with pixel clock higher than the +* chipset capabilities +*/ + if ((bridge->ops & DRM_BRIDGE_OP_HPD) || + (dp->next_bridge && (dp->next_bridge->ops & DRM_BRIDGE_OP_HPD))) Doesn't drm_bridge_chain_mode_valid() already run the mode_valid bridge function for all bridges in the chain? I don't understand why we need to peek at the bridge or the next bridge and only filter in that case. Why can't we always filter modes here? Do we want to allow higher pixel clks than the chip supports? The next bridge does not know about the max capability of the previous bridge. If the DP is used as a built-in display, we dont want this filter. If the DP is used as the external display either directly or with the next/last bridge as the pluggable one, then we want to apply this filter. The reason we cant always filter modes here is that lets say the DP is being used as a built-in display, then this filter is not needed. Now coming to the HPD part of the next bridge, its not necessary that we use the DP bridge's HPD. We could be using the external bridge's HPD. Like the DSI patch, I should change this to check the last bridge's HPD bridge op. + if (mode->clock > dp_display->max_ext_pclk) + return MODE_CLOCK_HIGH;
Re: [RFC PATCH 2/3] drm/msm: filter out modes for DSI bridge having unsupported clock
Hi Stephen On 9/7/2022 6:06 PM, Stephen Boyd wrote: Quoting Abhinav Kumar (2022-08-29 20:33:08) diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c index 39bbabb5daf6..3a06a157d1b1 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.c +++ b/drivers/gpu/drm/msm/dsi/dsi.c @@ -265,6 +265,11 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, return ret; } +void msm_dsi_set_max_extpclk(struct msm_dsi *msm_dsi, int max_ext_pclk) Do we really need a 'setter' API for something like this? Why can't we directly access the constant value for the max clk in the function that uses it to limit modes? That constant value is part of the DPU catalog. the value needs to be passed from the DPU to DSI/DP for it to use. Hence the setter API. In this RFC atleast, this is being modeled as a DPU catalog entry. +{ +msm_dsi_host_set_max_extpclk(msm_dsi->host, max_ext_pclk); +} + void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi) { msm_dsi_host_snapshot(disp_state, msm_dsi->host); diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 2a96b4fe7839..1be4ebb0f9c8 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -93,8 +93,9 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, int msm_dsi_host_power_off(struct mipi_dsi_host *host); int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, const struct drm_display_mode *mode); -enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, - const struct drm_display_mode *mode); +enum drm_mode_status msm_dsi_host_mode_valid(struct mipi_dsi_host *host, + const struct drm_display_mode *mode, + struct drm_bridge *ext_bridge); unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); int msm_dsi_host_register(struct mipi_dsi_host *host); void msm_dsi_host_unregister(struct mipi_dsi_host *host); @@ -109,6 +110,7 @@ void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host, void msm_dsi_host_destroy(struct mipi_dsi_host *host); int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct drm_device *dev); +void msm_dsi_host_set_max_extpclk(struct mipi_dsi_host *host, int max_ext_pclk); int msm_dsi_host_init(struct msm_dsi *msm_dsi); int msm_dsi_runtime_suspend(struct device *dev); int msm_dsi_runtime_resume(struct device *dev); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 57a4c0fa614b..4428a6a66ee1 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -172,6 +172,9 @@ struct msm_dsi_host { int dlane_swap; int num_data_lanes; + /* max pixel clock when used with a bridge chip */ + int max_ext_pclk; Will pixel clock be negative? What units is this in? Hz? This is in Khz. It cannot be negative. I was also thinking of an unsigned int for this but the drm_display_mode's clock is an int so i also kept it like this. 227 struct drm_display_mode { 228 /** 229 * @clock: 230 * 231 * Pixel clock in kHz. 232 */ 233 int clock; /* in kHz */ 234 u16 hdisplay; + /* from phy DT */ bool cphy_mode; @@ -2076,6 +2079,13 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, return 0; } +void msm_dsi_host_set_max_extpclk(struct mipi_dsi_host *host, int max_ext_pclk) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + + msm_host->max_ext_pclk = max_ext_pclk; +} + int msm_dsi_host_register(struct mipi_dsi_host *host) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); @@ -2548,17 +2558,14 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, return 0; } -enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, - const struct drm_display_mode *mode) +static enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, + const struct drm_display_mode *mode) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); struct drm_dsc_config *dsc = msm_host->dsc; int pic_width = mode->hdisplay; int pic_height = mode->vdisplay; - if (!msm_host->dsc) - return MODE_OK; - if (pic_width % dsc->slice_width) { pr_err("DSI: pic_width %d has to be multiple of slice %d\n", pic_width, dsc->slice_width); @@ -2574,6 +2581,29 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, return MODE_OK; } +enum drm_mode_status msm_dsi_host_mode_valid(struct mipi_dsi_host *host, + const struct drm_display_mode *mode, +
Re: Rust in our code base
will merge Rusticl tomorrow or so unless somebody complains. On Wed, Aug 24, 2022 at 5:34 PM Karol Herbst wrote: > > On Wed, Aug 24, 2022 at 5:18 PM Jason Ekstrand > wrote: > > > > +mesa-dev and my jlekstrand.net e-mail > > > > On Sun, 2022-08-21 at 20:44 +0200, Karol Herbst wrote: > > > On Sun, Aug 21, 2022 at 8:34 PM Rob Clark > > > wrote: > > > > > > > > On Sun, Aug 21, 2022 at 10:45 AM Karol Herbst > > > > wrote: > > > > > > > > > > On Sun, Aug 21, 2022 at 7:43 PM Karol Herbst > > > > > wrote: > > > > > > > > > > > > On Sun, Aug 21, 2022 at 5:46 PM Rob Clark > > > > > > wrote: > > > > > > > > > > > > > > On Sat, Aug 20, 2022 at 5:23 AM Karol Herbst > > > > > > > wrote: > > > > > > > > > > > > > > > > Hey everybody, > > > > > > > > > > > > > > > > so I think it's time to have this discussion for real. > > > > > > > > > > > > > > > > I am working on Rusticl > > > > > > > > ( > > > > > > > > https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15 > > > > > > > > 439) > > > > > > > > which I would like to merge quite soon. > > > > > > > > > > > > > > > > Others might also plan on starting kernel drivers written > > > > > > > > in Rust (and > > > > > > > > if people feel comfortable to discuss this as well, they > > > > > > > > might reply > > > > > > > > here) > > > > > > > > > > > > > > > > The overall implication of that is: if we are doing this, > > > > > > > > people (that > > > > > > > > is we) have to accept that touching Rust code will be part > > > > > > > > of our > > > > > > > > development process. There is no other sane way of doing > > > > > > > > it. > > > > > > > > > > > > > > > > I am not willing to wrap things in Rusticl so changing > > > > > > > > gallium APIs > > > > > > > > won't involve touching Rust code, and we also can't expect > > > > > > > > people to > > > > > > > > design their kernel drivers in weird ways "just because > > > > > > > > somebody > > > > > > > > doesn't want to deal with Rust" > > > > > > > > > > > > > > > > If we are going to do this, we have to do it for real, > > > > > > > > which means, > > > > > > > > Rust code will call C APIs directly and a change in those > > > > > > > > APIs will > > > > > > > > also require changes in Rust code making use of those APIs. > > > > > > > > > > > > > > > > I am so explicit on this very point, because we had some > > > > > > > > discussion on > > > > > > > > IRC where this was seen as a no-go at least from some > > > > > > > > people, which > > > > > > > > makes me think we have to find a mutual agreement on how it > > > > > > > > should be > > > > > > > > going forward. > > > > > > > > > > > > > > > > And I want to be very explicit here about the future of > > > > > > > > Rusticl as > > > > > > > > well: if the agreement is that people don't want to have to > > > > > > > > deal with > > > > > > > > Rust changing e.g. gallium, Rusticl is a dead project. I am > > > > > > > > not > > > > > > > > willing to come up with some trashy external-internal API > > > > > > > > just to > > > > > > > > maintain Rusticl outside of the mesa git repo. > > > > > > > > And doing it on a kernel level is even more of a no-go. > > > > > > > > > > > > > > > > So what are we all thinking about Rust in our core repos? > > > > > > > > > > > > > > I think there has to be willingness on the part of rust folks > > > > > > > to help > > > > > > > others who aren't so familiar with rust with these sorts of > > > > > > > API > > > > > > > changes. You can't completely impose the burden on others > > > > > > > who have > > > > > > > never touched rust before. That said, I expect a lot of API > > > > > > > changes > > > > > > > over time are simple enough that other devs could figure out > > > > > > > the > > > > > > > related rust side changes. > > > > > > > > > > > > > > > > > > > yeah, I agree here. I wouldn't say it's all the responsibility > > > > > > of > > > > > > developers changing APIs to also know how to change the code. > > > > > > So e.g. > > > > > > if an MR fails to compile and it's because of rusticl, I will > > > > > > help out > > > > > > and do the changes myself if necessary. But long term we have > > > > > > to > > > > > > accept that API changes also come with the implication of also > > > > > > having > > > > > > to touch Rust code. > > > > > > > > > > > > Short term it might be a learning opportunity for some/most, > > > > > > but long > > > > > > term it has to be accepted as a part of development to deal > > > > > > with Rust. > > > > > > > > > > > > > As long as folks who want to start introducing rust in mesa > > > > > > > and drm > > > > > > > realize they are also signing up to play the role of rust > > > > > > > tutor and > > > > > > > technical assistance, I don't see a problem. But if they > > > > > > > aren't > > > > > > > around and willing to help, I could see this going badly. > > > > > > > > > > > > > > > > > > > Yep, I fully agree here. This is also the main reason I am > > > > > > bringing > > > > > >
[PATCH] drm: remove unnecessary conditionals
iput() has already handled null and non-null parameter, so it is no need to use if(). Signed-off-by: Jingyu Wang --- drivers/gpu/drm/drm_drv.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8214a0b1ab7f..beec45a89ca5 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -530,10 +530,8 @@ static struct inode *drm_fs_inode_new(void) static void drm_fs_inode_free(struct inode *inode) { - if (inode) { - iput(inode); - simple_release_fs(_fs_mnt, _fs_cnt); - } + iput(inode); + simple_release_fs(_fs_mnt, _fs_cnt); } /** base-commit: 5957ac6635a1a12d4aa2661bbf04d3085a73372a -- 2.34.1
Re: [PATCH 1/3] drm/scheduler: track GPU active time per entity
On 2022-09-08 14:10, Lucas Stach wrote: Track the accumulated time that jobs from this entity were active on the GPU. This allows drivers using the scheduler to trivially implement the DRM fdinfo when the hardware doesn't provide more specific information than signalling job completion anyways. Signed-off-by: Lucas Stach --- drivers/gpu/drm/scheduler/sched_main.c | 6 ++ include/drm/gpu_scheduler.h| 7 +++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 76fd2904c7c6..24c77a6a157f 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -847,6 +847,12 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) spin_unlock(>job_list_lock); + if (job) { + job->entity->elapsed_ns += ktime_to_ns( + ktime_sub(job->s_fence->finished.timestamp, + job->s_fence->scheduled.timestamp)); + } + return job; Looks like you making as assumption that drm_sched_entity will always be allocated using kzalloc ? Isn't it a bit dangerous assumption ? Andrey } diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index addb135eeea6..573bef640664 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -196,6 +196,13 @@ struct drm_sched_entity { * drm_sched_entity_fini(). */ struct completion entity_idle; + /** +* @elapsed_ns +* +* Records the amount of time where jobs from this entity were active +* on the GPU. +*/ + uint64_t elapsed_ns; }; /**
Re: [PATCH 1/4] drm/sched: returns struct drm_gpu_scheduler ** for drm_sched_pick_best
Please send everything together because otherwise it's not clear why we need this. Andrey On 2022-09-08 11:09, James Zhu wrote: Yes, it is for NPI design. I will send out patches for review soon. Thanks! James On 2022-09-08 11:05 a.m., Andrey Grodzovsky wrote: So this is the real need of this patch-set, but this explanation doesn't appear anywhere in the description. It's always good to add a short 0 RFC patch which describes the intention of the patchset if the code is not self explanatory. And I still don't understand the need - i don't see anything in amdgpu_ctx_fini_entity regarding rings tracking ? Is it a new code you plan to add and not included in this patcheset ? Did i miss an earlier patch maybe ? Andrey On 2022-09-08 10:45, James Zhu wrote: To save lines is not the purpose. Also I want to use entity->sched_list to track ring which is used in this ctx in amdgpu_ctx_fini_entity Best Regards! James On 2022-09-08 10:38 a.m., Andrey Grodzovsky wrote: I guess it's an option but i don't really see what's the added value ? You saved a few lines in this patch but added a few lines in another. In total seems to me no to much difference ? Andrey On 2022-09-08 10:17, James Zhu wrote: Hi Andrey Basically this entire patch set are derived from patch [3/4]: entity->sched_list = num_sched_list > 1 ? sched_list : NULL; I think no special reason to treat single and multiple schedule list here. Best Regards! James On 2022-09-08 10:08 a.m., Andrey Grodzovsky wrote: What's the reason for this entire patch set ? Andrey On 2022-09-07 16:57, James Zhu wrote: drm_sched_pick_best returns struct drm_gpu_scheduler ** instead of struct drm_gpu_scheduler * Signed-off-by: James Zhu --- include/drm/gpu_scheduler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index 0fca8f38bee4..011f70a43397 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -529,7 +529,7 @@ void drm_sched_fence_finished(struct drm_sched_fence *fence); unsigned long drm_sched_suspend_timeout(struct drm_gpu_scheduler *sched); void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched, unsigned long remaining); -struct drm_gpu_scheduler * +struct drm_gpu_scheduler ** drm_sched_pick_best(struct drm_gpu_scheduler **sched_list, unsigned int num_sched_list);
Re: [PATCH] amd/amdkfd: fix repeated words in comments
On 2022-09-08 09:17, wangjianli wrote: Delete the redundant word 'to'. Signed-off-by: wangjianli Reviewed-by: Felix Kuehling I'll apply this to amd-staging-drm-next. Thanks, Felix --- drivers/gpu/drm/amd/amdkfd/kfd_crat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 24b414cff3ec..cd5f8b219bf9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -2284,7 +2284,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, /* Fill in Subtype: IO_LINKS * Only direct links are added here which is Link from GPU to -* to its NUMA node. Indirect links are added by userspace. +* its NUMA node. Indirect links are added by userspace. */ sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr + cache_mem_filled);
Re: [pull] amdgpu, amdkfd, radeon, drm drm-next-6.1
On 2022-09-08 12:35, Alex Deucher wrote: On Thu, Sep 8, 2022 at 12:29 PM Felix Kuehling wrote: On 2022-09-08 11:52, Alex Deucher wrote: Hi Dave, Daniel, New stuff for 6.1. The following changes since commit 085292c3d78015412b752ee1ca4c7725fd2bf2fc: Revert "drm/amd/amdgpu: add pipe1 hardware support" (2022-08-16 18:14:31 -0400) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-next-6.1-2022-09-08 for you to fetch changes up to 780244a2fe8a82424c85f4cb15e45d0bbeec8f26: drm/amd/amdgpu: Add missing CGTS*TCC_DISABLE to 10.3 headers (2022-09-07 22:28:42 -0400) amd-drm-next-6.1-2022-09-08: amdgpu: - Mode2 reset for RDNA2 - Lots of new DC documentation - Add documentation about different asic families - DSC improvements - Aldebaran fixes - Misc spelling and grammar fixes - GFXOFF stats support for vangogh - DC frame size fixes - NBIO 7.7 updates - DCN 3.2 updates - DCN 3.1.4 Updates - SMU 13.x updates - Misc bug fixes - Rework DC register offset handling - GC 11.x updates - PSP 13.x updates - SDMA 6.x updates - GMC 11.x updates - SR-IOV updates - PSP fixes for TA unloading - DSC passthrough support - Misc code cleanups amdkfd: - ISA fixes for some GC 10.3 IPs - Misc code cleanups radeon: - Delayed work flush fix - Use time_after for some jiffies calculations drm: - DSC passthrough aux support Alex Deucher (1): drm/amd/display: fix documentation for amdgpu_dm_update_freesync_caps() Alex Sierra (1): drm/amdgpu: ensure no PCIe peer access for CPU XGMI iolinks Alvin Lee (6): drm/amd/display: Free phantom plane and stream properly drm/amd/display: Add interface to track PHY state drm/amd/display: Uncomment SubVP scaling case drm/amd/display: Don't choose SubVP display if ActiveMargin > 0 drm/amd/display: Only commit SubVP state after pipe programming drm/amd/display: SubVP missing scaling case André Almeida (4): drm/amd: Add detailed GFXOFF stats to debugfs drm/amd/pm: Implement GFXOFF's entry count and residency for vangogh Documentation/gpu: Document GFXOFF's count and residency drm/amdgpu: Document gfx_off members of struct amdgpu_gfx Anthony Koo (2): drm/amd/display: [FW Promotion] Release 0.0.130.0 drm/amd/display: [FW Promotion] Release 0.0.132.0 Aric Cyr (3): drm/amd/display: 3.2.199 drm/amd/display: 3.2.200 drm/amd/display: 3.2.201 Asher Song (1): drm/amd/display: remove a duplicated declaration Aurabindo Pillai (8): drm/amd/display: change to runtime initialization for reg offsets for DCN32 drm/amd/display: change to runtime initialization for reg offsets for DCN321 drm/amd/display: program k1/k2 divider for virtual signal for DCN32 drm/amd/display: Fix CAB cursor size allocation for DCN32/321 drm/amd/display: disable display fresh from MALL on an edge case for DCN321 drm/amd/display: use actual cursor size instead of max for CAB allocation drm/amd/display: Revert "program k1/k2 divider for virtual signal for DCN32" drm/amd/display: Use correct plane for CAB cursor size allocation Bernard Zhao (4): drm/amd: fix potential memory leak drm/amd: fix potential memory leak drm/amd: remove possible condition with no effect (if == else) drm/amd: remove possible condition with no effect (if == else) Candice Li (1): drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. Charlene Liu (1): drm/amd/display: fix wrong register access Chengming Gui (3): drm/amd/amdgpu: avoid soft reset check when gpu recovery disabled drm/amd/amdgpu: skip ucode loading if ucode_size == 0 drm/amd/amdgpu: add rlc_firmware_header_v2_4 to amdgpu_firmware_header David Belanger (1): drm/amdkfd: Added GFX 11.0.3 Support David Gow (1): drm/amd/display: fix overflow on MIN_I64 definition Derek Lai (1): drm/amd/display: do not change pipe split policy for RV2 Duncan Ma (1): drm/amd/display: Fix OTG H timing reset for dcn314 Ethan Wellenreiter (2): drm/amd/display: Re-initialize viewport after pipe merge drm/amd/display: Fix check for stream and plane Evan Quan (5): drm/amd/pm: update SMU 13.0.0 driver_if header drm/amd/pm: use vbios carried pptable for those supported SKUs drm/amd/pm: use vbios carried pptable for all SMU13.0.7 SKUs drm/amd/pm: bump SMU 13.0.0 driver_if header version drm/amd/pm: add missing SetMGpuFanBoostLimitRpm mapping for SMU 13.0.7 Felix Kuehling (1): drm/amdkfd: Allocate doorbells only when needed This patch broke CRIU. Rajneesh posted a fix for it. I'd recommend including the fix, though we're still debating the root cause
Re: [PATCH v4 07/11] drm/i915/mtl: Add DP AUX support on TypeC ports
On Thu, Sep 01, 2022 at 11:03:38PM -0700, Radhakrishna Sripada wrote: > From: Imre Deak > > On MTL TypeC ports the AUX_CH_CTL and AUX_CH_DATA addresses have > changed wrt. previous platforms, adjust the code accordingly. > > Signed-off-by: Imre Deak > Signed-off-by: Radhakrishna Sripada As noted on the previous patch, the _XELPDP_USBC1_AUX_CH_DATA* definitions aren't used until this patch so they should probably move into this one. Aside from that, Reviewed-by: Matt Roper > --- > drivers/gpu/drm/i915/display/intel_dp_aux.c | 45 - > drivers/gpu/drm/i915/i915_reg.h | 9 + > 2 files changed, 53 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c > b/drivers/gpu/drm/i915/display/intel_dp_aux.c > index 98bd33645b43..48c375c65a41 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c > @@ -637,6 +637,46 @@ static i915_reg_t tgl_aux_data_reg(struct intel_dp > *intel_dp, int index) > } > } > > +static i915_reg_t xelpdp_aux_ctl_reg(struct intel_dp *intel_dp) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + enum aux_ch aux_ch = dig_port->aux_ch; > + > + switch (aux_ch) { > + case AUX_CH_A: > + case AUX_CH_B: > + case AUX_CH_USBC1: > + case AUX_CH_USBC2: > + case AUX_CH_USBC3: > + case AUX_CH_USBC4: > + return XELPDP_DP_AUX_CH_CTL(aux_ch); > + default: > + MISSING_CASE(aux_ch); > + return XELPDP_DP_AUX_CH_CTL(AUX_CH_A); > + } > +} > + > +static i915_reg_t xelpdp_aux_data_reg(struct intel_dp *intel_dp, int index) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + enum aux_ch aux_ch = dig_port->aux_ch; > + > + switch (aux_ch) { > + case AUX_CH_A: > + case AUX_CH_B: > + case AUX_CH_USBC1: > + case AUX_CH_USBC2: > + case AUX_CH_USBC3: > + case AUX_CH_USBC4: > + return XELPDP_DP_AUX_CH_DATA(aux_ch, index); > + default: > + MISSING_CASE(aux_ch); > + return XELPDP_DP_AUX_CH_DATA(AUX_CH_A, index); > + } > +} > + > void intel_dp_aux_fini(struct intel_dp *intel_dp) > { > if (cpu_latency_qos_request_active(_dp->pm_qos)) > @@ -652,7 +692,10 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) > struct intel_encoder *encoder = _port->base; > enum aux_ch aux_ch = dig_port->aux_ch; > > - if (DISPLAY_VER(dev_priv) >= 12) { > + if (DISPLAY_VER(dev_priv) >= 14) { > + intel_dp->aux_ch_ctl_reg = xelpdp_aux_ctl_reg; > + intel_dp->aux_ch_data_reg = xelpdp_aux_data_reg; > + } else if (DISPLAY_VER(dev_priv) >= 12) { > intel_dp->aux_ch_ctl_reg = tgl_aux_ctl_reg; > intel_dp->aux_ch_data_reg = tgl_aux_data_reg; > } else if (DISPLAY_VER(dev_priv) >= 9) { > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 99b2cd2abca4..4ec6a3dd1f2b 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3470,6 +3470,15 @@ > > _XELPDP_USBC3_AUX_CH_CTL, \ > > _XELPDP_USBC4_AUX_CH_CTL)) > > +#define XELPDP_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PICK(aux_ch, \ > +_DPA_AUX_CH_DATA1, \ > +_DPB_AUX_CH_DATA1, \ > +0, /* port/aux_ch C is > non-existent */ \ > + > _XELPDP_USBC1_AUX_CH_DATA1, \ > + > _XELPDP_USBC2_AUX_CH_DATA1, \ > + > _XELPDP_USBC3_AUX_CH_DATA1, \ > + > _XELPDP_USBC4_AUX_CH_DATA1) + (i) * 4) > + > #define DP_AUX_CH_CTL_SEND_BUSY(1 << 31) > #define DP_AUX_CH_CTL_DONE (1 << 30) > #define DP_AUX_CH_CTL_INTERRUPT(1 << 29) > -- > 2.34.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
Re: [PATCH v4 06/11] drm/i915/mtl: Add display power wells
On Thu, Sep 08, 2022 at 11:07:16AM -0700, Matt Roper wrote: > On Thu, Sep 01, 2022 at 11:03:37PM -0700, Radhakrishna Sripada wrote: > > From: Imre Deak > > > > Add support for display power wells on MTL. The differences from XE_LPD: > > - The AUX HW block is moved to the PICA block, where the registers are on > > an always-on power well and the functionality needs to be powered on/off > > via the AUX_CH_CTL register: [1], [2] > > - The DDI IO power on/off programming sequence is moved to the PHY PLL > > enable/disable sequence. [3], [4], [5] > > > > Bspec: [1] 49233, [2] 65247, [3] 64568, [4] 65451, [5] 65450 > > > > v2: > > - Update the comment in aux power well enable > > - Reuse the noop sync fn for aux sync. > > - Use REG_BIT for new register bit definitions > > > > Signed-off-by: Imre Deak > > Signed-off-by: Radhakrishna Sripada > > Reviewed-by: Matt Roper Oops, one very minor comment down at the bottom. > > > --- > > .../i915/display/intel_display_power_map.c| 115 +- > > .../i915/display/intel_display_power_well.c | 44 +++ > > .../i915/display/intel_display_power_well.h | 4 + > > drivers/gpu/drm/i915/display/intel_dp_aux.c | 8 ++ > > drivers/gpu/drm/i915/i915_reg.h | 21 > > 5 files changed, 191 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c > > b/drivers/gpu/drm/i915/display/intel_display_power_map.c > > index 5ddd1b93751c..dc04afc6cc8f 100644 > > --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c > > +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c > > @@ -1350,6 +1350,117 @@ static const struct i915_power_well_desc_list > > xelpd_power_wells[] = { > > I915_PW_DESCRIPTORS(xelpd_power_wells_main), > > }; > > > > +/* > > + * MTL is based on XELPD power domains with the exception of power gating > > for: > > + * - DDI_IO (moved to PLL logic) > > + * - AUX and AUX_IO functionality and register access for USBC1-4 (PICA > > always-on) > > + */ > > +#define XELPDP_PW_2_POWER_DOMAINS \ > > + XELPD_PW_B_POWER_DOMAINS, \ > > + XELPD_PW_C_POWER_DOMAINS, \ > > + XELPD_PW_D_POWER_DOMAINS, \ > > + POWER_DOMAIN_AUDIO_PLAYBACK, \ > > + POWER_DOMAIN_VGA, \ > > + POWER_DOMAIN_PORT_DDI_LANES_TC1, \ > > + POWER_DOMAIN_PORT_DDI_LANES_TC2, \ > > + POWER_DOMAIN_PORT_DDI_LANES_TC3, \ > > + POWER_DOMAIN_PORT_DDI_LANES_TC4 > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_pw_2, > > + XELPDP_PW_2_POWER_DOMAINS, > > + POWER_DOMAIN_INIT); > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_dc_off, > > + XELPDP_PW_2_POWER_DOMAINS, > > + POWER_DOMAIN_AUDIO_MMIO, > > + POWER_DOMAIN_MODESET, > > + POWER_DOMAIN_AUX_A, > > + POWER_DOMAIN_AUX_B, > > + POWER_DOMAIN_INIT); > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc1, > > + POWER_DOMAIN_AUX_USBC1, > > + POWER_DOMAIN_AUX_TBT1); > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc2, > > + POWER_DOMAIN_AUX_USBC2, > > + POWER_DOMAIN_AUX_TBT2); > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc3, > > + POWER_DOMAIN_AUX_USBC3, > > + POWER_DOMAIN_AUX_TBT3); > > + > > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc4, > > + POWER_DOMAIN_AUX_USBC4, > > + POWER_DOMAIN_AUX_TBT4); > > + > > +static const struct i915_power_well_desc xelpdp_power_wells_main[] = { > > + { > > + .instances = _PW_INSTANCES( > > + I915_PW("DC_off", _pwdoms_dc_off, > > + .id = SKL_DISP_DC_OFF), > > + ), > > + .ops = _dc_off_power_well_ops, > > + }, { > > + .instances = _PW_INSTANCES( > > + I915_PW("PW_2", _pwdoms_pw_2, > > + .hsw.idx = ICL_PW_CTL_IDX_PW_2, > > + .id = SKL_DISP_PW_2), > > + ), > > + .ops = _power_well_ops, > > + .has_vga = true, > > + .has_fuses = true, > > + }, { > > + .instances = _PW_INSTANCES( > > + I915_PW("PW_A", _pwdoms_pw_a, > > + .hsw.idx = XELPD_PW_CTL_IDX_PW_A), > > + ), > > + .ops = _power_well_ops, > > + .irq_pipe_mask = BIT(PIPE_A), > > + .has_fuses = true, > > + }, { > > + .instances = _PW_INSTANCES( > > + I915_PW("PW_B", _pwdoms_pw_b, > > + .hsw.idx = XELPD_PW_CTL_IDX_PW_B), > > + ), > > + .ops = _power_well_ops, > > + .irq_pipe_mask = BIT(PIPE_B), > > + .has_fuses = true, > > + }, { > > + .instances = _PW_INSTANCES( > > + I915_PW("PW_C", _pwdoms_pw_c, > > + .hsw.idx = XELPD_PW_CTL_IDX_PW_C), > > + ), > > + .ops = _power_well_ops, > > + .irq_pipe_mask = BIT(PIPE_C), > > + .has_fuses = true, > > + }, { > > + .instances = _PW_INSTANCES( > > + I915_PW("PW_D",
[PATCH 2/3] drm/etnaviv: allocate unique ID per drm_file
Allows to easily track if several fd are pointing to the same execution context due to being dup'ed. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 3 +++ drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 1d2b4fb4bcf8..b69edb40ae2a 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -49,6 +49,7 @@ static void load_gpu(struct drm_device *dev) static int etnaviv_open(struct drm_device *dev, struct drm_file *file) { struct etnaviv_drm_private *priv = dev->dev_private; + static atomic_t ident = ATOMIC_INIT(0); struct etnaviv_file_private *ctx; int ret, i; @@ -56,6 +57,8 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) if (!ctx) return -ENOMEM; + ctx->id = atomic_inc_return(); + ctx->mmu = etnaviv_iommu_context_init(priv->mmu_global, priv->cmdbuf_suballoc); if (!ctx->mmu) { diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index f32f4771dada..851b4b4ef146 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -27,6 +27,7 @@ struct etnaviv_iommu_global; #define ETNAVIV_SOFTPIN_START_ADDRESS SZ_4M /* must be >= SUBALLOC_SIZE */ struct etnaviv_file_private { + int id; struct etnaviv_iommu_context*mmu; struct drm_sched_entity sched_entity[ETNA_MAX_PIPES]; }; -- 2.30.2
[PATCH 1/3] drm/scheduler: track GPU active time per entity
Track the accumulated time that jobs from this entity were active on the GPU. This allows drivers using the scheduler to trivially implement the DRM fdinfo when the hardware doesn't provide more specific information than signalling job completion anyways. Signed-off-by: Lucas Stach --- drivers/gpu/drm/scheduler/sched_main.c | 6 ++ include/drm/gpu_scheduler.h| 7 +++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 76fd2904c7c6..24c77a6a157f 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -847,6 +847,12 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) spin_unlock(>job_list_lock); + if (job) { + job->entity->elapsed_ns += ktime_to_ns( + ktime_sub(job->s_fence->finished.timestamp, + job->s_fence->scheduled.timestamp)); + } + return job; } diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h index addb135eeea6..573bef640664 100644 --- a/include/drm/gpu_scheduler.h +++ b/include/drm/gpu_scheduler.h @@ -196,6 +196,13 @@ struct drm_sched_entity { * drm_sched_entity_fini(). */ struct completion entity_idle; + /** +* @elapsed_ns +* +* Records the amount of time where jobs from this entity were active +* on the GPU. +*/ + uint64_t elapsed_ns; }; /** -- 2.30.2
[PATCH 3/3] drm/etnaviv: export client GPU usage statistics via fdinfo
This exposes a accumulated GPU active time per client via the fdinfo infrastructure. Signed-off-by: Lucas Stach --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 38 ++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index b69edb40ae2a..11b1f11fcb58 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -22,6 +22,7 @@ #include "etnaviv_gem.h" #include "etnaviv_mmu.h" #include "etnaviv_perfmon.h" +#include "common.xml.h" /* * DRM operations: @@ -471,7 +472,42 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = { ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW), }; -DEFINE_DRM_GEM_FOPS(fops); +static void etnaviv_fop_show_fdinfo(struct seq_file *m, struct file *f) +{ + struct drm_file *file = f->private_data; + struct drm_device *dev = file->minor->dev; + struct etnaviv_drm_private *priv = dev->dev_private; + struct etnaviv_file_private *ctx = file->driver_priv; + struct drm_printer p = drm_seq_file_printer(m); + int i; + + drm_printf(, "drm-driver:\t%s\n", dev->driver->name); + drm_printf(, "drm-client-id:\t%u\n", ctx->id); + + for (i = 0; i < ETNA_MAX_PIPES; i++) { +struct etnaviv_gpu *gpu = priv->gpu[i]; + char engine[8]; + int cur = 0; + + if (!gpu) + continue; + + if (gpu->identity.features & chipFeatures_PIPE_2D) + cur = snprintf(engine, sizeof(engine), "2D"); + if (gpu->identity.features & chipFeatures_PIPE_3D) + cur = snprintf(engine + cur, sizeof(engine) - cur, + "%s3D", cur ? "/" : ""); + + drm_printf(, "drm-engine-%s:\t%llu ns\n", engine, + ctx->sched_entity[i].elapsed_ns); + } +} + +static const struct file_operations fops = { +.owner = THIS_MODULE, +DRM_GEM_FOPS, +.show_fdinfo = etnaviv_fop_show_fdinfo, +}; static const struct drm_driver etnaviv_drm_driver = { .driver_features= DRIVER_GEM | DRIVER_RENDER, -- 2.30.2
Re: [PATCH v4 06/11] drm/i915/mtl: Add display power wells
On Thu, Sep 01, 2022 at 11:03:37PM -0700, Radhakrishna Sripada wrote: > From: Imre Deak > > Add support for display power wells on MTL. The differences from XE_LPD: > - The AUX HW block is moved to the PICA block, where the registers are on > an always-on power well and the functionality needs to be powered on/off > via the AUX_CH_CTL register: [1], [2] > - The DDI IO power on/off programming sequence is moved to the PHY PLL > enable/disable sequence. [3], [4], [5] > > Bspec: [1] 49233, [2] 65247, [3] 64568, [4] 65451, [5] 65450 > > v2: > - Update the comment in aux power well enable > - Reuse the noop sync fn for aux sync. > - Use REG_BIT for new register bit definitions > > Signed-off-by: Imre Deak > Signed-off-by: Radhakrishna Sripada Reviewed-by: Matt Roper > --- > .../i915/display/intel_display_power_map.c| 115 +- > .../i915/display/intel_display_power_well.c | 44 +++ > .../i915/display/intel_display_power_well.h | 4 + > drivers/gpu/drm/i915/display/intel_dp_aux.c | 8 ++ > drivers/gpu/drm/i915/i915_reg.h | 21 > 5 files changed, 191 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c > b/drivers/gpu/drm/i915/display/intel_display_power_map.c > index 5ddd1b93751c..dc04afc6cc8f 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c > +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c > @@ -1350,6 +1350,117 @@ static const struct i915_power_well_desc_list > xelpd_power_wells[] = { > I915_PW_DESCRIPTORS(xelpd_power_wells_main), > }; > > +/* > + * MTL is based on XELPD power domains with the exception of power gating > for: > + * - DDI_IO (moved to PLL logic) > + * - AUX and AUX_IO functionality and register access for USBC1-4 (PICA > always-on) > + */ > +#define XELPDP_PW_2_POWER_DOMAINS \ > + XELPD_PW_B_POWER_DOMAINS, \ > + XELPD_PW_C_POWER_DOMAINS, \ > + XELPD_PW_D_POWER_DOMAINS, \ > + POWER_DOMAIN_AUDIO_PLAYBACK, \ > + POWER_DOMAIN_VGA, \ > + POWER_DOMAIN_PORT_DDI_LANES_TC1, \ > + POWER_DOMAIN_PORT_DDI_LANES_TC2, \ > + POWER_DOMAIN_PORT_DDI_LANES_TC3, \ > + POWER_DOMAIN_PORT_DDI_LANES_TC4 > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_pw_2, > + XELPDP_PW_2_POWER_DOMAINS, > + POWER_DOMAIN_INIT); > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_dc_off, > + XELPDP_PW_2_POWER_DOMAINS, > + POWER_DOMAIN_AUDIO_MMIO, > + POWER_DOMAIN_MODESET, > + POWER_DOMAIN_AUX_A, > + POWER_DOMAIN_AUX_B, > + POWER_DOMAIN_INIT); > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc1, > + POWER_DOMAIN_AUX_USBC1, > + POWER_DOMAIN_AUX_TBT1); > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc2, > + POWER_DOMAIN_AUX_USBC2, > + POWER_DOMAIN_AUX_TBT2); > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc3, > + POWER_DOMAIN_AUX_USBC3, > + POWER_DOMAIN_AUX_TBT3); > + > +I915_DECL_PW_DOMAINS(xelpdp_pwdoms_aux_tc4, > + POWER_DOMAIN_AUX_USBC4, > + POWER_DOMAIN_AUX_TBT4); > + > +static const struct i915_power_well_desc xelpdp_power_wells_main[] = { > + { > + .instances = _PW_INSTANCES( > + I915_PW("DC_off", _pwdoms_dc_off, > + .id = SKL_DISP_DC_OFF), > + ), > + .ops = _dc_off_power_well_ops, > + }, { > + .instances = _PW_INSTANCES( > + I915_PW("PW_2", _pwdoms_pw_2, > + .hsw.idx = ICL_PW_CTL_IDX_PW_2, > + .id = SKL_DISP_PW_2), > + ), > + .ops = _power_well_ops, > + .has_vga = true, > + .has_fuses = true, > + }, { > + .instances = _PW_INSTANCES( > + I915_PW("PW_A", _pwdoms_pw_a, > + .hsw.idx = XELPD_PW_CTL_IDX_PW_A), > + ), > + .ops = _power_well_ops, > + .irq_pipe_mask = BIT(PIPE_A), > + .has_fuses = true, > + }, { > + .instances = _PW_INSTANCES( > + I915_PW("PW_B", _pwdoms_pw_b, > + .hsw.idx = XELPD_PW_CTL_IDX_PW_B), > + ), > + .ops = _power_well_ops, > + .irq_pipe_mask = BIT(PIPE_B), > + .has_fuses = true, > + }, { > + .instances = _PW_INSTANCES( > + I915_PW("PW_C", _pwdoms_pw_c, > + .hsw.idx = XELPD_PW_CTL_IDX_PW_C), > + ), > + .ops = _power_well_ops, > + .irq_pipe_mask = BIT(PIPE_C), > + .has_fuses = true, > + }, { > + .instances = _PW_INSTANCES( > + I915_PW("PW_D", _pwdoms_pw_d, > + .hsw.idx = XELPD_PW_CTL_IDX_PW_D), > + ), > + .ops = _power_well_ops, > + .irq_pipe_mask = BIT(PIPE_D), > + .has_fuses = true, > + }, { > +
Re: [RFC PATCH 0/3] Limit pluggable display modes
On 30/08/2022 06:33, Abhinav Kumar wrote: As reported on https://gitlab.freedesktop.org/drm/msm/-/issues/17, currently there is no mechanism to limit the display output to the pluggable displays and it lets users connect any monitor on any chipset based device. This can lead to undefined behavior because lets say the display advertises an unsupported pixel clock as its preferred resolution, then the end-user can experience undefined behavior such as black screen, crash or an underrun. The capabilities of every chipset are advertised in the product specification for both on-device displays and pluggable displays. After discussing this privately, it was agreed that there are two kinds of issues here: - filtering the modes which can not be handled by the DPU/DSI/DP hardware pieces themselves - filtering the modes which can not be handled by the external limitations (e.g. the bridge not being able to drive this mode, the pcb routing of data lanes being unable to sustain the rate, the connector being the limit, etc). Krzysztof, I'd like to ask your advice if adding a properly like `max-link-frequency' sounds like a good idea? The video-interfaces.yaml bindings already has the `link-frequencies' property, but it is an array of discrete frequencies supported by the link in the graph. In our case the list of frequencies is more or less continuous, with max (and min) values. Also, can it be added to the final device in the chain (e.g. hdmi/dp/vga connectors) or should it be added to the endpoint graph nodes? Documents such as [1], [2] and [3] can easily be found on the vendor's website which advertise the max resolution support for that chipset. Utilize this information to filter out the resolutions which have pixel clock more than the supported limits. This change only addresses pluggable displays because the underlying assumption is that for the built-in displays, the display being chosen for the product will be done so after referring to the advertised limits. For calculating the pixel clock, the value has been taken from the CEA speficiation if the resolution is a CEA one and from the CVT specification for non-CEA. This change has only been compile tested so far to get a general feedback first and once it takes a final shape, will validate on whatever devices I have and will appreciate help from others who have devices which I dont. [1]: https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf [2]: https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c_gen2.pdf [3]: https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd8cx_gen2.pdf Abhinav Kumar (3): drm/msm/dpu: add max external pixel clock for all targets drm/msm: filter out modes for DSI bridge having unsupported clock drm/msm: filter out modes for DP/eDP bridge having unsupported clock drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 18 drivers/gpu/drm/msm/dp/dp_display.c| 16 +-- drivers/gpu/drm/msm/dp/dp_parser.h | 1 - drivers/gpu/drm/msm/dsi/dsi.c | 5 drivers/gpu/drm/msm/dsi/dsi.h | 6 ++-- drivers/gpu/drm/msm/dsi/dsi_host.c | 40 ++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- drivers/gpu/drm/msm/msm_drv.h | 9 -- 10 files changed, 88 insertions(+), 19 deletions(-) -- With best wishes Dmitry
Re: [Intel-gfx] [PATCH v4 05/11] drm/i915/mtl: Add gmbus and gpio support
On Thu, Sep 01, 2022 at 11:03:36PM -0700, Radhakrishna Sripada wrote: > Add tables to map the GMBUS pin pairs to GPIO registers and port to DDC. > From spec we have registers GPIO_CTL[1-5] mapped to native display phys and > GPIO_CTL[9-12] are mapped to TC ports. > > v2: > - Drop unused GPIO pins(MattR) > > BSpec: 49306 > > Cc: Matt Roper > Original Author: Brian J Lovin > Signed-off-by: Radhakrishna Sripada Reviewed-by: Matt Roper > --- > drivers/gpu/drm/i915/display/intel_gmbus.c | 15 +++ > drivers/gpu/drm/i915/display/intel_gmbus.h | 1 + > 2 files changed, 16 insertions(+) > > diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c > b/drivers/gpu/drm/i915/display/intel_gmbus.c > index 6f6cfccad477..74443f57f62d 100644 > --- a/drivers/gpu/drm/i915/display/intel_gmbus.c > +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c > @@ -117,6 +117,18 @@ static const struct gmbus_pin gmbus_pins_dg2[] = { > [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ }, > }; > > +static const struct gmbus_pin gmbus_pins_mtp[] = { > + [GMBUS_PIN_1_BXT] = { "dpa", GPIOB }, > + [GMBUS_PIN_2_BXT] = { "dpb", GPIOC }, > + [GMBUS_PIN_3_BXT] = { "dpc", GPIOD }, > + [GMBUS_PIN_4_CNP] = { "dpd", GPIOE }, > + [GMBUS_PIN_5_MTP] = { "dpe", GPIOF }, > + [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ }, > + [GMBUS_PIN_10_TC2_ICP] = { "tc2", GPIOK }, > + [GMBUS_PIN_11_TC3_ICP] = { "tc3", GPIOL }, > + [GMBUS_PIN_12_TC4_ICP] = { "tc4", GPIOM }, > +}; > + > static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *i915, >unsigned int pin) > { > @@ -129,6 +141,9 @@ static const struct gmbus_pin *get_gmbus_pin(struct > drm_i915_private *i915, > } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { > pins = gmbus_pins_dg1; > size = ARRAY_SIZE(gmbus_pins_dg1); > + } else if (INTEL_PCH_TYPE(i915) >= PCH_MTP) { > + pins = gmbus_pins_mtp; > + size = ARRAY_SIZE(gmbus_pins_mtp); > } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { > pins = gmbus_pins_icp; > size = ARRAY_SIZE(gmbus_pins_icp); > diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.h > b/drivers/gpu/drm/i915/display/intel_gmbus.h > index 8edc2e99cf53..20f704bd4e70 100644 > --- a/drivers/gpu/drm/i915/display/intel_gmbus.h > +++ b/drivers/gpu/drm/i915/display/intel_gmbus.h > @@ -24,6 +24,7 @@ struct i2c_adapter; > #define GMBUS_PIN_2_BXT 2 > #define GMBUS_PIN_3_BXT 3 > #define GMBUS_PIN_4_CNP 4 > +#define GMBUS_PIN_5_MTP 5 > #define GMBUS_PIN_9_TC1_ICP 9 > #define GMBUS_PIN_10_TC2_ICP 10 > #define GMBUS_PIN_11_TC3_ICP 11 > -- > 2.34.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
Re: [Intel-gfx] [PATCH v4.1] drm/i915/mtl: Define engine context layouts
On Wed, Sep 07, 2022 at 04:33:17PM -0700, Radhakrishna Sripada wrote: > From: Matt Roper > > The part of the media and blitter engine contexts that we care about for > setting up an initial state are the same on MTL as they were on DG2 > (and PVC), so we need to update the driver conditions to re-use the DG2 > context table. > > For render/compute engines, the part of the context images are nearly > the same, although the layout had a very slight change --- one POSH > register was removed and the placement of some LRI/noops adjusted > slightly to compensate. > > v2: > - Dg2, mtl xcs offsets slightly vary. Use a separate offsets array(Bala) > - Drop unused registers in mtl rcs offsets.(Bala) > - Add missing nop in xcs offsets(Bala) > > Bspec: 46261, 46260, 45585 > Cc: Balasubramani Vivekanandan > Signed-off-by: Matt Roper > Signed-off-by: Radhakrishna Sripada > --- > drivers/gpu/drm/i915/gt/intel_lrc.c | 82 - > 1 file changed, 80 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c > b/drivers/gpu/drm/i915/gt/intel_lrc.c > index 070cec4ff8a4..a2247d39bdb7 100644 > --- a/drivers/gpu/drm/i915/gt/intel_lrc.c > +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c > @@ -264,6 +264,39 @@ static const u8 dg2_xcs_offsets[] = { > END > }; > > +static const u8 mtl_xcs_offsets[] = { > + NOP(1), > + LRI(13, POSTED), > + REG16(0x244), > + REG(0x034), > + REG(0x030), > + REG(0x038), > + REG(0x03c), > + REG(0x168), > + REG(0x140), > + REG(0x110), > + REG(0x1c0), > + REG(0x1c4), > + REG(0x1c8), > + REG(0x180), > + REG16(0x2b4), > + NOP(1), Shouldn't this be NOP(4)? Matt > + > + NOP(1), > + LRI(9, POSTED), > + REG16(0x3a8), > + REG16(0x28c), > + REG16(0x288), > + REG16(0x284), > + REG16(0x280), > + REG16(0x27c), > + REG16(0x278), > + REG16(0x274), > + REG16(0x270), > + > + END > +}; > + > static const u8 gen8_rcs_offsets[] = { > NOP(1), > LRI(14, POSTED), > @@ -606,6 +639,47 @@ static const u8 dg2_rcs_offsets[] = { > END > }; > > +static const u8 mtl_rcs_offsets[] = { > + NOP(1), > + LRI(13, POSTED), > + REG16(0x244), > + REG(0x034), > + REG(0x030), > + REG(0x038), > + REG(0x03c), > + REG(0x168), > + REG(0x140), > + REG(0x110), > + REG(0x1c0), > + REG(0x1c4), > + REG(0x1c8), > + REG(0x180), > + REG16(0x2b4), > + > + NOP(1), > + LRI(9, POSTED), > + REG16(0x3a8), > + REG16(0x28c), > + REG16(0x288), > + REG16(0x284), > + REG16(0x280), > + REG16(0x27c), > + REG16(0x278), > + REG16(0x274), > + REG16(0x270), > + > + NOP(2), > + LRI(2, POSTED), > + REG16(0x5a8), > + REG16(0x5ac), > + > + NOP(6), > + LRI(1, 0), > + REG(0x0c8), > + > + END > +}; > + > #undef END > #undef REG16 > #undef REG > @@ -624,7 +698,9 @@ static const u8 *reg_offsets(const struct intel_engine_cs > *engine) > !intel_engine_has_relative_mmio(engine)); > > if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) { > - if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) > + if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 70)) > + return mtl_rcs_offsets; > + else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) > return dg2_rcs_offsets; > else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) > return xehp_rcs_offsets; > @@ -637,7 +713,9 @@ static const u8 *reg_offsets(const struct intel_engine_cs > *engine) > else > return gen8_rcs_offsets; > } else { > - if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) > + if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 70)) > + return mtl_xcs_offsets; > + else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) > return dg2_xcs_offsets; > else if (GRAPHICS_VER(engine->i915) >= 12) > return gen12_xcs_offsets; > -- > 2.34.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
Re: [Intel-gfx] [PATCH v4 03/11] drm/i915: Parse and set stepping for platforms with GMD
On Thu, Sep 01, 2022 at 11:03:34PM -0700, Radhakrishna Sripada wrote: > From: José Roberto de Souza > > The GMD step field do not properly match the current stepping convention > that we use(STEP_A0, STEP_A1, STEP_B0...). > > One platform could have { arch = 12, rel = 70, step = 1 } and the > actual stepping is STEP_B0 but without the translation of the step > field would mean STEP_A1. > That is why we will need to have gmd_to_intel_step tables for each IP. The (unofficial) claim by the hardware team when GMD_ID was introduced was that they planned to standardize stepping numbering going forward such that they would leave space for up to four minor steppings between each major stepping. I.e., B0 is expected to be 0x4 on all future platforms, C0 is expected to be 0x8, etc. While I'm not super confident that they'll actually stick with that plan forever (e.g., what happens if we wind up having an A5 stepping someday?), it seems like we could at least start with that as our initial assumption and write generic translation code for now; if/when we encounter a platform that deviates, we can add a platform-specific table for it at that time. Matt > > v2: > - Pass the updated ip version structure > > Cc: Balasubramani Vivekanandan > Signed-off-by: José Roberto de Souza > --- > drivers/gpu/drm/i915/intel_step.c | 60 +++ > 1 file changed, 60 insertions(+) > > diff --git a/drivers/gpu/drm/i915/intel_step.c > b/drivers/gpu/drm/i915/intel_step.c > index 42b3133d8387..14ea103d6dab 100644 > --- a/drivers/gpu/drm/i915/intel_step.c > +++ b/drivers/gpu/drm/i915/intel_step.c > @@ -135,6 +135,48 @@ static const struct intel_step_info adlp_n_revids[] = { > [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_D0 }, > }; > > +struct gmd_to_intel_step { > + struct ip_version gmd; > + enum intel_step step; > +}; > + > +static const struct gmd_to_intel_step gmd_graphics_table[] = { > + { .gmd.ver = 12, .gmd.rel = 70, .gmd.step = 0, .step = STEP_A0 }, > + { .gmd.ver = 12, .gmd.rel = 70, .gmd.step = 4, .step = STEP_B0 }, > + { .gmd.ver = 12, .gmd.rel = 71, .gmd.step = 0, .step = STEP_A0 }, > + { .gmd.ver = 12, .gmd.rel = 71, .gmd.step = 4, .step = STEP_B0 }, > + { .gmd.ver = 12, .gmd.rel = 73, .gmd.step = 0, .step = STEP_A0 }, > + { .gmd.ver = 12, .gmd.rel = 73, .gmd.step = 4, .step = STEP_B0 }, > +}; > + > +static const struct gmd_to_intel_step gmd_media_table[] = { > + { .gmd.ver = 13, .gmd.rel = 70, .gmd.step = 0, .step = STEP_A0 }, > + { .gmd.ver = 13, .gmd.rel = 70, .gmd.step = 4, .step = STEP_B0 }, > +}; > + > +static const struct gmd_to_intel_step gmd_display_table[] = { > + { .gmd.ver = 14, .gmd.rel = 0, .gmd.step = 0, .step = STEP_A0 }, > + { .gmd.ver = 14, .gmd.rel = 0, .gmd.step = 4, .step = STEP_B0 }, > +}; > + > +static u8 gmd_to_intel_step(struct drm_i915_private *i915, > + struct ip_version *gmd, > + const struct gmd_to_intel_step *table, > + int len) > +{ > + int i; > + > + for (i = 0; i < len; i++) { > + if (table[i].gmd.ver == gmd->ver && > + table[i].gmd.rel == gmd->rel && > + table[i].gmd.step == gmd->step) > + return table[i].step; > + } > + > + drm_dbg(>drm, "Using future steppings\n"); > + return STEP_FUTURE; > +} > + > static void pvc_step_init(struct drm_i915_private *i915, int pci_revid); > > void intel_step_init(struct drm_i915_private *i915) > @@ -144,6 +186,24 @@ void intel_step_init(struct drm_i915_private *i915) > int revid = INTEL_REVID(i915); > struct intel_step_info step = {}; > > + if (HAS_GMD_ID(i915)) { > + step.graphics_step = gmd_to_intel_step(i915, > + > _INFO(i915)->graphics.version, > +gmd_graphics_table, > + > ARRAY_SIZE(gmd_graphics_table)); > + step.media_step = gmd_to_intel_step(i915, > + > _INFO(i915)->media.version, > + gmd_media_table, > + > ARRAY_SIZE(gmd_media_table)); > + step.display_step = gmd_to_intel_step(i915, > + > _INFO(i915)->display.version, > + gmd_display_table, > + > ARRAY_SIZE(gmd_display_table)); > + RUNTIME_INFO(i915)->step = step; > + > + return; > + } > + > if (IS_PONTEVECCHIO(i915)) { > pvc_step_init(i915, revid); > return; > -- > 2.34.1 > -- Matt Roper Graphics Software Engineer VTT-OSGC Platform Enablement Intel Corporation
Re: [PATCH v4.1] drm/i915: Move display and media IP version to runtime info
On Fri, Sep 02, 2022 at 03:10:54PM -0700, Radhakrishna Sripada wrote: > Future platforms can read the IP version from a register and the > IP version numbers need not be hard coded in device info. Move the > ip version for media and display to runtime info. > > On platforms where hard coding of IP version is required, update > the IP version in __runtime under device_info. > > v2: > - Avoid name collision for ip versions(Jani) > v4.1: > - Fix build error in mock_gem_device.c > > Suggested-by: Jani Nikula > Cc: Matt Roper > Signed-off-by: Radhakrishna Sripada > --- > drivers/gpu/drm/i915/i915_drv.h | 14 +++ > drivers/gpu/drm/i915/i915_pci.c | 38 +-- > drivers/gpu/drm/i915/intel_device_info.c | 28 +- > drivers/gpu/drm/i915/intel_device_info.h | 15 +--- > .../gpu/drm/i915/selftests/mock_gem_device.c | 2 +- > 5 files changed, 54 insertions(+), 43 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index c9cca165bf5d..f85a470397a5 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -469,19 +469,19 @@ static inline struct intel_gt *to_gt(struct > drm_i915_private *i915) > > #define IP_VER(ver, rel) ((ver) << 8 | (rel)) > > -#define GRAPHICS_VER(i915) (RUNTIME_INFO(i915)->graphics.ver) > -#define GRAPHICS_VER_FULL(i915) > IP_VER(RUNTIME_INFO(i915)->graphics.ver, \ > -RUNTIME_INFO(i915)->graphics.rel) > +#define GRAPHICS_VER(i915) > (RUNTIME_INFO(i915)->graphics.version.ver) > +#define GRAPHICS_VER_FULL(i915) > IP_VER(RUNTIME_INFO(i915)->graphics.version.ver, \ > + > RUNTIME_INFO(i915)->graphics.version.rel) > #define IS_GRAPHICS_VER(i915, from, until) \ > (GRAPHICS_VER(i915) >= (from) && GRAPHICS_VER(i915) <= (until)) > > -#define MEDIA_VER(i915) (INTEL_INFO(i915)->media.ver) > -#define MEDIA_VER_FULL(i915) IP_VER(INTEL_INFO(i915)->media.ver, \ > -INTEL_INFO(i915)->media.rel) > +#define MEDIA_VER(i915) > (RUNTIME_INFO(i915)->media.version.ver) > +#define MEDIA_VER_FULL(i915) > IP_VER(RUNTIME_INFO(i915)->media.version.ver, \ > + > RUNTIME_INFO(i915)->media.version.rel) > #define IS_MEDIA_VER(i915, from, until) \ > (MEDIA_VER(i915) >= (from) && MEDIA_VER(i915) <= (until)) > > -#define DISPLAY_VER(i915)(INTEL_INFO(i915)->display.ver) > +#define DISPLAY_VER(i915)(RUNTIME_INFO(i915)->display.version.ver) > #define IS_DISPLAY_VER(i915, from, until) \ > (DISPLAY_VER(i915) >= (from) && DISPLAY_VER(i915) <= (until)) > > diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c > index 26b25d9434d6..f6aaf938c53c 100644 > --- a/drivers/gpu/drm/i915/i915_pci.c > +++ b/drivers/gpu/drm/i915/i915_pci.c > @@ -34,9 +34,9 @@ > > #define PLATFORM(x) .platform = (x) > #define GEN(x) \ > - .__runtime.graphics.ver = (x), \ > - .media.ver = (x), \ > - .display.ver = (x) > + .__runtime.graphics.version.ver = (x), \ > + .__runtime.media.version.ver = (x), \ > + .__runtime.display.version.ver = (x) > > #define I845_PIPE_OFFSETS \ > .display.pipe_offsets = { \ > @@ -740,7 +740,7 @@ static const struct intel_device_info bxt_info = { > static const struct intel_device_info glk_info = { > GEN9_LP_FEATURES, > PLATFORM(INTEL_GEMINILAKE), > - .display.ver = 10, > + .__runtime.display.version.ver = 10, > .display.dbuf.size = 1024 - 4, /* 4 blocks for bypass path allocation */ > GLK_COLORS, > }; > @@ -919,7 +919,7 @@ static const struct intel_device_info rkl_info = { > static const struct intel_device_info dg1_info = { > GEN12_FEATURES, > DGFX_FEATURES, > - .__runtime.graphics.rel = 10, > + .__runtime.graphics.version.rel = 10, > PLATFORM(INTEL_DG1), > .__runtime.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | > BIT(PIPE_D), > .require_force_probe = 1, > @@ -962,7 +962,7 @@ static const struct intel_device_info adl_s_info = { > .display.has_hotplug = 1, > \ > .display.has_ipc = 1, > \ > .display.has_psr = 1, > \ > - .display.ver = 13, > \ > + .__runtime.display.version.ver = 13, > \ > .__runtime.pipe_mask = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | > BIT(PIPE_D), \ > .display.pipe_offsets = { > \ > [TRANSCODER_A] = PIPE_A_OFFSET,
Re: Re: Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table
Dne četrtek, 08. september 2022 ob 18:26:31 CEST je Jernej Škrabec napisal(a): > Dne torek, 06. september 2022 ob 21:26:34 CEST je Clément Péron napisal(a): > > Hi Jernej, > > > > On Tue, 6 Sept 2022 at 21:10, Jernej Škrabec > > wrote: > > > Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron > > napisal(a): > > > > Add an Operating Performance Points table for the GPU to > > > > enable Dynamic Voltage & Frequency Scaling on the H6. > > > > > > > > The voltage range is set with minimal voltage set to the target > > > > and the maximal voltage set to 1.2V. This allow DVFS framework to > > > > work properly on board with fixed regulator. > > > > > > > > Signed-off-by: Clément Péron > > > > --- > > > > > > > > .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 > > > > +++ > > > > 1 file changed, 87 insertions(+) > > > > create mode 100644 > > > > arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > > > > > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > > b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode > > > > 100644 > > > > index ..b48049c4fc85 > > > > --- /dev/null > > > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > > @@ -0,0 +1,87 @@ > > > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) > > > > +// Copyright (C) 2022 Clément Péron > > > > + > > > > +/ { > > > > + gpu_opp_table: opp-table-gpu { > > > > + compatible = "operating-points-v2"; > > > > + > > > > + opp-21600 { > > > > + opp-hz = /bits/ 64 <21600>; > > > > + opp-microvolt = <81 81 120>; > > > > + }; > > > > + > > > > + opp-26400 { > > > > + opp-hz = /bits/ 64 <26400>; > > > > + opp-microvolt = <81 81 120>; > > > > + }; > > > > > > As mentioned in clock patch review, rates below 288 MHz are deemed > > > unstable on GPU PLL by vendor GPU kernel driver. At least in the BSP > > > version that I have. Did you test these points? If not, better to drop > > > them. > > > > I changed the governor to userspace and set the freq to 216MHz / 264MHz > > Run glmark2 and didn't observe any glitch nor issue. > > > > I'm not sure if it's enough to say it's stable but I didn't observe > > any strange behavior. > > Ok then. > > Forgot to ask, where did you get 1.2 V as an upper limit? H6 datasheet lists > max. GPU voltage as 1.08 V. To answer my own question, absolute max. voltage is 1.3 V, so 1.2 V is still somewhat acceptable and in practice, fixed regulator on Tanix TX6 board is around 1.12 V. Boards with PMIC can set lower voltage anyway. All good. Acked-by: Jernej Skrabec Best regards, Jernej > > Regards, > > Clement > > > > > Best regards, > > > Jernej > > > > > > > + > > > > + opp-31200 { > > > > + opp-hz = /bits/ 64 <31200>; > > > > + opp-microvolt = <81 81 120>; > > > > + }; > > > > + > > > > + opp-33600 { > > > > + opp-hz = /bits/ 64 <33600>; > > > > + opp-microvolt = <81 81 120>; > > > > + }; > > > > + > > > > + opp-36000 { > > > > + opp-hz = /bits/ 64 <36000>; > > > > + opp-microvolt = <82 82 120>; > > > > + }; > > > > + > > > > + opp-38400 { > > > > + opp-hz = /bits/ 64 <38400>; > > > > + opp-microvolt = <83 83 120>; > > > > + }; > > > > + > > > > + opp-40800 { > > > > + opp-hz = /bits/ 64 <40800>; > > > > + opp-microvolt = <84 84 120>; > > > > + }; > > > > + > > > > + opp-42000 { > > > > + opp-hz = /bits/ 64 <42000>; > > > > + opp-microvolt = <85 85 120>; > > > > + }; > > > > + > > > > + opp-43200 { > > > > + opp-hz = /bits/ 64 <43200>; > > > > + opp-microvolt = <86 86 120>; > > > > + }; > > > > + > > > > + opp-45600 { > > > > + opp-hz = /bits/ 64 <45600>; > > > > + opp-microvolt = <87 87 120>; > > > > + }; > > > > + > > > > + opp-50400 { > > > > + opp-hz = /bits/ 64 <50400>; > > > > + opp-microvolt = <89 89 120>; > > > > + }; > > > > + > > > > + opp-54000 { > > > > + opp-hz = /bits/ 64 <54000>; > > > > + opp-microvolt = <91 91 120>; > > > > + }; > > > > + > > > > + opp-57600 { > > > > +
Re: [pull] amdgpu, amdkfd, radeon, drm drm-next-6.1
On Thu, Sep 8, 2022 at 12:29 PM Felix Kuehling wrote: > > > On 2022-09-08 11:52, Alex Deucher wrote: > > Hi Dave, Daniel, > > > > New stuff for 6.1. > > > > The following changes since commit 085292c3d78015412b752ee1ca4c7725fd2bf2fc: > > > >Revert "drm/amd/amdgpu: add pipe1 hardware support" (2022-08-16 18:14:31 > > -0400) > > > > are available in the Git repository at: > > > >https://gitlab.freedesktop.org/agd5f/linux.git > > tags/amd-drm-next-6.1-2022-09-08 > > > > for you to fetch changes up to 780244a2fe8a82424c85f4cb15e45d0bbeec8f26: > > > >drm/amd/amdgpu: Add missing CGTS*TCC_DISABLE to 10.3 headers (2022-09-07 > > 22:28:42 -0400) > > > > > > amd-drm-next-6.1-2022-09-08: > > > > amdgpu: > > - Mode2 reset for RDNA2 > > - Lots of new DC documentation > > - Add documentation about different asic families > > - DSC improvements > > - Aldebaran fixes > > - Misc spelling and grammar fixes > > - GFXOFF stats support for vangogh > > - DC frame size fixes > > - NBIO 7.7 updates > > - DCN 3.2 updates > > - DCN 3.1.4 Updates > > - SMU 13.x updates > > - Misc bug fixes > > - Rework DC register offset handling > > - GC 11.x updates > > - PSP 13.x updates > > - SDMA 6.x updates > > - GMC 11.x updates > > - SR-IOV updates > > - PSP fixes for TA unloading > > - DSC passthrough support > > - Misc code cleanups > > > > amdkfd: > > - ISA fixes for some GC 10.3 IPs > > - Misc code cleanups > > > > radeon: > > - Delayed work flush fix > > - Use time_after for some jiffies calculations > > > > drm: > > - DSC passthrough aux support > > > > > > Alex Deucher (1): > >drm/amd/display: fix documentation for > > amdgpu_dm_update_freesync_caps() > > > > Alex Sierra (1): > >drm/amdgpu: ensure no PCIe peer access for CPU XGMI iolinks > > > > Alvin Lee (6): > >drm/amd/display: Free phantom plane and stream properly > >drm/amd/display: Add interface to track PHY state > >drm/amd/display: Uncomment SubVP scaling case > >drm/amd/display: Don't choose SubVP display if ActiveMargin > 0 > >drm/amd/display: Only commit SubVP state after pipe programming > >drm/amd/display: SubVP missing scaling case > > > > André Almeida (4): > >drm/amd: Add detailed GFXOFF stats to debugfs > >drm/amd/pm: Implement GFXOFF's entry count and residency for vangogh > >Documentation/gpu: Document GFXOFF's count and residency > >drm/amdgpu: Document gfx_off members of struct amdgpu_gfx > > > > Anthony Koo (2): > >drm/amd/display: [FW Promotion] Release 0.0.130.0 > >drm/amd/display: [FW Promotion] Release 0.0.132.0 > > > > Aric Cyr (3): > >drm/amd/display: 3.2.199 > >drm/amd/display: 3.2.200 > >drm/amd/display: 3.2.201 > > > > Asher Song (1): > >drm/amd/display: remove a duplicated declaration > > > > Aurabindo Pillai (8): > >drm/amd/display: change to runtime initialization for reg offsets > > for DCN32 > >drm/amd/display: change to runtime initialization for reg offsets > > for DCN321 > >drm/amd/display: program k1/k2 divider for virtual signal for DCN32 > >drm/amd/display: Fix CAB cursor size allocation for DCN32/321 > >drm/amd/display: disable display fresh from MALL on an edge case for > > DCN321 > >drm/amd/display: use actual cursor size instead of max for CAB > > allocation > >drm/amd/display: Revert "program k1/k2 divider for virtual signal > > for DCN32" > >drm/amd/display: Use correct plane for CAB cursor size allocation > > > > Bernard Zhao (4): > >drm/amd: fix potential memory leak > >drm/amd: fix potential memory leak > >drm/amd: remove possible condition with no effect (if == else) > >drm/amd: remove possible condition with no effect (if == else) > > > > Candice Li (1): > >drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. > > > > Charlene Liu (1): > >drm/amd/display: fix wrong register access > > > > Chengming Gui (3): > >drm/amd/amdgpu: avoid soft reset check when gpu recovery disabled > >drm/amd/amdgpu: skip ucode loading if ucode_size == 0 > >drm/amd/amdgpu: add rlc_firmware_header_v2_4 to > > amdgpu_firmware_header > > > > David Belanger (1): > >drm/amdkfd: Added GFX 11.0.3 Support > > > > David Gow (1): > >drm/amd/display: fix overflow on MIN_I64 definition > > > > Derek Lai (1): > >drm/amd/display: do not change pipe split policy for RV2 > > > > Duncan Ma (1): > >drm/amd/display: Fix OTG H timing reset for dcn314 > > > > Ethan Wellenreiter (2): > >drm/amd/display: Re-initialize viewport after pipe merge > >drm/amd/display: Fix check for stream and plane > > > > Evan Quan (5): > >drm/amd/pm: update SMU 13.0.0 driver_if header > >drm/amd/pm: use vbios
Re: [Intel-gfx] [PATCH] drm/i915: Invert if/else ladder for frequency read
On Thu, Sep 08, 2022 at 02:08:55PM +0300, Ville Syrjälä wrote: On Wed, Sep 07, 2022 at 01:30:41PM -0700, Lucas De Marchi wrote: Continue converting the driver to the convention of last version first, extending it to the future platforms. Now, any GRAPHICS_VER >= 11 will be handled by the first branch. With the new ranges it's easier to see what platform a branch started to be taken. Besides the >= 11 change, the branch taken for GRAPHICS_VER == 10 is also different, but currently there is no such platform in i915. Cc: Matt Roper Signed-off-by: Lucas De Marchi --- .../gpu/drm/i915/gt/intel_gt_clock_utils.c| 77 +-- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c index d5d1b04dbcad..93608c9349fd 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c @@ -78,77 +78,74 @@ static u32 read_clock_frequency(struct intel_uncore *uncore) u32 f19_2_mhz = 1920; u32 f24_mhz = 2400; - if (GRAPHICS_VER(uncore->i915) <= 4) { - /* -* PRMs say: -* -* "The value in this register increments once every 16 -* hclks." (through the “Clocking Configuration” -* (“CLKCFG”) MCHBAR register) -*/ - return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000 / 16; - } else if (GRAPHICS_VER(uncore->i915) <= 8) { - /* -* PRMs say: -* -* "The PCU TSC counts 10ns increments; this timestamp -* reflects bits 38:3 of the TSC (i.e. 80ns granularity, -* rolling over every 1.5 hours). -*/ - return f12_5_mhz; - } else if (GRAPHICS_VER(uncore->i915) <= 9) { Is there a good reason each of these branches isn't just its own function? Because they are a single line, hard to justify a separate function, but yes, we could move each of those to a separate one since the others start to span a little more. Lucas De Marchi + if (GRAPHICS_VER(uncore->i915) >= 11) { u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); u32 freq = 0; + /* +* First figure out the reference frequency. There are 2 ways +* we can compute the frequency, either through the +* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE +* tells us which one we should use. +*/ if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { freq = read_reference_ts_freq(uncore); } else { - freq = IS_GEN9_LP(uncore->i915) ? f19_2_mhz : f24_mhz; + u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); + + if (GRAPHICS_VER(uncore->i915) >= 11) + freq = gen11_get_crystal_clock_freq(uncore, c0); + else + freq = gen9_get_crystal_clock_freq(uncore, c0); /* * Now figure out how the command stream's timestamp * register increments from this frequency (it might * increment only every few clock cycle). */ - freq >>= 3 - ((ctc_reg & CTC_SHIFT_PARAMETER_MASK) >> - CTC_SHIFT_PARAMETER_SHIFT); + freq >>= 3 - ((c0 & GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK) >> + GEN10_RPM_CONFIG0_CTC_SHIFT_PARAMETER_SHIFT); } return freq; - } else if (GRAPHICS_VER(uncore->i915) <= 12) { + } else if (GRAPHICS_VER(uncore->i915) >= 9) { u32 ctc_reg = intel_uncore_read(uncore, CTC_MODE); u32 freq = 0; - /* -* First figure out the reference frequency. There are 2 ways -* we can compute the frequency, either through the -* TIMESTAMP_OVERRIDE register or through RPM_CONFIG. CTC_MODE -* tells us which one we should use. -*/ if ((ctc_reg & CTC_SOURCE_PARAMETER_MASK) == CTC_SOURCE_DIVIDE_LOGIC) { freq = read_reference_ts_freq(uncore); } else { - u32 c0 = intel_uncore_read(uncore, RPM_CONFIG0); - - if (GRAPHICS_VER(uncore->i915) >= 11) - freq = gen11_get_crystal_clock_freq(uncore, c0); - else - freq = gen9_get_crystal_clock_freq(uncore, c0); + freq = IS_GEN9_LP(uncore->i915) ?
Re: [pull] amdgpu, amdkfd, radeon, drm drm-next-6.1
On 2022-09-08 11:52, Alex Deucher wrote: Hi Dave, Daniel, New stuff for 6.1. The following changes since commit 085292c3d78015412b752ee1ca4c7725fd2bf2fc: Revert "drm/amd/amdgpu: add pipe1 hardware support" (2022-08-16 18:14:31 -0400) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-next-6.1-2022-09-08 for you to fetch changes up to 780244a2fe8a82424c85f4cb15e45d0bbeec8f26: drm/amd/amdgpu: Add missing CGTS*TCC_DISABLE to 10.3 headers (2022-09-07 22:28:42 -0400) amd-drm-next-6.1-2022-09-08: amdgpu: - Mode2 reset for RDNA2 - Lots of new DC documentation - Add documentation about different asic families - DSC improvements - Aldebaran fixes - Misc spelling and grammar fixes - GFXOFF stats support for vangogh - DC frame size fixes - NBIO 7.7 updates - DCN 3.2 updates - DCN 3.1.4 Updates - SMU 13.x updates - Misc bug fixes - Rework DC register offset handling - GC 11.x updates - PSP 13.x updates - SDMA 6.x updates - GMC 11.x updates - SR-IOV updates - PSP fixes for TA unloading - DSC passthrough support - Misc code cleanups amdkfd: - ISA fixes for some GC 10.3 IPs - Misc code cleanups radeon: - Delayed work flush fix - Use time_after for some jiffies calculations drm: - DSC passthrough aux support Alex Deucher (1): drm/amd/display: fix documentation for amdgpu_dm_update_freesync_caps() Alex Sierra (1): drm/amdgpu: ensure no PCIe peer access for CPU XGMI iolinks Alvin Lee (6): drm/amd/display: Free phantom plane and stream properly drm/amd/display: Add interface to track PHY state drm/amd/display: Uncomment SubVP scaling case drm/amd/display: Don't choose SubVP display if ActiveMargin > 0 drm/amd/display: Only commit SubVP state after pipe programming drm/amd/display: SubVP missing scaling case André Almeida (4): drm/amd: Add detailed GFXOFF stats to debugfs drm/amd/pm: Implement GFXOFF's entry count and residency for vangogh Documentation/gpu: Document GFXOFF's count and residency drm/amdgpu: Document gfx_off members of struct amdgpu_gfx Anthony Koo (2): drm/amd/display: [FW Promotion] Release 0.0.130.0 drm/amd/display: [FW Promotion] Release 0.0.132.0 Aric Cyr (3): drm/amd/display: 3.2.199 drm/amd/display: 3.2.200 drm/amd/display: 3.2.201 Asher Song (1): drm/amd/display: remove a duplicated declaration Aurabindo Pillai (8): drm/amd/display: change to runtime initialization for reg offsets for DCN32 drm/amd/display: change to runtime initialization for reg offsets for DCN321 drm/amd/display: program k1/k2 divider for virtual signal for DCN32 drm/amd/display: Fix CAB cursor size allocation for DCN32/321 drm/amd/display: disable display fresh from MALL on an edge case for DCN321 drm/amd/display: use actual cursor size instead of max for CAB allocation drm/amd/display: Revert "program k1/k2 divider for virtual signal for DCN32" drm/amd/display: Use correct plane for CAB cursor size allocation Bernard Zhao (4): drm/amd: fix potential memory leak drm/amd: fix potential memory leak drm/amd: remove possible condition with no effect (if == else) drm/amd: remove possible condition with no effect (if == else) Candice Li (1): drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. Charlene Liu (1): drm/amd/display: fix wrong register access Chengming Gui (3): drm/amd/amdgpu: avoid soft reset check when gpu recovery disabled drm/amd/amdgpu: skip ucode loading if ucode_size == 0 drm/amd/amdgpu: add rlc_firmware_header_v2_4 to amdgpu_firmware_header David Belanger (1): drm/amdkfd: Added GFX 11.0.3 Support David Gow (1): drm/amd/display: fix overflow on MIN_I64 definition Derek Lai (1): drm/amd/display: do not change pipe split policy for RV2 Duncan Ma (1): drm/amd/display: Fix OTG H timing reset for dcn314 Ethan Wellenreiter (2): drm/amd/display: Re-initialize viewport after pipe merge drm/amd/display: Fix check for stream and plane Evan Quan (5): drm/amd/pm: update SMU 13.0.0 driver_if header drm/amd/pm: use vbios carried pptable for those supported SKUs drm/amd/pm: use vbios carried pptable for all SMU13.0.7 SKUs drm/amd/pm: bump SMU 13.0.0 driver_if header version drm/amd/pm: add missing SetMGpuFanBoostLimitRpm mapping for SMU 13.0.7 Felix Kuehling (1): drm/amdkfd: Allocate doorbells only when needed This patch broke CRIU. Rajneesh posted a fix for it. I'd recommend including the fix, though we're still debating the root cause and may refine it later: [Patch v2] drm/amdkfd: Fix CRIU restore op due to doorbell offset Regards, Felix Frank Min (3):
Re: [PATCH v4 5/5] arm64: dts: allwinner: beelink-gs1: Enable GPU OPP
Dne torek, 06. september 2022 ob 17:30:34 CEST je Clément Péron napisal(a): > Enable GPU OPP table for Beelink GS1. > > Signed-off-by: Clément Péron Acked-by: Jernej Skrabec Best regards, Jernej > --- > arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts > b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts index > 6249e9e02928..9ec49ac2f6fd 100644 > --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts > @@ -5,6 +5,7 @@ > > #include "sun50i-h6.dtsi" > #include "sun50i-h6-cpu-opp.dtsi" > +#include "sun50i-h6-gpu-opp.dtsi" > > #include > > -- > 2.34.1
Re: Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table
Dne torek, 06. september 2022 ob 21:26:34 CEST je Clément Péron napisal(a): > Hi Jernej, > > On Tue, 6 Sept 2022 at 21:10, Jernej Škrabec wrote: > > Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron napisal(a): > > > Add an Operating Performance Points table for the GPU to > > > enable Dynamic Voltage & Frequency Scaling on the H6. > > > > > > The voltage range is set with minimal voltage set to the target > > > and the maximal voltage set to 1.2V. This allow DVFS framework to > > > work properly on board with fixed regulator. > > > > > > Signed-off-by: Clément Péron > > > --- > > > > > > .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++ > > > 1 file changed, 87 insertions(+) > > > create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > > > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode > > > 100644 > > > index ..b48049c4fc85 > > > --- /dev/null > > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi > > > @@ -0,0 +1,87 @@ > > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) > > > +// Copyright (C) 2022 Clément Péron > > > + > > > +/ { > > > + gpu_opp_table: opp-table-gpu { > > > + compatible = "operating-points-v2"; > > > + > > > + opp-21600 { > > > + opp-hz = /bits/ 64 <21600>; > > > + opp-microvolt = <81 81 120>; > > > + }; > > > + > > > + opp-26400 { > > > + opp-hz = /bits/ 64 <26400>; > > > + opp-microvolt = <81 81 120>; > > > + }; > > > > As mentioned in clock patch review, rates below 288 MHz are deemed > > unstable on GPU PLL by vendor GPU kernel driver. At least in the BSP > > version that I have. Did you test these points? If not, better to drop > > them. > > I changed the governor to userspace and set the freq to 216MHz / 264MHz > Run glmark2 and didn't observe any glitch nor issue. > > I'm not sure if it's enough to say it's stable but I didn't observe > any strange behavior. Ok then. Forgot to ask, where did you get 1.2 V as an upper limit? H6 datasheet lists max. GPU voltage as 1.08 V. Best regards, Jernej > > Regards, > Clement > > > Best regards, > > Jernej > > > > > + > > > + opp-31200 { > > > + opp-hz = /bits/ 64 <31200>; > > > + opp-microvolt = <81 81 120>; > > > + }; > > > + > > > + opp-33600 { > > > + opp-hz = /bits/ 64 <33600>; > > > + opp-microvolt = <81 81 120>; > > > + }; > > > + > > > + opp-36000 { > > > + opp-hz = /bits/ 64 <36000>; > > > + opp-microvolt = <82 82 120>; > > > + }; > > > + > > > + opp-38400 { > > > + opp-hz = /bits/ 64 <38400>; > > > + opp-microvolt = <83 83 120>; > > > + }; > > > + > > > + opp-40800 { > > > + opp-hz = /bits/ 64 <40800>; > > > + opp-microvolt = <84 84 120>; > > > + }; > > > + > > > + opp-42000 { > > > + opp-hz = /bits/ 64 <42000>; > > > + opp-microvolt = <85 85 120>; > > > + }; > > > + > > > + opp-43200 { > > > + opp-hz = /bits/ 64 <43200>; > > > + opp-microvolt = <86 86 120>; > > > + }; > > > + > > > + opp-45600 { > > > + opp-hz = /bits/ 64 <45600>; > > > + opp-microvolt = <87 87 120>; > > > + }; > > > + > > > + opp-50400 { > > > + opp-hz = /bits/ 64 <50400>; > > > + opp-microvolt = <89 89 120>; > > > + }; > > > + > > > + opp-54000 { > > > + opp-hz = /bits/ 64 <54000>; > > > + opp-microvolt = <91 91 120>; > > > + }; > > > + > > > + opp-57600 { > > > + opp-hz = /bits/ 64 <57600>; > > > + opp-microvolt = <93 93 120>; > > > + }; > > > + > > > + opp-62400 { > > > + opp-hz = /bits/ 64 <62400>; > > > + opp-microvolt = <95 95 120>; > > > + }; > > > + > > > + opp-75600 { > > > + opp-hz = /bits/ 64 <75600>; > > > + opp-microvolt = <104 104 120>; > > > + }; > > > + }; > > > +}; > > > + > > > + { > > > +
Re: [PATCH v3 12/14] drm/i915/xelpmp: Expose media as another GT
On 07-09-2022 05:19, Matt Roper wrote: > Xe_LPM+ platforms have "standalone media." I.e., the media unit is > designed as an additional GT with its own engine list, GuC, forcewake, > etc. Let's allow platforms to include media GTs in their device info. > > v2: > - Simplify GSI register handling and split it out to a separate patch >for ease of review. (Daniele) > > Cc: Aravind Iddamsetty > Cc: Daniele Ceraolo Spurio > Signed-off-by: Matt Roper > Reviewed-by: Aravind Iddamsetty > --- > drivers/gpu/drm/i915/Makefile| 1 + > drivers/gpu/drm/i915/gt/intel_gt.c | 6 > drivers/gpu/drm/i915/gt/intel_gt_regs.h | 8 + > drivers/gpu/drm/i915/gt/intel_gt_types.h | 1 + > drivers/gpu/drm/i915/gt/intel_sa_media.c | 39 > drivers/gpu/drm/i915/gt/intel_sa_media.h | 15 + > drivers/gpu/drm/i915/i915_pci.c | 14 + > 7 files changed, 84 insertions(+) > create mode 100644 drivers/gpu/drm/i915/gt/intel_sa_media.c > create mode 100644 drivers/gpu/drm/i915/gt/intel_sa_media.h > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 522ef9b4aff3..e83e4cd46968 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -123,6 +123,7 @@ gt-y += \ > gt/intel_ring.o \ > gt/intel_ring_submission.o \ > gt/intel_rps.o \ > + gt/intel_sa_media.o \ > gt/intel_sseu.o \ > gt/intel_sseu_debugfs.o \ > gt/intel_timeline.o \ > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c > b/drivers/gpu/drm/i915/gt/intel_gt.c > index aa0e40987798..9b9c0ea73b7f 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c > @@ -31,6 +31,7 @@ > #include "intel_rc6.h" > #include "intel_renderstate.h" > #include "intel_rps.h" > +#include "intel_sa_media.h" > #include "intel_gt_sysfs.h" > #include "intel_uncore.h" > #include "shmem_utils.h" > @@ -864,6 +865,11 @@ int intel_gt_probe_all(struct drm_i915_private *i915) > ret = intel_gt_tile_setup(gt, phys_addr + > gtdef->mapping_base); > break; > > + case GT_MEDIA: > + ret = intel_sa_mediagt_setup(gt, phys_addr + > gtdef->mapping_base, > + gtdef->gsi_offset); > + break; > + > case GT_PRIMARY: > /* Primary GT should not appear in extra GT list */ > default: > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > index d414785003cc..fb2c56777480 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h > +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h > @@ -1578,4 +1578,12 @@ > > #define GEN12_SFC_DONE(n)_MMIO(0x1cc000 + (n) * 0x1000) > > +/* > + * Standalone Media's non-engine GT registers are located at their regular GT > + * offsets plus 0x38. This extra offset is stored inside the > intel_uncore > + * structure so that the existing code can be used for both GTs without > + * modification. > + */ > +#define MTL_MEDIA_GSI_BASE 0x38 > + > #endif /* __INTEL_GT_REGS__ */ > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h > b/drivers/gpu/drm/i915/gt/intel_gt_types.h > index 82dc28643572..726695936a79 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt_types.h > +++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h > @@ -84,6 +84,7 @@ struct gt_defaults { > enum intel_gt_type { > GT_PRIMARY, > GT_TILE, > + GT_MEDIA, > }; > > struct intel_gt { > diff --git a/drivers/gpu/drm/i915/gt/intel_sa_media.c > b/drivers/gpu/drm/i915/gt/intel_sa_media.c > new file mode 100644 > index ..8c5c519457cc > --- /dev/null > +++ b/drivers/gpu/drm/i915/gt/intel_sa_media.c > @@ -0,0 +1,39 @@ > +// SPDX-License-Identifier: MIT > +/* > + * Copyright © 2021 Intel Corporation > + */ > + > +#include > + > +#include "i915_drv.h" > +#include "gt/intel_gt.h" > +#include "gt/intel_sa_media.h" > + > +int intel_sa_mediagt_setup(struct intel_gt *gt, phys_addr_t phys_addr, > +u32 gsi_offset) > +{ > + struct drm_i915_private *i915 = gt->i915; > + struct intel_uncore *uncore; > + > + uncore = drmm_kzalloc(>drm, sizeof(*uncore), GFP_KERNEL); > + if (!uncore) > + return -ENOMEM; > + > + uncore->gsi_offset = gsi_offset; > + > + intel_gt_common_init_early(gt); > + intel_uncore_init_early(uncore, gt); > + > + /* > + * Standalone media shares the general MMIO space with the primary > + * GT. We'll re-use the primary GT's mapping. > + */ > + uncore->regs = i915->uncore.regs; > + if (drm_WARN_ON(>drm, uncore->regs == NULL)) > + return -EIO; > + > + gt->uncore = uncore; > + gt->phys_addr = phys_addr; > + > + return 0; > +} > diff --git a/drivers/gpu/drm/i915/gt/intel_sa_media.h >
Re: [PATCH v4 2/5] arm64: dts: allwinner: h6: Add cooling map for GPU
Dne torek, 06. september 2022 ob 17:30:31 CEST je Clément Péron napisal(a): > Add a simple cooling map for the GPU. > > This cooling map come from the vendor kernel 4.9 with a > 2°C hysteresis added. > > Signed-off-by: Clément Péron Acked-by: Jernej Skrabec Best regards, Jernej
Re: [PATCH v3 05/14] drm/i915: Prepare more multi-GT initialization
On 07-09-2022 05:19, Matt Roper wrote: > We're going to introduce an additional intel_gt for MTL's media unit > soon. Let's provide a bit more multi-GT initialization framework in > preparation for that. The initialization will pull the list of GTs for > a platform from the device info structure. Although necessary for the > immediate MTL media enabling, this same framework will also be used > farther down the road when we enable remote tiles on xehpsdv and pvc. > > v2: > - Re-add missing test for !HAS_EXTRA_GT_LIST in intel_gt_probe_all(). > > v3: > - Move intel_gt_definition struct to intel_gt_types.h. (Jani) > - Drop gtdef->setup(). For now we'll just use a switch() based on GT >type since we don't have too many different handlers for the >forseeable future. (Jani) > > Cc: Aravind Iddamsetty > Cc: Jani Nikula > Signed-off-by: Matt Roper > Reviewed-by: Radhakrishna Sripada > --- > drivers/gpu/drm/i915/gt/intel_engine_cs.c | 2 +- > drivers/gpu/drm/i915/gt/intel_gt.c| 59 ++- > drivers/gpu/drm/i915/gt/intel_gt.h| 1 - > drivers/gpu/drm/i915/gt/intel_gt_types.h | 15 + > drivers/gpu/drm/i915/i915_drv.h | 2 + > drivers/gpu/drm/i915/intel_device_info.h | 3 + > .../gpu/drm/i915/selftests/mock_gem_device.c | 1 + > 7 files changed, 80 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > index 275ad72940c1..41acc285e8bf 100644 > --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c > +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c > @@ -736,7 +736,7 @@ static intel_engine_mask_t init_engine_mask(struct > intel_gt *gt) > u16 vdbox_mask; > u16 vebox_mask; > > - info->engine_mask = RUNTIME_INFO(i915)->platform_engine_mask; > + GEM_BUG_ON(!info->engine_mask); > > if (GRAPHICS_VER(i915) < 11) > return info->engine_mask; > diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c > b/drivers/gpu/drm/i915/gt/intel_gt.c > index 663a4798fb2e..85c75375391c 100644 > --- a/drivers/gpu/drm/i915/gt/intel_gt.c > +++ b/drivers/gpu/drm/i915/gt/intel_gt.c > @@ -807,8 +807,10 @@ int intel_gt_probe_all(struct drm_i915_private *i915) > { > struct pci_dev *pdev = to_pci_dev(i915->drm.dev); > struct intel_gt *gt = >gt0; > + const struct intel_gt_definition *gtdef; > phys_addr_t phys_addr; > unsigned int mmio_bar; > + unsigned int i; > int ret; > > mmio_bar = GRAPHICS_VER(i915) == 2 ? GEN2_GTTMMADR_BAR : GTTMMADR_BAR; > @@ -819,14 +821,69 @@ int intel_gt_probe_all(struct drm_i915_private *i915) >* and it has been already initialized early during probe >* in i915_driver_probe() >*/ > + gt->i915 = i915; > + gt->name = "Primary GT"; > + gt->info.engine_mask = RUNTIME_INFO(i915)->platform_engine_mask; > + > + drm_dbg(>drm, "Setting up %s\n", gt->name); > ret = intel_gt_tile_setup(gt, phys_addr); > if (ret) > return ret; > > i915->gt[0] = gt; > > - /* TODO: add more tiles */ > + if (!HAS_EXTRA_GT_LIST(i915)) > + return 0; > + > + for (i = 1, gtdef = _INFO(i915)->extra_gt_list[i - 1]; > + gtdef->name != NULL; > + i++, gtdef = _INFO(i915)->extra_gt_list[i - 1]) { > + gt = drmm_kzalloc(>drm, sizeof(*gt), GFP_KERNEL); > + if (!gt) { > + ret = -ENOMEM; > + goto err; > + } > + > + gt->i915 = i915; > + gt->name = gtdef->name; > + gt->type = gtdef->type; > + gt->info.engine_mask = gtdef->engine_mask; > + gt->info.id = i; > + > + drm_dbg(>drm, "Setting up %s\n", gt->name); > + if (GEM_WARN_ON(range_overflows_t(resource_size_t, > + gtdef->mapping_base, > + SZ_16M, > + pci_resource_len(pdev, > mmio_bar { > + ret = -ENODEV; > + goto err; > + } > + > + switch (gtdef->type) { > + case GT_TILE: > + ret = intel_gt_tile_setup(gt, phys_addr + > gtdef->mapping_base); > + break; > + > + case GT_PRIMARY: > + /* Primary GT should not appear in extra GT list */ > + default: > + MISSING_CASE(gtdef->type); > + ret = -ENODEV; > + } > + > + if (ret) > + goto err; > + > + i915->gt[i] = gt; > + } > + > return 0; > + > +err: > + i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, > ret); > + intel_gt_release_all(i915); > + > + return ret; > } > > int intel_gt_tiles_init(struct
Re: [PATCH v3] drm/msm/dp: cleared DP_DOWNSPREAD_CTRL register before start link training
On Thu, 8 Sept 2022 at 18:38, Kuogee Hsieh wrote: > > DOWNSPREAD_CTRL (0x107) shall be cleared to 0 upon power-on reset or an > upstream device disconnect. This patch will enforce this rule by always > cleared DOWNSPREAD_CTRL register to 0 before start link training. At rare > case that DP MSA timing parameters may be mis-interpreted by the sink > which causes audio sampling rate be calculated wrongly and cause audio > did not work at sink if DOWNSPREAD_CTRL register is not cleared to 0. > This patch also make sure bring sink out of D3 power-down mode into D0 > (normal operation mode) successfully by retrying 3 times. Split into three separate patches please. -- With best wishes Dmitry
Re: [PATCH] drm/i915/gt: Fix perf limit reasons bit positions
On Thu, 08 Sep 2022 08:58:21 -0700, Ashutosh Dixit wrote: > > Perf limit reasons bit positions were off by one. > > Fixes: fa68bff7cf27 ("drm/i915/gt: Add sysfs throttle frequency interfaces") > Cc: sta...@vger.kernel.org # v5.18+ > Signed-off-by: Ashutosh Dixit > Acked-by: Andi Shyti > Reviewed-by: Sujaritha Sundaresan I copied the A-b and R-b on this patch from: https://patchwork.freedesktop.org/patch/501919/?series=108091=2 And have also copied stable just in case. Thanks. > --- > drivers/gpu/drm/i915/i915_reg.h | 16 > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index c413eec3373f..24009786f88b 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -1794,14 +1794,14 @@ > > #define GT0_PERF_LIMIT_REASONS _MMIO(0x1381a8) > #define GT0_PERF_LIMIT_REASONS_MASK0xde3 > -#define PROCHOT_MASK REG_BIT(1) > -#define THERMAL_LIMIT_MASK REG_BIT(2) > -#define RATL_MASK REG_BIT(6) > -#define VR_THERMALERT_MASK REG_BIT(7) > -#define VR_TDC_MASKREG_BIT(8) > -#define POWER_LIMIT_4_MASK REG_BIT(9) > -#define POWER_LIMIT_1_MASK REG_BIT(11) > -#define POWER_LIMIT_2_MASK REG_BIT(12) > +#define PROCHOT_MASK REG_BIT(0) > +#define THERMAL_LIMIT_MASK REG_BIT(1) > +#define RATL_MASK REG_BIT(5) > +#define VR_THERMALERT_MASK REG_BIT(6) > +#define VR_TDC_MASKREG_BIT(7) > +#define POWER_LIMIT_4_MASK REG_BIT(8) > +#define POWER_LIMIT_1_MASK REG_BIT(10) > +#define POWER_LIMIT_2_MASK REG_BIT(11) > > #define CHV_CLK_CTL1 _MMIO(0x101100) > #define VLV_CLK_CTL2 _MMIO(0x101104) > -- > 2.34.1 >
[PATCH] drm/i915/gt: Fix perf limit reasons bit positions
Perf limit reasons bit positions were off by one. Fixes: fa68bff7cf27 ("drm/i915/gt: Add sysfs throttle frequency interfaces") Cc: sta...@vger.kernel.org # v5.18+ Signed-off-by: Ashutosh Dixit Acked-by: Andi Shyti Reviewed-by: Sujaritha Sundaresan --- drivers/gpu/drm/i915/i915_reg.h | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c413eec3373f..24009786f88b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1794,14 +1794,14 @@ #define GT0_PERF_LIMIT_REASONS _MMIO(0x1381a8) #define GT0_PERF_LIMIT_REASONS_MASK 0xde3 -#define PROCHOT_MASK REG_BIT(1) -#define THERMAL_LIMIT_MASK REG_BIT(2) -#define RATL_MASKREG_BIT(6) -#define VR_THERMALERT_MASK REG_BIT(7) -#define VR_TDC_MASK REG_BIT(8) -#define POWER_LIMIT_4_MASK REG_BIT(9) -#define POWER_LIMIT_1_MASK REG_BIT(11) -#define POWER_LIMIT_2_MASK REG_BIT(12) +#define PROCHOT_MASK REG_BIT(0) +#define THERMAL_LIMIT_MASK REG_BIT(1) +#define RATL_MASKREG_BIT(5) +#define VR_THERMALERT_MASK REG_BIT(6) +#define VR_TDC_MASK REG_BIT(7) +#define POWER_LIMIT_4_MASK REG_BIT(8) +#define POWER_LIMIT_1_MASK REG_BIT(10) +#define POWER_LIMIT_2_MASK REG_BIT(11) #define CHV_CLK_CTL1 _MMIO(0x101100) #define VLV_CLK_CTL2 _MMIO(0x101104) -- 2.34.1
[pull] amdgpu, amdkfd, radeon, drm drm-next-6.1
Hi Dave, Daniel, New stuff for 6.1. The following changes since commit 085292c3d78015412b752ee1ca4c7725fd2bf2fc: Revert "drm/amd/amdgpu: add pipe1 hardware support" (2022-08-16 18:14:31 -0400) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-next-6.1-2022-09-08 for you to fetch changes up to 780244a2fe8a82424c85f4cb15e45d0bbeec8f26: drm/amd/amdgpu: Add missing CGTS*TCC_DISABLE to 10.3 headers (2022-09-07 22:28:42 -0400) amd-drm-next-6.1-2022-09-08: amdgpu: - Mode2 reset for RDNA2 - Lots of new DC documentation - Add documentation about different asic families - DSC improvements - Aldebaran fixes - Misc spelling and grammar fixes - GFXOFF stats support for vangogh - DC frame size fixes - NBIO 7.7 updates - DCN 3.2 updates - DCN 3.1.4 Updates - SMU 13.x updates - Misc bug fixes - Rework DC register offset handling - GC 11.x updates - PSP 13.x updates - SDMA 6.x updates - GMC 11.x updates - SR-IOV updates - PSP fixes for TA unloading - DSC passthrough support - Misc code cleanups amdkfd: - ISA fixes for some GC 10.3 IPs - Misc code cleanups radeon: - Delayed work flush fix - Use time_after for some jiffies calculations drm: - DSC passthrough aux support Alex Deucher (1): drm/amd/display: fix documentation for amdgpu_dm_update_freesync_caps() Alex Sierra (1): drm/amdgpu: ensure no PCIe peer access for CPU XGMI iolinks Alvin Lee (6): drm/amd/display: Free phantom plane and stream properly drm/amd/display: Add interface to track PHY state drm/amd/display: Uncomment SubVP scaling case drm/amd/display: Don't choose SubVP display if ActiveMargin > 0 drm/amd/display: Only commit SubVP state after pipe programming drm/amd/display: SubVP missing scaling case André Almeida (4): drm/amd: Add detailed GFXOFF stats to debugfs drm/amd/pm: Implement GFXOFF's entry count and residency for vangogh Documentation/gpu: Document GFXOFF's count and residency drm/amdgpu: Document gfx_off members of struct amdgpu_gfx Anthony Koo (2): drm/amd/display: [FW Promotion] Release 0.0.130.0 drm/amd/display: [FW Promotion] Release 0.0.132.0 Aric Cyr (3): drm/amd/display: 3.2.199 drm/amd/display: 3.2.200 drm/amd/display: 3.2.201 Asher Song (1): drm/amd/display: remove a duplicated declaration Aurabindo Pillai (8): drm/amd/display: change to runtime initialization for reg offsets for DCN32 drm/amd/display: change to runtime initialization for reg offsets for DCN321 drm/amd/display: program k1/k2 divider for virtual signal for DCN32 drm/amd/display: Fix CAB cursor size allocation for DCN32/321 drm/amd/display: disable display fresh from MALL on an edge case for DCN321 drm/amd/display: use actual cursor size instead of max for CAB allocation drm/amd/display: Revert "program k1/k2 divider for virtual signal for DCN32" drm/amd/display: Use correct plane for CAB cursor size allocation Bernard Zhao (4): drm/amd: fix potential memory leak drm/amd: fix potential memory leak drm/amd: remove possible condition with no effect (if == else) drm/amd: remove possible condition with no effect (if == else) Candice Li (1): drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. Charlene Liu (1): drm/amd/display: fix wrong register access Chengming Gui (3): drm/amd/amdgpu: avoid soft reset check when gpu recovery disabled drm/amd/amdgpu: skip ucode loading if ucode_size == 0 drm/amd/amdgpu: add rlc_firmware_header_v2_4 to amdgpu_firmware_header David Belanger (1): drm/amdkfd: Added GFX 11.0.3 Support David Gow (1): drm/amd/display: fix overflow on MIN_I64 definition Derek Lai (1): drm/amd/display: do not change pipe split policy for RV2 Duncan Ma (1): drm/amd/display: Fix OTG H timing reset for dcn314 Ethan Wellenreiter (2): drm/amd/display: Re-initialize viewport after pipe merge drm/amd/display: Fix check for stream and plane Evan Quan (5): drm/amd/pm: update SMU 13.0.0 driver_if header drm/amd/pm: use vbios carried pptable for those supported SKUs drm/amd/pm: use vbios carried pptable for all SMU13.0.7 SKUs drm/amd/pm: bump SMU 13.0.0 driver_if header version drm/amd/pm: add missing SetMGpuFanBoostLimitRpm mapping for SMU 13.0.7 Felix Kuehling (1): drm/amdkfd: Allocate doorbells only when needed Frank Min (3): drm/amdgpu: support psp v13_0_10 ip block drm/amdgpu: add new ip block for PSP 13.0 drm/amdgpu: add gc v11_0_3 ip headers Gabe Teeger (2): drm/amd/display: Cursor lag with PSR1 eDP drm/amd/display: Cleanup PSR flag George Shen (1): drm/amd/display: Fix DCN32 DPSTREAMCLK_CNTL programming Graham Sider (1):