1*ee3f67d3Sriastradh /* $NetBSD: drm_module.c,v 1.32 2023/09/05 20:15:10 riastradh Exp $ */
26cb10275Sriastradh
36cb10275Sriastradh /*-
46cb10275Sriastradh * Copyright (c) 2013 The NetBSD Foundation, Inc.
56cb10275Sriastradh * All rights reserved.
66cb10275Sriastradh *
76cb10275Sriastradh * This code is derived from software contributed to The NetBSD Foundation
86cb10275Sriastradh * by Taylor R. Campbell.
96cb10275Sriastradh *
106cb10275Sriastradh * Redistribution and use in source and binary forms, with or without
116cb10275Sriastradh * modification, are permitted provided that the following conditions
126cb10275Sriastradh * are met:
136cb10275Sriastradh * 1. Redistributions of source code must retain the above copyright
146cb10275Sriastradh * notice, this list of conditions and the following disclaimer.
156cb10275Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
166cb10275Sriastradh * notice, this list of conditions and the following disclaimer in the
176cb10275Sriastradh * documentation and/or other materials provided with the distribution.
186cb10275Sriastradh *
196cb10275Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
206cb10275Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
216cb10275Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
226cb10275Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
236cb10275Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
246cb10275Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
256cb10275Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
266cb10275Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
276cb10275Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
286cb10275Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
296cb10275Sriastradh * POSSIBILITY OF SUCH DAMAGE.
306cb10275Sriastradh */
316cb10275Sriastradh
326cb10275Sriastradh #include <sys/cdefs.h>
33*ee3f67d3Sriastradh __KERNEL_RCSID(0, "$NetBSD: drm_module.c,v 1.32 2023/09/05 20:15:10 riastradh Exp $");
346cb10275Sriastradh
356cb10275Sriastradh #include <sys/types.h>
3626e846f0Sriastradh #include <sys/condvar.h>
376585c4c4Sriastradh #include <sys/conf.h>
386cb10275Sriastradh #include <sys/device.h>
396cb10275Sriastradh #include <sys/module.h>
4026e846f0Sriastradh #include <sys/mutex.h>
4177b5597aSriastradh #include <sys/once.h>
42c5f5d171Sriastradh #include <sys/reboot.h>
436cb10275Sriastradh #include <sys/systm.h>
446cb10275Sriastradh
4577b5597aSriastradh #include <linux/mutex.h>
4677b5597aSriastradh
478fe3f4a7Sriastradh #include <drm/drm_agpsupport.h>
48429b039cSriastradh #include <drm/drm_bridge.h>
49f21b21b0Sriastradh #include <drm/drm_device.h>
50c48dc052Sriastradh #include <drm/drm_encoder_slave.h>
51453c4aa9Sjmcneill #include <drm/drm_panel.h>
528fe3f4a7Sriastradh #include <drm/drm_print.h>
53f21b21b0Sriastradh #include <drm/drm_sysctl.h>
546cb10275Sriastradh
55dafabe62Sriastradh #include "../dist/drm/drm_crtc_internal.h"
563f26b5c5Sriastradh #include "../dist/drm/drm_internal.h"
573f26b5c5Sriastradh
586cb10275Sriastradh /*
59d46aeca2Sriastradh * XXX This is stupid.
60d46aeca2Sriastradh *
61d46aeca2Sriastradh * 1. Builtin modules are broken: they don't get initialized before
62d46aeca2Sriastradh * autoconf matches devices, but we need the initialization to be
63d46aeca2Sriastradh * run in order to match and attach drmkms drivers.
64d46aeca2Sriastradh *
65d46aeca2Sriastradh * 2. The following dependencies are _not_ correct:
66d46aeca2Sriastradh * - drmkms can't depend on agp because not all drmkms drivers run
67d46aeca2Sriastradh * on platforms guaranteed to have pci, let alone agp
68d46aeca2Sriastradh * - drmkms_pci can't depend on agp because not all _pci_ has agp
69d46aeca2Sriastradh * (e.g., tegra)
70d46aeca2Sriastradh * - radeon (e.g.) can't depend on agp because not all radeon
71d46aeca2Sriastradh * devices are on platforms guaranteed to have agp
72d46aeca2Sriastradh *
73d46aeca2Sriastradh * 3. We need to register the agp hooks before we try to attach a
74d46aeca2Sriastradh * device.
75d46aeca2Sriastradh *
76d46aeca2Sriastradh * 4. The only mechanism we have to force this is the
77d46aeca2Sriastradh * mumblefrotz_guarantee_initialized kludge.
78d46aeca2Sriastradh *
79d46aeca2Sriastradh * 5. We don't know if we even _can_ call
80d46aeca2Sriastradh * drmkms_agp_guarantee_initialized unless we know NAGP.
81d46aeca2Sriastradh *
82d46aeca2Sriastradh * 6. We don't know NAGP unless we include "agp.h".
83d46aeca2Sriastradh *
84d46aeca2Sriastradh * 7. We can't include "agp.h" if the platform has agp.
85d46aeca2Sriastradh *
86d46aeca2Sriastradh * 8. The way we determine whether we have agp is NAGP.
87d46aeca2Sriastradh *
88d46aeca2Sriastradh * 9. @!*#&^@&*@!&^#@
89d46aeca2Sriastradh */
90d46aeca2Sriastradh #if defined(__powerpc__) || defined(__i386__) || defined(__x86_64__)
91d46aeca2Sriastradh #include "agp.h"
92*ee3f67d3Sriastradh #include "drmkms_pci.h"
93d46aeca2Sriastradh #endif
94d46aeca2Sriastradh
95d46aeca2Sriastradh /*
966cb10275Sriastradh * XXX I2C stuff should be moved to a separate drmkms_i2c module.
976cb10275Sriastradh */
981c26109fSriastradh MODULE(MODULE_CLASS_DRIVER, drmkms, "drmkms_linux,sysmon_power");
996cb10275Sriastradh
10077b5597aSriastradh struct mutex drm_global_mutex;
10177b5597aSriastradh
1028ba1623fSchristos struct drm_sysctl_def drm_def = DRM_SYSCTL_INIT();
1038ba1623fSchristos
10477b5597aSriastradh static int
drm_init(void)10577b5597aSriastradh drm_init(void)
10677b5597aSriastradh {
10777b5597aSriastradh extern int linux_guarantee_initialized(void);
10877b5597aSriastradh int error;
10977b5597aSriastradh
11077b5597aSriastradh error = linux_guarantee_initialized();
11177b5597aSriastradh if (error)
11277b5597aSriastradh return error;
11377b5597aSriastradh
11477fcb07cSriastradh extern bool drm_core_init_complete;
11577fcb07cSriastradh drm_core_init_complete = true;
11677fcb07cSriastradh
117d46aeca2Sriastradh drm_agp_hooks_init();
118*ee3f67d3Sriastradh #if NDRMKMS_PCI > 0 && NAGP > 0
119d46aeca2Sriastradh extern int drmkms_agp_guarantee_initialized(void);
120d46aeca2Sriastradh error = drmkms_agp_guarantee_initialized();
121d46aeca2Sriastradh if (error) {
122d46aeca2Sriastradh drm_agp_hooks_fini();
123d46aeca2Sriastradh return error;
124d46aeca2Sriastradh }
125d46aeca2Sriastradh #endif
126d46aeca2Sriastradh
12777b5597aSriastradh if (ISSET(boothowto, AB_DEBUG))
1285fb65ca2Sriastradh __drm_debug = DRM_UT_DRIVER;
12977b5597aSriastradh
13077b5597aSriastradh spin_lock_init(&drm_minor_lock);
13177b5597aSriastradh idr_init(&drm_minors_idr);
1329e5fbd4fSriastradh _init_srcu_struct(&drm_unplug_srcu, "drmunplg");
13377b5597aSriastradh linux_mutex_init(&drm_global_mutex);
1340f849473Sriastradh linux_mutex_init(&drm_kernel_fb_helper_lock);
13577b5597aSriastradh drm_connector_ida_init();
136453c4aa9Sjmcneill drm_panel_init_lock();
137453c4aa9Sjmcneill drm_bridge_init_lock();
1388ba1623fSchristos drm_sysctl_init(&drm_def);
139c48dc052Sriastradh drm_i2c_encoders_init();
14077b5597aSriastradh
14177b5597aSriastradh return 0;
14277b5597aSriastradh }
14377b5597aSriastradh
14477b5597aSriastradh int
drm_guarantee_initialized(void)14577b5597aSriastradh drm_guarantee_initialized(void)
14677b5597aSriastradh {
147185e03d3Sriastradh #ifdef _MODULE
14877b5597aSriastradh return 0;
149185e03d3Sriastradh #else
15077b5597aSriastradh static ONCE_DECL(drm_init_once);
15177b5597aSriastradh
15277b5597aSriastradh return RUN_ONCE(&drm_init_once, &drm_init);
1536cb10275Sriastradh #endif
15477b5597aSriastradh }
15577b5597aSriastradh
15677b5597aSriastradh static void
drm_fini(void)15777b5597aSriastradh drm_fini(void)
15877b5597aSriastradh {
159c48dc052Sriastradh
160c48dc052Sriastradh drm_i2c_encoders_fini();
1618ba1623fSchristos drm_sysctl_fini(&drm_def);
162453c4aa9Sjmcneill drm_bridge_fini_lock();
163453c4aa9Sjmcneill drm_panel_fini_lock();
16477b5597aSriastradh drm_connector_ida_destroy();
1650f849473Sriastradh linux_mutex_destroy(&drm_kernel_fb_helper_lock);
16677b5597aSriastradh linux_mutex_destroy(&drm_global_mutex);
1679e5fbd4fSriastradh cleanup_srcu_struct(&drm_unplug_srcu);
16877b5597aSriastradh idr_destroy(&drm_minors_idr);
16977b5597aSriastradh spin_lock_destroy(&drm_minor_lock);
170d46aeca2Sriastradh drm_agp_hooks_fini();
17177b5597aSriastradh }
1726cb10275Sriastradh
17326e846f0Sriastradh int
drm_irq_by_busid(struct drm_device * dev,void * data,struct drm_file * file)17426e846f0Sriastradh drm_irq_by_busid(struct drm_device *dev, void *data, struct drm_file *file)
17526e846f0Sriastradh {
17626e846f0Sriastradh
17726e846f0Sriastradh return -ENODEV;
17826e846f0Sriastradh }
17926e846f0Sriastradh
1806cb10275Sriastradh static int
drmkms_modcmd(modcmd_t cmd,void * arg __unused)1816cb10275Sriastradh drmkms_modcmd(modcmd_t cmd, void *arg __unused)
1826cb10275Sriastradh {
1836cb10275Sriastradh #ifdef _MODULE
1846cb10275Sriastradh devmajor_t bmajor = NODEVMAJOR, cmajor = NODEVMAJOR;
1856cb10275Sriastradh #endif
18677b5597aSriastradh int error;
1876cb10275Sriastradh
1886cb10275Sriastradh switch (cmd) {
1896cb10275Sriastradh case MODULE_CMD_INIT:
1906cb10275Sriastradh #ifdef _MODULE
19177b5597aSriastradh error = drm_init();
19277b5597aSriastradh #else
19377b5597aSriastradh error = drm_guarantee_initialized();
19477b5597aSriastradh #endif
19577b5597aSriastradh if (error)
19677b5597aSriastradh return error;
19777b5597aSriastradh #ifdef _MODULE
1986cb10275Sriastradh error = devsw_attach("drm", NULL, &bmajor,
1996cb10275Sriastradh &drm_cdevsw, &cmajor);
2006cb10275Sriastradh if (error) {
2016cb10275Sriastradh aprint_error("drmkms: unable to attach devsw: %d\n",
2026cb10275Sriastradh error);
20377b5597aSriastradh return error;
2046cb10275Sriastradh }
2056cb10275Sriastradh #endif
2066cb10275Sriastradh return 0;
2076cb10275Sriastradh
2086cb10275Sriastradh case MODULE_CMD_FINI:
2096cb10275Sriastradh #ifdef _MODULE
2102f7fddcfSriastradh devsw_detach(NULL, &drm_cdevsw);
2116cb10275Sriastradh #endif
21277b5597aSriastradh drm_fini();
2136cb10275Sriastradh return 0;
2146cb10275Sriastradh
2156cb10275Sriastradh default:
2166cb10275Sriastradh return ENOTTY;
2176cb10275Sriastradh }
2186cb10275Sriastradh }
219