From 42d819a34a5778d82e176383b54d49e59b1d82d8 Mon Sep 17 00:00:00 2001 From: Johannes Lundberg Date: Mon, 22 Jul 2019 07:52:30 -0700 Subject: [PATCH 01/13] Update get_dma_buf() for changes to fhold() (cherry picked from commit 0b2c3cfb0836cf1b3222ca7afae4b063b61c423d) --- linuxkpi/gplv2/include/linux/dma-buf.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linuxkpi/gplv2/include/linux/dma-buf.h b/linuxkpi/gplv2/include/linux/dma-buf.h index 28a7fde78d..8f3430e7c8 100644 --- a/linuxkpi/gplv2/include/linux/dma-buf.h +++ b/linuxkpi/gplv2/include/linux/dma-buf.h @@ -132,7 +132,9 @@ struct dma_buf_attachment { static inline void get_dma_buf(struct dma_buf *dmabuf) { - fhold(dmabuf->file); + while(!fhold(dmabuf->file)) { + pause("fhold", hz); + } } From 0c0bff3967ed6c9ffcf57561491add11a7ab4bc0 Mon Sep 17 00:00:00 2001 From: Johannes Lundberg Date: Mon, 22 Jul 2019 08:21:41 -0700 Subject: [PATCH 02/13] Check for fhold macro in get_dma_buf to make it backwards compatible (cherry picked from commit 9dc2a2b5ab5693d401d2f1694f944c36f6a3b41c) --- linuxkpi/gplv2/include/linux/dma-buf.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linuxkpi/gplv2/include/linux/dma-buf.h b/linuxkpi/gplv2/include/linux/dma-buf.h index 8f3430e7c8..361a6592a6 100644 --- a/linuxkpi/gplv2/include/linux/dma-buf.h +++ b/linuxkpi/gplv2/include/linux/dma-buf.h @@ -132,9 +132,17 @@ struct dma_buf_attachment { static inline void get_dma_buf(struct dma_buf *dmabuf) { + /* + * As of r350199 fhold changed from macro to a function returning + * true/false at success/failure to avoid overflow. + */ +#ifdef fhold + fhold(dmabuf->file); +#else while(!fhold(dmabuf->file)) { pause("fhold", hz); } +#endif } From fa3bd0c010d424d868e7185e11eae26d69e2399f Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sat, 24 Aug 2019 11:18:54 -0700 Subject: [PATCH 03/13] Fix build on FreeBSD-current r351457. (cherry picked from commit 3484b98c3b26242c076f6897cf81658a2bbd0551) --- linuxkpi/gplv2/src/linux_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linuxkpi/gplv2/src/linux_compat.c b/linuxkpi/gplv2/src/linux_compat.c index f5cdca4680..177b5158b8 100644 --- a/linuxkpi/gplv2/src/linux_compat.c +++ b/linuxkpi/gplv2/src/linux_compat.c @@ -1,6 +1,7 @@ #include #include +#include #include #include From ee40fcfd7e6415b5a6cbaaec449de57daffca68f Mon Sep 17 00:00:00 2001 From: Johannes Lundberg Date: Fri, 13 Dec 2019 22:32:42 -0700 Subject: [PATCH 04/13] Replace deprecated timeout code with callout. (cherry picked from commit b17900b06950fdc8a73361543fc8dc75fe58fe33) --- drm/drm_os_freebsd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drm/drm_os_freebsd.c b/drm/drm_os_freebsd.c index c5c46898ec..6cdb799c9e 100644 --- a/drm/drm_os_freebsd.c +++ b/drm/drm_os_freebsd.c @@ -32,7 +32,7 @@ int drm_always_interruptible; SYSCTL_INT(_dev_drm, OID_AUTO, always_interruptible, CTLFLAG_RWTUN, &drm_always_interruptible, 0, "always allow a thread to be interrupted in driver wait"); static atomic_t reset_debug_log_armed = ATOMIC_INIT(0); -static struct callout_handle reset_debug_log_handle; +static struct callout reset_debug_log_handle; static void clear_debug_func(void *arg __unused) @@ -44,7 +44,7 @@ void cancel_reset_debug_log(void) { if (atomic_read(&reset_debug_log_armed)) - untimeout(clear_debug_func, NULL, reset_debug_log_handle); + callout_stop(&reset_debug_log_handle); } static void @@ -54,8 +54,7 @@ reset_debug_log(void) return; if (atomic_add_unless(&reset_debug_log_armed, 1, 1)) { - reset_debug_log_handle = timeout(clear_debug_func, NULL, - 10*hz); + callout_reset(&reset_debug_log_handle, 10*hz, clear_debug_func, NULL); } } @@ -312,6 +311,7 @@ drm_modevent(module_t mod, int type, void *data) switch (type) { case MOD_LOAD: TUNABLE_INT_FETCH("drm.debug", &drm_debug); + callout_init(&reset_debug_log_handle, 1); break; } return (0); From 49168f6ce6cbe19eaba987e9f0d91e35dc13df12 Mon Sep 17 00:00:00 2001 From: Johannes Lundberg Date: Tue, 17 Dec 2019 13:02:44 -0700 Subject: [PATCH 05/13] Replace deprecated timeout code with callout - improve callout code. (cherry picked from commit 9ea021d3a9e7bdd3fa0a906c80403d823ce6a767) --- drm/drm_os_freebsd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drm/drm_os_freebsd.c b/drm/drm_os_freebsd.c index 6cdb799c9e..63c21cec47 100644 --- a/drm/drm_os_freebsd.c +++ b/drm/drm_os_freebsd.c @@ -31,7 +31,6 @@ SYSCTL_INT(_dev_drm, OID_AUTO, error_panic, CTLFLAG_RWTUN, &drm_panic_on_error, int drm_always_interruptible; SYSCTL_INT(_dev_drm, OID_AUTO, always_interruptible, CTLFLAG_RWTUN, &drm_always_interruptible, 0, "always allow a thread to be interrupted in driver wait"); -static atomic_t reset_debug_log_armed = ATOMIC_INIT(0); static struct callout reset_debug_log_handle; static void @@ -43,8 +42,7 @@ clear_debug_func(void *arg __unused) void cancel_reset_debug_log(void) { - if (atomic_read(&reset_debug_log_armed)) - callout_stop(&reset_debug_log_handle); + callout_stop(&reset_debug_log_handle); } static void @@ -53,9 +51,8 @@ reset_debug_log(void) if (drm_debug_persist) return; - if (atomic_add_unless(&reset_debug_log_armed, 1, 1)) { + if (!callout_pending(&reset_debug_log_handle)) callout_reset(&reset_debug_log_handle, 10*hz, clear_debug_func, NULL); - } } int @@ -313,6 +310,9 @@ drm_modevent(module_t mod, int type, void *data) TUNABLE_INT_FETCH("drm.debug", &drm_debug); callout_init(&reset_debug_log_handle, 1); break; + case MOD_UNLOAD: + callout_drain(&reset_debug_log_handle); + break; } return (0); } From 5c1dda779be431de4c29b6b860e40631aa4f583e Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Tue, 4 Apr 2017 17:52:21 +0100 Subject: [PATCH 06/13] drm: Pass CRTC ID in userspace vblank events With the atomic API, it is possible that a single commit affects multiple crtcs. If the user requests an event with that commit, one event will be sent for each CRTC, but it is not possible to distinguish which crtc an event is for in user space. To solve this, the reserved field in struct drm_vblank_event is repurposed to include the crtc_id which the event is for. The DRM_CAP_CRTC_IN_VBLANK_EVENT is added to allow userspace to query if the crtc field will be set properly. [daniels: Rebased, using Maarten's forward-port.] Signed-off-by: Ander Conselvan de Oliveira Signed-off-by: Daniel Stone Cc: Maarten Lankhorst Link: http://patchwork.freedesktop.org/patch/msgid/20170404165221.28240-2-daniels@collabora.com (cherry picked from commit 9f1da74e03ef9448e936a602cb07e86c7738420c) --- drm/drm_ioctl.c | 3 +++ drm/drm_irq.c | 2 ++ include/uapi/drm/drm.h | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drm/drm_ioctl.c b/drm/drm_ioctl.c index 0ce667d5c9..59af7ab052 100644 --- a/drm/drm_ioctl.c +++ b/drm/drm_ioctl.c @@ -277,6 +277,9 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ case DRM_CAP_ADDFB2_MODIFIERS: req->value = dev->mode_config.allow_fb_modifiers; break; + case DRM_CAP_CRTC_IN_VBLANK_EVENT: + req->value = 1; + break; default: return -EINVAL; } diff --git a/drm/drm_irq.c b/drm/drm_irq.c index a5d76d5cc5..7ac7235ec1 100644 --- a/drm/drm_irq.c +++ b/drm/drm_irq.c @@ -1052,6 +1052,7 @@ void drm_crtc_arm_vblank_event(struct drm_crtc *crtc, e->pipe = pipe; e->event.sequence = drm_vblank_count(dev, pipe); + e->event.crtc_id = crtc->base.id; list_add_tail(&e->base.link, &dev->vblank_event_list); } EXPORT_SYMBOL(drm_crtc_arm_vblank_event); @@ -1082,6 +1083,7 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc, now = get_drm_timestamp(); } e->pipe = pipe; + e->event.crtc_id = crtc->base.id; send_vblank_event(dev, e, seq, &now); } EXPORT_SYMBOL(drm_crtc_send_vblank_event); diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index 08ba627de4..f6f2be2b8c 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -655,6 +655,7 @@ struct drm_gem_open { #define DRM_CAP_CURSOR_HEIGHT 0x9 #define DRM_CAP_ADDFB2_MODIFIERS 0x10 #define DRM_CAP_PAGE_FLIP_TARGET 0x11 +#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 /** DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { @@ -859,7 +860,7 @@ struct drm_event_vblank { __u32 tv_sec; __u32 tv_usec; __u32 sequence; - __u32 reserved; + __u32 crtc_id; /* 0 on older kernels that do not support this */ }; /* typedef area */ From 207e1f0a91af38569c23c561216b28bae91aa3ce Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 30 Jan 2018 11:27:04 +0100 Subject: [PATCH 07/13] drm/atomic: Remove WARN_ON for invalid plane configuration. Userspace can set a FB_ID on a plane without setting CRTC_ID, which will fail with -EINVAL, but the kernel shouldn't warn about that. Same for !FB_ID and CRTC_ID being set. Signed-off-by: Maarten Lankhorst Acked-by: Daniel Vetter Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180130102704.28016-1-maarten.lankhorst@linux.intel.com Reviewed-by: Harry Wentland (cherry picked from commit github.com/torvalds/linux/commit/fa5aaeecf524ecbcae9755ee3d34b7b8ba412583) --- drm/drm_atomic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drm/drm_atomic.c b/drm/drm_atomic.c index b78688ab1b..9c82daac07 100644 --- a/drm/drm_atomic.c +++ b/drm/drm_atomic.c @@ -819,10 +819,10 @@ static int drm_atomic_plane_check(struct drm_plane *plane, int ret; /* either *both* CRTC and FB must be set, or neither */ - if (WARN_ON(state->crtc && !state->fb)) { + if (state->crtc && !state->fb) { DRM_DEBUG_ATOMIC("CRTC set but no FB\n"); return -EINVAL; - } else if (WARN_ON(state->fb && !state->crtc)) { + } else if (state->fb && !state->crtc) { DRM_DEBUG_ATOMIC("FB set but no CRTC\n"); return -EINVAL; } From 90123a59239a31b73886d1ebd31daef09cd529a2 Mon Sep 17 00:00:00 2001 From: myfreeweb Date: Thu, 3 Jan 2019 16:36:29 +0300 Subject: [PATCH 08/13] Add devctl (devd) notification for connector hotplug (#119) Wayland compositors need a notification to know when to rescan display connectors. (cherry picked from commit fe4385951eec0e6e73be747032f221413233c813) --- drm/drm_sysfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drm/drm_sysfs.c b/drm/drm_sysfs.c index 17caa46b57..9a813211cb 100644 --- a/drm/drm_sysfs.c +++ b/drm/drm_sysfs.c @@ -338,6 +338,15 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) DRM_DEBUG("generating hotplug event\n"); kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); +#else + struct sbuf *sb = sbuf_new_auto(); + + DRM_DEBUG("generating hotplug event\n"); + + sbuf_printf(sb, "cdev=dri/%s", dev_name(dev->primary->kdev)); + sbuf_finish(sb); + devctl_notify("DRM", "CONNECTOR", "HOTPLUG", sbuf_data(sb)); + sbuf_delete(sb); #endif } EXPORT_SYMBOL(drm_sysfs_hotplug_event); From e3207a4a9925289011687eaedfe2300e02e331af Mon Sep 17 00:00:00 2001 From: myfreeweb Date: Wed, 7 Aug 2019 20:00:56 +0300 Subject: [PATCH 09/13] Enable Message Signaled Interrupts (MSI) (#163) This fixes ridiculous interrupt rate on aarch64, was enabled in the legacy in-tree drm port, and is a good idea in general. (cherry picked from commit f4e740399dfa333f23623292caeff49daa94cc99) --- amd/amdgpu/amdgpu_irq.c | 6 ++---- i915/i915_drv.c | 6 ++++-- radeon/radeon_irq_kms.c | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/amd/amdgpu/amdgpu_irq.c b/amd/amdgpu/amdgpu_irq.c index f484a92fe5..d32d519958 100644 --- a/amd/amdgpu/amdgpu_irq.c +++ b/amd/amdgpu/amdgpu_irq.c @@ -37,8 +37,6 @@ #include #define AMDGPU_WAIT_IDLE_TIMEOUT 200 -#define pci_enable_msi linux_pci_enable_msi -#define pci_disable_msi linux_pci_disable_msi /* * Handle hotplug events outside the interrupt handler proper. @@ -226,7 +224,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev) adev->irq.msi_enabled = false; if (amdgpu_msi_ok(adev)) { -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_enable_msi) int ret = pci_enable_msi(adev->pdev); if (!ret) { adev->irq.msi_enabled = true; @@ -266,7 +264,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev) if (adev->irq.installed) { drm_irq_uninstall(adev->ddev); adev->irq.installed = false; -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_disable_msi) if (adev->irq.msi_enabled) pci_disable_msi(adev->pdev); #endif diff --git a/i915/i915_drv.c b/i915/i915_drv.c index 19a6a5b86d..28d35bb509 100644 --- a/i915/i915_drv.c +++ b/i915/i915_drv.c @@ -1128,7 +1128,7 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) i915_gem_load_init_fences(dev_priv); -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_enable_msi) /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there * according to the published specs. It doesn't appear to function @@ -1160,9 +1160,11 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv) */ static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) { -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_disable_msi) struct pci_dev *pdev = dev_priv->drm.pdev; +#endif +#if defined(__linux__) || defined(pci_disable_msi) if (pdev->msi_enabled) pci_disable_msi(pdev); #endif diff --git a/radeon/radeon_irq_kms.c b/radeon/radeon_irq_kms.c index 065f7c5e31..a029dcf9d7 100644 --- a/radeon/radeon_irq_kms.c +++ b/radeon/radeon_irq_kms.c @@ -298,7 +298,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) rdev->msi_enabled = 0; if (radeon_msi_ok(rdev)) { -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_enable_msi) int ret = pci_enable_msi(rdev->pdev); if (!ret) { rdev->msi_enabled = 1; @@ -336,7 +336,7 @@ void radeon_irq_kms_fini(struct radeon_device *rdev) if (rdev->irq.installed) { drm_irq_uninstall(rdev->ddev); rdev->irq.installed = false; -#ifndef __FreeBSD__ +#if defined(__linux__) || defined(pci_disable_msi) if (rdev->msi_enabled) pci_disable_msi(rdev->pdev); #endif From d7596d35e1ff5a86ee3e388e33142bd6fe800b2f Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 28 Mar 2018 15:14:49 +0300 Subject: [PATCH 10/13] i2c_sendbyte: pulse SCL to request ACK/NACK bit from slave (#51) (cherry picked from commit 6a3d6e69ab5bf47756fde2a7c00e3f7d6295c10f) --- linuxkpi/gplv2/src/linux_i2c.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linuxkpi/gplv2/src/linux_i2c.c b/linuxkpi/gplv2/src/linux_i2c.c index 01d4597aaa..5a606707ac 100644 --- a/linuxkpi/gplv2/src/linux_i2c.c +++ b/linuxkpi/gplv2/src/linux_i2c.c @@ -302,6 +302,9 @@ i2c_sendbyte(struct i2c_algo_bit_data *adap, unsigned char data) } } + sdahi(adap); + if (sclhi(adap) < 0) + return (-ETIMEDOUT); ack = (getsda(adap) == 0); scllo(adap); return ack; From ef4a1eb9d9f4ae00ca87770bc04885d4dcb0a4ef Mon Sep 17 00:00:00 2001 From: "Alfonso S. Siciliano" Date: Tue, 27 Aug 2019 18:55:08 +0200 Subject: [PATCH 11/13] DRM_SYSCTL_PRINT fails without the lock (#170) fix 'mutex_unlock() system panic' when DRM_SYSCTL_PRINT fails and has not the lock, reproduced by: % sysctl -B 1 hw.dri.0.vblank % sysctl -B 1 hw.dri % sysctl -B 1 -a (cherry picked from commit 324a27a7347336af267c6e68eaf8f98458808f37) --- drm/drm_sysctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drm/drm_sysctl.c b/drm/drm_sysctl.c index 60f6a0f919..8dac92308f 100644 --- a/drm/drm_sysctl.c +++ b/drm/drm_sysctl.c @@ -419,8 +419,8 @@ static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS int retcode; int i; - DRM_SYSCTL_PRINT("\ncrtc ref count last enabled inmodeset\n"); mutex_lock(&dev->struct_mutex); + DRM_SYSCTL_PRINT("\ncrtc ref count last enabled inmodeset\n"); if (dev->vblank == NULL) goto done; for (i = 0 ; i < dev->num_crtcs ; i++) { From 8f47fe2b8563ad95ba77a232db1dbbf9a7682989 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 17 Oct 2019 16:49:52 -0400 Subject: [PATCH 12/13] Catch up with busy state changes in FreeBSD head. cdev_pager_free_page() now expects an xbusy page. (cherry picked from commit 727f5a133dd6af81db3c9602bc1aa0cd91059605) --- linuxkpi/gplv2/src/linux_page.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linuxkpi/gplv2/src/linux_page.c b/linuxkpi/gplv2/src/linux_page.c index ceaa8a9505..87e882dbf4 100644 --- a/linuxkpi/gplv2/src/linux_page.c +++ b/linuxkpi/gplv2/src/linux_page.c @@ -249,8 +249,13 @@ unmap_mapping_range(void *obj, loff_t const holebegin, loff_t const holelen, int page = vm_page_lookup(devobj, i); if (page == NULL) continue; +#if __FreeBSD_version >= 1300052 + if (!vm_page_busy_acquire(page, VM_ALLOC_WAITFAIL)) + goto retry; +#else if (vm_page_sleep_if_busy(page, "linuxkpi")) goto retry; +#endif cdev_pager_free_page(devobj, page); } VM_OBJECT_WUNLOCK(devobj); From 29d4843ad9e1c552dcc090478907ff17402d639c Mon Sep 17 00:00:00 2001 From: Niclas Zeising Date: Thu, 20 Feb 2020 20:07:09 +0100 Subject: [PATCH 13/13] Update after header change in current Update to chase a header change in current. Signed-off-by: Niclas Zeising Signed-off-by: Hans Petter Selasky (cherry picked from commit ea881213f5ef47948bf81b2a94e00a3885b1b035) --- linuxkpi/dummy/include/linux/shmem_fs.h | 0 linuxkpi/gplv2/include/linux/shmem_fs.h | 3 +++ 2 files changed, 3 insertions(+) delete mode 100644 linuxkpi/dummy/include/linux/shmem_fs.h create mode 100644 linuxkpi/gplv2/include/linux/shmem_fs.h diff --git a/linuxkpi/dummy/include/linux/shmem_fs.h b/linuxkpi/dummy/include/linux/shmem_fs.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/linuxkpi/gplv2/include/linux/shmem_fs.h b/linuxkpi/gplv2/include/linux/shmem_fs.h new file mode 100644 index 0000000000..64a9aa2110 --- /dev/null +++ b/linuxkpi/gplv2/include/linux/shmem_fs.h @@ -0,0 +1,3 @@ +#if __FreeBSD_version >= 1300081 +#include_next +#endif