projects/linux·blob master · refs

219 lines · 5.8 KiB

1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2021 Intel Corporation
4 */
5
6#include "xe_module.h"
7
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/workqueue.h>
11
12#include <drm/drm_module.h>
13
14#include "xe_defaults.h"
15#include "xe_device_types.h"
16#include "xe_drv.h"
17#include "xe_configfs.h"
18#include "xe_hw_fence.h"
19#include "xe_pci.h"
20#include "xe_pm.h"
21#include "xe_observation.h"
22#include "xe_sched_job.h"
23
24struct xe_modparam xe_modparam = {
25 .probe_display = XE_DEFAULT_PROBE_DISPLAY,
26 .guc_log_level = XE_DEFAULT_GUC_LOG_LEVEL,
27 .force_probe = XE_DEFAULT_FORCE_PROBE,
28#ifdef CONFIG_PCI_IOV
29 .max_vfs = XE_DEFAULT_MAX_VFS,
30#endif
31 .wedged_mode = XE_DEFAULT_WEDGED_MODE,
32 .svm_notifier_size = XE_DEFAULT_SVM_NOTIFIER_SIZE,
33 /* the rest are 0 by default */
34};
35
36module_param_named(svm_notifier_size, xe_modparam.svm_notifier_size, uint, 0600);
37MODULE_PARM_DESC(svm_notifier_size, "Set the svm notifier size in MiB, must be power of 2 "
38 "[default=" __stringify(XE_DEFAULT_SVM_NOTIFIER_SIZE) "]");
39
40#if IS_ENABLED(CONFIG_DRM_XE_DISPLAY)
41module_param_named(probe_display, xe_modparam.probe_display, bool, 0444);
42MODULE_PARM_DESC(probe_display, "Probe display HW, otherwise it's left untouched "
43 "[default=" __stringify(XE_DEFAULT_PROBE_DISPLAY) "])");
44#endif
45
46module_param_named(vram_bar_size, xe_modparam.force_vram_bar_size, int, 0600);
47MODULE_PARM_DESC(vram_bar_size, "Set the vram bar size in MiB (<0=disable-resize, 0=max-needed-size, >0=force-size "
48 "[default=" __stringify(XE_DEFAULT_VRAM_BAR_SIZE) "])");
49
50module_param_named(guc_log_level, xe_modparam.guc_log_level, int, 0600);
51MODULE_PARM_DESC(guc_log_level, "GuC firmware logging level (0=disable, 1=normal, 2..5=verbose-levels "
52 "[default=" __stringify(XE_DEFAULT_GUC_LOG_LEVEL) "])");
53
54module_param_named_unsafe(guc_firmware_path, xe_modparam.guc_firmware_path, charp, 0400);
55MODULE_PARM_DESC(guc_firmware_path,
56 "GuC firmware path to use instead of the default one");
57
58module_param_named_unsafe(huc_firmware_path, xe_modparam.huc_firmware_path, charp, 0400);
59MODULE_PARM_DESC(huc_firmware_path,
60 "HuC firmware path to use instead of the default one - empty string disables");
61
62module_param_named_unsafe(gsc_firmware_path, xe_modparam.gsc_firmware_path, charp, 0400);
63MODULE_PARM_DESC(gsc_firmware_path,
64 "GSC firmware path to use instead of the default one - empty string disables");
65
66module_param_named_unsafe(force_probe, xe_modparam.force_probe, charp, 0400);
67MODULE_PARM_DESC(force_probe,
68 "Force probe options for specified devices. See CONFIG_DRM_XE_FORCE_PROBE for details "
69 "[default=" XE_DEFAULT_FORCE_PROBE "])");
70
71#ifdef CONFIG_PCI_IOV
72module_param_named(max_vfs, xe_modparam.max_vfs, uint, 0400);
73MODULE_PARM_DESC(max_vfs,
74 "Limit number of Virtual Functions (VFs) that could be managed. "
75 "(0=no VFs; N=allow up to N VFs "
76 "[default=" XE_DEFAULT_MAX_VFS_STR "])");
77#endif
78
79module_param_named_unsafe(wedged_mode, xe_modparam.wedged_mode, uint, 0600);
80MODULE_PARM_DESC(wedged_mode,
81 "Module's default policy for the wedged mode (0=never, 1=upon-critical-error, 2=upon-any-hang-no-reset "
82 "[default=" XE_DEFAULT_WEDGED_MODE_STR "])");
83
84static int xe_check_nomodeset(void)
85{
86 if (drm_firmware_drivers_only())
87 return -ENODEV;
88
89 return 0;
90}
91
92static struct workqueue_struct *xe_destroy_wq;
93
94static int __init xe_destroy_wq_module_init(void)
95{
96 xe_destroy_wq = alloc_workqueue("xe-guc-destroy-wq", WQ_UNBOUND, 0);
97 if (!xe_destroy_wq)
98 return -ENOMEM;
99 return 0;
100}
101
102static void xe_destroy_wq_module_exit(void)
103{
104 if (xe_destroy_wq)
105 destroy_workqueue(xe_destroy_wq);
106 xe_destroy_wq = NULL;
107}
108
109/**
110 * xe_destroy_wq_queue() - Queue work on the destroy workqueue
111 * @work: work item to queue
112 *
113 * The destroy workqueue has module lifetime and is used for GuC exec queue
114 * teardown that can outlive a single xe_device. SVM pagemap destroy uses the
115 * per-device xe->destroy_wq instead.
116 *
117 * Return: %true if @work was queued, %false if it was already pending.
118 */
119bool xe_destroy_wq_queue(struct work_struct *work)
120{
121 return queue_work(xe_destroy_wq, work);
122}
123
124/**
125 * xe_destroy_wq_flush() - Flush the destroy workqueue
126 *
127 * Drains all pending destroy work. Called from PCI remove to ensure
128 * teardown ordering before the device is destroyed.
129 */
130void xe_destroy_wq_flush(void)
131{
132 if (xe_destroy_wq)
133 flush_workqueue(xe_destroy_wq);
134}
135
136struct init_funcs {
137 int (*init)(void);
138 void (*exit)(void);
139};
140
141static const struct init_funcs init_funcs[] = {
142 {
143 .init = xe_check_nomodeset,
144 },
145 {
146 .init = xe_configfs_init,
147 .exit = xe_configfs_exit,
148 },
149 {
150 .init = xe_hw_fence_module_init,
151 .exit = xe_hw_fence_module_exit,
152 },
153 {
154 .init = xe_sched_job_module_init,
155 .exit = xe_sched_job_module_exit,
156 },
157 {
158 .init = xe_destroy_wq_module_init,
159 .exit = xe_destroy_wq_module_exit,
160 },
161 {
162 .init = xe_register_pci_driver,
163 .exit = xe_unregister_pci_driver,
164 },
165 {
166 .init = xe_observation_sysctl_register,
167 .exit = xe_observation_sysctl_unregister,
168 },
169 {
170 .init = xe_pm_module_init,
171 },
172};
173
174static int __init xe_call_init_func(const struct init_funcs *func)
175{
176 if (func->init)
177 return func->init();
178 return 0;
179}
180
181static void xe_call_exit_func(const struct init_funcs *func)
182{
183 if (func->exit)
184 func->exit();
185}
186
187static int __init xe_init(void)
188{
189 int err, i;
190
191 for (i = 0; i < ARRAY_SIZE(init_funcs); i++) {
192 err = xe_call_init_func(init_funcs + i);
193 if (err) {
194 pr_info("%s: module_init aborted at %ps %pe\n",
195 DRIVER_NAME, init_funcs[i].init, ERR_PTR(err));
196 while (i--)
197 xe_call_exit_func(init_funcs + i);
198 return err;
199 }
200 }
201
202 return 0;
203}
204
205static void __exit xe_exit(void)
206{
207 int i;
208
209 for (i = ARRAY_SIZE(init_funcs) - 1; i >= 0; i--)
210 xe_call_exit_func(init_funcs + i);
211}
212
213module_init(xe_init);
214module_exit(xe_exit);
215
216MODULE_AUTHOR("Intel Corporation");
217
218MODULE_DESCRIPTION(DRIVER_DESC);
219MODULE_LICENSE("GPL and additional rights");