nvidia-driver-565/nvidia-graphics-drivers-565/debian/patches/0010-FROM-AOSC-TTM-fbdev-emulation-for-Linux-6.13.patch
ferreo 1666dcb0ea
Some checks failed
PikaOS Package Build Only (amd64-v3) / build (push) Failing after 36s
Add 6.13 patches
2025-01-20 13:45:45 +00:00

157 lines
5.5 KiB
Diff

From 88b8ae7642ef21e685d51148e8f57c3dfa1323ac Mon Sep 17 00:00:00 2001
From: Bingwu Zhang <xtex@aosc.io>
Date: Sat, 7 Dec 2024 23:56:43 +0800
Subject: [PATCH 10/10] FROM AOSC: TTM fbdev emulation for Linux 6.13+
Link: https://github.com/torvalds/linux/commit/1000634477d8d178179b1ad45d92e925fabe3deb
Link: https://github.com/NVIDIA/open-gpu-kernel-modules/issues/749
Signed-off-by: xtex <xtexchooser@duck.com>
Signed-off-by: Eric Naim <dnaim@cachyos.org>
---
kernel-open/nvidia-drm/nvidia-drm-drv.c | 72 +++++++++++++++++++
kernel-open/nvidia-drm/nvidia-drm-linux.c | 4 ++
.../nvidia-drm/nvidia-drm-os-interface.h | 5 ++
3 files changed, 81 insertions(+)
diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c
index 2e4f6404..ab85152f 100644
--- a/kernel-open/nvidia-drm/nvidia-drm-drv.c
+++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c
@@ -1951,7 +1951,60 @@ void nv_drm_update_drm_driver_features(void)
#endif /* NV_DRM_ATOMIC_MODESET_AVAILABLE */
}
+#if !defined(NV_DRM_FBDEV_TTM_AVAILABLE) && \
+ !defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
+// AOSC OS: Workaround for Linux 6.13+
+static const struct drm_fb_helper_funcs nv_drm_fbdev_helper_funcs = {
+ .fb_probe = drm_fbdev_ttm_driver_fbdev_probe,
+};
+
+static void nv_drm_fbdev_client_unregister(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+ if (fb_helper->info) {
+ drm_fb_helper_unregister_info(fb_helper);
+ } else {
+ drm_client_release(&fb_helper->client);
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+ }
+}
+static int nv_drm_fbdev_client_restore(struct drm_client_dev *client)
+{
+ drm_fb_helper_lastclose(client->dev);
+ return 0;
+}
+static int nv_drm_fbdev_client_hotplug(struct drm_client_dev *client)
+{
+ struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+ struct drm_device *dev = client->dev;
+ int ret;
+ if (dev->fb_helper)
+ return drm_fb_helper_hotplug_event(dev->fb_helper);
+ ret = drm_fb_helper_init(dev, fb_helper);
+ if (ret)
+ goto err_drm_err;
+ if (!drm_drv_uses_atomic_modeset(dev))
+ drm_helper_disable_unused_functions(dev);
+ ret = drm_fb_helper_initial_config(fb_helper);
+ if (ret)
+ goto err_drm_fb_helper_fini;
+ return 0;
+err_drm_fb_helper_fini:
+ drm_fb_helper_fini(fb_helper);
+err_drm_err:
+ drm_err(dev, "AOSC OS: NV-DRM: fbdev: Failed to setup emulation (ret=%d)\n", ret);
+ return ret;
+}
+
+static const struct drm_client_funcs nv_drm_fbdev_client_funcs = {
+ .owner = THIS_MODULE,
+ .unregister = nv_drm_fbdev_client_unregister,
+ .restore = nv_drm_fbdev_client_restore,
+ .hotplug = nv_drm_fbdev_client_hotplug,
+};
+#endif
/*
* Helper function for allocate/register DRM device for given NVIDIA GPU ID.
@@ -1961,6 +2014,7 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
struct nv_drm_device *nv_dev = NULL;
struct drm_device *dev = NULL;
struct device *device = gpu_info->os_device_ptr;
+ struct drm_fb_helper *fb_helper = NULL;
bool bus_is_pci;
DRM_DEBUG(
@@ -2039,6 +2093,20 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
drm_fbdev_ttm_setup(dev, 32);
#elif defined(NV_DRM_FBDEV_GENERIC_AVAILABLE)
drm_fbdev_generic_setup(dev, 32);
+ #else
+ // AOSC OS: Workaround for Linux 6.13+
+ int drm_client_ret;
+ fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
+ if (!fb_helper)
+ return;
+ drm_fb_helper_prepare(dev, fb_helper, 32, &nv_drm_fbdev_helper_funcs);
+ drm_client_ret = drm_client_init(dev, &fb_helper->client, "fbdev",
+ &nv_drm_fbdev_client_funcs);
+ if (drm_client_ret) {
+ drm_err(dev, "AOSC OS: NV-DRM: Failed to register DRM client: %d\n", drm_client_ret);
+ goto failed_drm_client_init;
+ }
+ drm_client_register(&fb_helper->client);
#endif
}
#endif /* defined(NV_DRM_FBDEV_AVAILABLE) */
@@ -2050,6 +2118,10 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info)
return; /* Success */
+failed_drm_client_init:
+ drm_fb_helper_unprepare(fb_helper);
+ kfree(fb_helper);
+
failed_drm_register:
nv_drm_dev_free(dev);
diff --git a/kernel-open/nvidia-drm/nvidia-drm-linux.c b/kernel-open/nvidia-drm/nvidia-drm-linux.c
index 83d40983..ac4fe967 100644
--- a/kernel-open/nvidia-drm/nvidia-drm-linux.c
+++ b/kernel-open/nvidia-drm/nvidia-drm-linux.c
@@ -39,8 +39,12 @@ MODULE_PARM_DESC(
fbdev,
"Create a framebuffer device (1 = enable (default), 0 = disable) (EXPERIMENTAL)");
module_param_named(fbdev, nv_drm_fbdev_module_param, bool, 0400);
+#else
+#error "nvidia-drm fbdev should always be available."
#endif
+#else
+#error "nvidia-drm is not available"
#endif /* NV_DRM_AVAILABLE */
/*************************************************************************
diff --git a/kernel-open/nvidia-drm/nvidia-drm-os-interface.h b/kernel-open/nvidia-drm/nvidia-drm-os-interface.h
index 71ca5f22..8195af32 100644
--- a/kernel-open/nvidia-drm/nvidia-drm-os-interface.h
+++ b/kernel-open/nvidia-drm/nvidia-drm-os-interface.h
@@ -78,6 +78,11 @@ typedef struct nv_timer nv_drm_timer;
#define NV_DRM_FBDEV_TTM_AVAILABLE
#endif
+// AOSC OS: Always enable DRM fbdev
+// FIXME: Add config test for drm helper functions.
+// The implementation uses drm_client_register, which is added in v5.2-rc1.
+#define NV_DRM_FBDEV_AVAILABLE
+
struct page;
/* Set to true when the atomic modeset feature is enabled. */
--
2.47.1