1d6c0b56eSmrg/*
2d6c0b56eSmrg * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3d6c0b56eSmrg *                VA Linux Systems Inc., Fremont, California.
4d6c0b56eSmrg *
5d6c0b56eSmrg * All Rights Reserved.
6d6c0b56eSmrg *
7d6c0b56eSmrg * Permission is hereby granted, free of charge, to any person obtaining
8d6c0b56eSmrg * a copy of this software and associated documentation files (the
9d6c0b56eSmrg * "Software"), to deal in the Software without restriction, including
10d6c0b56eSmrg * without limitation on the rights to use, copy, modify, merge,
11d6c0b56eSmrg * publish, distribute, sublicense, and/or sell copies of the Software,
12d6c0b56eSmrg * and to permit persons to whom the Software is furnished to do so,
13d6c0b56eSmrg * subject to the following conditions:
14d6c0b56eSmrg *
15d6c0b56eSmrg * The above copyright notice and this permission notice (including the
16d6c0b56eSmrg * next paragraph) shall be included in all copies or substantial
17d6c0b56eSmrg * portions of the Software.
18d6c0b56eSmrg *
19d6c0b56eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20d6c0b56eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21d6c0b56eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22d6c0b56eSmrg * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23d6c0b56eSmrg * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24d6c0b56eSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25d6c0b56eSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26d6c0b56eSmrg * DEALINGS IN THE SOFTWARE.
27d6c0b56eSmrg */
28d6c0b56eSmrg
29d6c0b56eSmrg#ifdef HAVE_CONFIG_H
30d6c0b56eSmrg#include "config.h"
31d6c0b56eSmrg#endif
32d6c0b56eSmrg
33d6c0b56eSmrg#include <errno.h>
34d6c0b56eSmrg#include <string.h>
35d6c0b56eSmrg#include <stdlib.h>
3646845023Smrg#include <sys/stat.h>
3746845023Smrg#include <fcntl.h>
38d6c0b56eSmrg
39d6c0b56eSmrg/*
40d6c0b56eSmrg * Authors:
41d6c0b56eSmrg *   Kevin E. Martin <martin@xfree86.org>
42d6c0b56eSmrg *   Rickard E. Faith <faith@valinux.com>
43d6c0b56eSmrg * KMS support - Dave Airlie <airlied@redhat.com>
44d6c0b56eSmrg */
45d6c0b56eSmrg
46d6c0b56eSmrg#include "amdgpu_probe.h"
47d6c0b56eSmrg#include "amdgpu_version.h"
48d6c0b56eSmrg#include "amdgpu_drv.h"
49d6c0b56eSmrg
50d6c0b56eSmrg#include "xf86.h"
51d6c0b56eSmrg
52d6c0b56eSmrg#include "xf86drmMode.h"
53d6c0b56eSmrg
54d6c0b56eSmrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
55d6c0b56eSmrg#include <xf86_OSproc.h>
56d6c0b56eSmrg#endif
57d6c0b56eSmrg
58d6c0b56eSmrg#include <xf86platformBus.h>
59d6c0b56eSmrg
60d6c0b56eSmrg_X_EXPORT int gAMDGPUEntityIndex = -1;
61d6c0b56eSmrg
62d6c0b56eSmrg/* Return the options for supported chipset 'n'; NULL otherwise */
63d6c0b56eSmrgstatic const OptionInfoRec *AMDGPUAvailableOptions(int chipid, int busid)
64d6c0b56eSmrg{
65d6c0b56eSmrg	return AMDGPUOptionsWeak();
66d6c0b56eSmrg}
67d6c0b56eSmrg
6811bf0794Smrgstatic SymTabRec AMDGPUAny[] = {
6911bf0794Smrg	{ 0, "All GPUs supported by the amdgpu kernel driver" },
7011bf0794Smrg	{ -1, NULL }
7111bf0794Smrg};
7211bf0794Smrg
73d6c0b56eSmrg/* Return the string name for supported chipset 'n'; NULL otherwise. */
74d6c0b56eSmrgstatic void AMDGPUIdentify(int flags)
75d6c0b56eSmrg{
7611bf0794Smrg	xf86PrintChipsets(AMDGPU_NAME, "Driver for AMD Radeon", AMDGPUAny);
77d6c0b56eSmrg}
78d6c0b56eSmrg
7946845023Smrgstatic Bool amdgpu_device_matches(const drmDevicePtr device,
8046845023Smrg				  const struct pci_device *dev)
81d6c0b56eSmrg{
8246845023Smrg	return (device->bustype == DRM_BUS_PCI &&
8346845023Smrg		device->businfo.pci->domain == dev->domain &&
8446845023Smrg		device->businfo.pci->bus == dev->bus &&
8546845023Smrg		device->businfo.pci->dev == dev->dev &&
8646845023Smrg		device->businfo.pci->func == dev->func);
87d6c0b56eSmrg}
88d6c0b56eSmrg
8946845023Smrgstatic Bool amdgpu_kernel_mode_enabled(ScrnInfoPtr pScrn)
90d6c0b56eSmrg{
9146845023Smrg#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
9246845023Smrg	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn);
9346845023Smrg	const char *busIdString = pAMDGPUEnt->busid;
94d6c0b56eSmrg	int ret = drmCheckModesettingSupported(busIdString);
95d6c0b56eSmrg
96d6c0b56eSmrg	if (ret) {
97d6c0b56eSmrg		if (xf86LoadKernelModule("amdgpukms"))
98d6c0b56eSmrg			ret = drmCheckModesettingSupported(busIdString);
99d6c0b56eSmrg	}
100d6c0b56eSmrg	if (ret) {
101d6c0b56eSmrg		xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
102d6c0b56eSmrg			       "[KMS] drm report modesetting isn't supported.\n");
103d6c0b56eSmrg		return FALSE;
104d6c0b56eSmrg	}
105d6c0b56eSmrg
10646845023Smrg#endif
107d6c0b56eSmrg	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
108d6c0b56eSmrg		       "[KMS] Kernel modesetting enabled.\n");
109d6c0b56eSmrg	return TRUE;
110d6c0b56eSmrg}
111d6c0b56eSmrg
11235d5b7c7Smrgstatic int amdgpu_kernel_open_fd(ScrnInfoPtr pScrn,
11335d5b7c7Smrg				 struct pci_device *pci_dev,
11446845023Smrg				 struct xf86_platform_device *platform_dev,
11546845023Smrg				 AMDGPUEntPtr pAMDGPUEnt)
116d6c0b56eSmrg{
11746845023Smrg#define MAX_DRM_DEVICES 64
11846845023Smrg	drmDevicePtr devices[MAX_DRM_DEVICES];
11935d5b7c7Smrg	struct pci_device *dev;
12046845023Smrg	const char *path;
12146845023Smrg	int fd = -1, i, ret;
12246845023Smrg
12346845023Smrg	if (platform_dev)
12446845023Smrg		dev = platform_dev->pdev;
12546845023Smrg	else
12646845023Smrg		dev = pci_dev;
12746845023Smrg
12846845023Smrg	XNFasprintf(&pAMDGPUEnt->busid, "pci:%04x:%02x:%02x.%u",
12946845023Smrg		    dev->domain, dev->bus, dev->dev, dev->func);
130d6c0b56eSmrg
131d6c0b56eSmrg	if (platform_dev) {
13246845023Smrg#ifdef ODEV_ATTRIB_FD
133d6c0b56eSmrg		fd = xf86_get_platform_device_int_attrib(platform_dev,
134d6c0b56eSmrg							 ODEV_ATTRIB_FD, -1);
135d6c0b56eSmrg		if (fd != -1)
136d6c0b56eSmrg			return fd;
137d6c0b56eSmrg#endif
138d6c0b56eSmrg
13946845023Smrg#ifdef ODEV_ATTRIB_PATH
14046845023Smrg		path = xf86_get_platform_device_attrib(platform_dev,
14146845023Smrg						       ODEV_ATTRIB_PATH);
14235d5b7c7Smrg
14346845023Smrg		fd = open(path, O_RDWR | O_CLOEXEC);
14446845023Smrg		if (fd != -1)
14546845023Smrg			return fd;
14646845023Smrg#endif
14746845023Smrg	}
14846845023Smrg
14946845023Smrg	if (!amdgpu_kernel_mode_enabled(pScrn))
15035d5b7c7Smrg		return -1;
15135d5b7c7Smrg
15246845023Smrg	ret = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
15346845023Smrg	if (ret == -1) {
15446845023Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
15546845023Smrg			   "[drm] Failed to retrieve DRM devices information.\n");
15635d5b7c7Smrg		return -1;
15735d5b7c7Smrg	}
15846845023Smrg	for (i = 0; i < ret; i++) {
15946845023Smrg		if (amdgpu_device_matches(devices[i], dev) &&
16046845023Smrg		    devices[i]->available_nodes & (1 << DRM_NODE_PRIMARY)) {
16146845023Smrg			path = devices[i]->nodes[DRM_NODE_PRIMARY];
16246845023Smrg			fd = open(path, O_RDWR | O_CLOEXEC);
16346845023Smrg			break;
16446845023Smrg		}
16546845023Smrg	}
16646845023Smrg	drmFreeDevices(devices, ret);
16735d5b7c7Smrg
168d6c0b56eSmrg	if (fd == -1)
169d6c0b56eSmrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
170d6c0b56eSmrg			   "[drm] Failed to open DRM device for %s: %s\n",
17146845023Smrg			   pAMDGPUEnt->busid, strerror(errno));
172d6c0b56eSmrg	return fd;
17346845023Smrg#undef MAX_DRM_DEVICES
174d6c0b56eSmrg}
175d6c0b56eSmrg
17611bf0794Smrgvoid amdgpu_kernel_close_fd(AMDGPUEntPtr pAMDGPUEnt)
17711bf0794Smrg{
17835d5b7c7Smrg#if defined(XSERVER_PLATFORM_BUS) && defined(XF86_PDEV_SERVER_FD)
17911bf0794Smrg	if (!(pAMDGPUEnt->platform_dev &&
18011bf0794Smrg	      pAMDGPUEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
18111bf0794Smrg#endif
18246845023Smrg		close(pAMDGPUEnt->fd);
18311bf0794Smrg	pAMDGPUEnt->fd = -1;
18411bf0794Smrg}
18511bf0794Smrg
18646845023Smrg/* Pull a local version of the helper. It's available since 2.4.98 yet
18746845023Smrg * it may be too new for some distributions.
18846845023Smrg */
18946845023Smrgstatic int local_drmIsMaster(int fd)
190d6c0b56eSmrg{
19146845023Smrg	return drmAuthMagic(fd, 0) != -EACCES;
19246845023Smrg}
193d6c0b56eSmrg
19446845023Smrgstatic Bool amdgpu_open_drm_master(ScrnInfoPtr pScrn,
19546845023Smrg				   struct pci_device *pci_dev,
19646845023Smrg				   struct xf86_platform_device *platform_dev,
19746845023Smrg				   AMDGPUEntPtr pAMDGPUEnt)
19846845023Smrg{
19933a2f185Smrg	drmSetVersion sv;
20033a2f185Smrg	int err;
20133a2f185Smrg
20246845023Smrg	pAMDGPUEnt->fd = amdgpu_kernel_open_fd(pScrn, pci_dev, platform_dev, pAMDGPUEnt);
203d6c0b56eSmrg	if (pAMDGPUEnt->fd == -1)
204d6c0b56eSmrg		return FALSE;
205d6c0b56eSmrg
20633a2f185Smrg	/* Check that what we opened was a master or a master-capable FD,
20733a2f185Smrg	 * by setting the version of the interface we'll use to talk to it.
20833a2f185Smrg	 * (see DRIOpenDRMMaster() in DRI1)
20933a2f185Smrg	 */
21033a2f185Smrg	sv.drm_di_major = 1;
21133a2f185Smrg	sv.drm_di_minor = 1;
21233a2f185Smrg	sv.drm_dd_major = -1;
21333a2f185Smrg	sv.drm_dd_minor = -1;
21433a2f185Smrg	err = drmSetInterfaceVersion(pAMDGPUEnt->fd, &sv);
21533a2f185Smrg	if (err != 0) {
21633a2f185Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
21733a2f185Smrg			   "[drm] failed to set drm interface version.\n");
21833a2f185Smrg		amdgpu_kernel_close_fd(pAMDGPUEnt);
21933a2f185Smrg		return FALSE;
22033a2f185Smrg	}
22133a2f185Smrg
22246845023Smrg	/* Check that what we opened is a master or a master-capable FD */
22346845023Smrg	if (!local_drmIsMaster(pAMDGPUEnt->fd)) {
224d6c0b56eSmrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
22546845023Smrg			   "[drm] device is not DRM master.\n");
22611bf0794Smrg		amdgpu_kernel_close_fd(pAMDGPUEnt);
227d6c0b56eSmrg		return FALSE;
228d6c0b56eSmrg	}
229d6c0b56eSmrg
230d6c0b56eSmrg	return TRUE;
231d6c0b56eSmrg}
232d6c0b56eSmrg
23346845023Smrgstatic Bool amdgpu_device_setup(ScrnInfoPtr pScrn,
23446845023Smrg				struct pci_device *pci_dev,
23546845023Smrg				struct xf86_platform_device *platform_dev,
23646845023Smrg				AMDGPUEntPtr pAMDGPUEnt)
23746845023Smrg{
23846845023Smrg	uint32_t major_version;
23946845023Smrg	uint32_t minor_version;
24046845023Smrg
24146845023Smrg	pAMDGPUEnt->platform_dev = platform_dev;
24246845023Smrg	if (!amdgpu_open_drm_master(pScrn, pci_dev, platform_dev,
24346845023Smrg				    pAMDGPUEnt))
24446845023Smrg		return FALSE;
24546845023Smrg
24646845023Smrg	if (amdgpu_device_initialize(pAMDGPUEnt->fd,
24746845023Smrg				     &major_version,
24846845023Smrg				     &minor_version,
24946845023Smrg				     &pAMDGPUEnt->pDev)) {
25046845023Smrg		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
25146845023Smrg			   "amdgpu_device_initialize failed\n");
25246845023Smrg		goto error_amdgpu;
25346845023Smrg	}
25446845023Smrg
25546845023Smrg	return TRUE;
25646845023Smrg
25746845023Smrgerror_amdgpu:
25846845023Smrg	amdgpu_kernel_close_fd(pAMDGPUEnt);
25946845023Smrg	return FALSE;
26046845023Smrg}
26146845023Smrg
26246845023Smrgstatic Bool
26346845023Smrgamdgpu_probe(ScrnInfoPtr pScrn, int entity_num,
26446845023Smrg	     struct pci_device *pci_dev, struct xf86_platform_device *dev)
265d6c0b56eSmrg{
26624b90cf4Smrg	EntityInfoPtr pEnt = NULL;
267d6c0b56eSmrg	DevUnion *pPriv;
268d6c0b56eSmrg	AMDGPUEntPtr pAMDGPUEnt;
269d6c0b56eSmrg
270d6c0b56eSmrg	if (!pScrn)
271d6c0b56eSmrg		return FALSE;
272d6c0b56eSmrg
273d6c0b56eSmrg	pScrn->driverVersion = AMDGPU_VERSION_CURRENT;
274d6c0b56eSmrg	pScrn->driverName = AMDGPU_DRIVER_NAME;
275d6c0b56eSmrg	pScrn->name = AMDGPU_NAME;
276d6c0b56eSmrg	pScrn->Probe = NULL;
277d6c0b56eSmrg	pScrn->PreInit = AMDGPUPreInit_KMS;
278d6c0b56eSmrg	pScrn->ScreenInit = AMDGPUScreenInit_KMS;
279d6c0b56eSmrg	pScrn->SwitchMode = AMDGPUSwitchMode_KMS;
280d6c0b56eSmrg	pScrn->AdjustFrame = AMDGPUAdjustFrame_KMS;
281d6c0b56eSmrg	pScrn->EnterVT = AMDGPUEnterVT_KMS;
282d6c0b56eSmrg	pScrn->LeaveVT = AMDGPULeaveVT_KMS;
283d6c0b56eSmrg	pScrn->FreeScreen = AMDGPUFreeScreen_KMS;
284d6c0b56eSmrg	pScrn->ValidMode = AMDGPUValidMode;
285d6c0b56eSmrg
286d6c0b56eSmrg	pEnt = xf86GetEntityInfo(entity_num);
287d6c0b56eSmrg
288d6c0b56eSmrg	/* Create a AMDGPUEntity for all chips, even with old single head
289d6c0b56eSmrg	 * Radeon, need to use pAMDGPUEnt for new monitor detection routines.
290d6c0b56eSmrg	 */
291d6c0b56eSmrg	xf86SetEntitySharable(entity_num);
292d6c0b56eSmrg
293d6c0b56eSmrg	if (gAMDGPUEntityIndex == -1)
294d6c0b56eSmrg		gAMDGPUEntityIndex = xf86AllocateEntityPrivateIndex();
295d6c0b56eSmrg
296d6c0b56eSmrg	pPriv = xf86GetEntityPrivate(pEnt->index, gAMDGPUEntityIndex);
297d6c0b56eSmrg
298d6c0b56eSmrg	if (!pPriv->ptr) {
299d6c0b56eSmrg		pPriv->ptr = xnfcalloc(sizeof(AMDGPUEntRec), 1);
300d6c0b56eSmrg		if (!pPriv->ptr)
301d6c0b56eSmrg			goto error;
302d6c0b56eSmrg
303d6c0b56eSmrg		pAMDGPUEnt = pPriv->ptr;
30446845023Smrg		if (!amdgpu_device_setup(pScrn, pci_dev, dev, pAMDGPUEnt))
30524b90cf4Smrg			goto error;
306d6c0b56eSmrg
307d6c0b56eSmrg		pAMDGPUEnt->fd_ref = 1;
308d6c0b56eSmrg
309d6c0b56eSmrg	} else {
310d6c0b56eSmrg		pAMDGPUEnt = pPriv->ptr;
31190f2b693Smrg
31290f2b693Smrg		if (pAMDGPUEnt->fd_ref == ARRAY_SIZE(pAMDGPUEnt->scrn)) {
31390f2b693Smrg			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
31490f2b693Smrg				   "Only up to %u Zaphod instances supported\n",
31590f2b693Smrg				   (unsigned)ARRAY_SIZE(pAMDGPUEnt->scrn));
31690f2b693Smrg			goto error;
31790f2b693Smrg		}
31890f2b693Smrg
319d6c0b56eSmrg		pAMDGPUEnt->fd_ref++;
320d6c0b56eSmrg	}
321d6c0b56eSmrg
322d6c0b56eSmrg	xf86SetEntityInstanceForScreen(pScrn, pEnt->index,
323d6c0b56eSmrg				       xf86GetNumEntityInstances(pEnt->
324d6c0b56eSmrg								 index)
325d6c0b56eSmrg				       - 1);
326d6c0b56eSmrg	free(pEnt);
327d6c0b56eSmrg
328d6c0b56eSmrg	return TRUE;
329d6c0b56eSmrg
330d6c0b56eSmrgerror:
33124b90cf4Smrg	free(pEnt);
332d6c0b56eSmrg	return FALSE;
333d6c0b56eSmrg}
334d6c0b56eSmrg
335d6c0b56eSmrgstatic Bool
336d6c0b56eSmrgamdgpu_pci_probe(DriverPtr pDriver,
337d6c0b56eSmrg		 int entity_num, struct pci_device *device, intptr_t match_data)
338d6c0b56eSmrg{
33946845023Smrg	ScrnInfoPtr pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
34046845023Smrg						NULL, NULL, NULL, NULL, NULL);
34146845023Smrg
34246845023Smrg	return amdgpu_probe(pScrn, entity_num, device, NULL);
343d6c0b56eSmrg}
344d6c0b56eSmrg
345d6c0b56eSmrgstatic Bool AMDGPUDriverFunc(ScrnInfoPtr scrn, xorgDriverFuncOp op, void *data)
346d6c0b56eSmrg{
347d6c0b56eSmrg	xorgHWFlags *flag;
348d6c0b56eSmrg
349d6c0b56eSmrg	switch (op) {
350d6c0b56eSmrg	case GET_REQUIRED_HW_INTERFACES:
351d6c0b56eSmrg		flag = (CARD32 *) data;
352d6c0b56eSmrg		(*flag) = 0;
353d6c0b56eSmrg		return TRUE;
354d6c0b56eSmrg#if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(1,15,99,0,0)
355d6c0b56eSmrg	case SUPPORTS_SERVER_FDS:
356d6c0b56eSmrg		return TRUE;
357d6c0b56eSmrg#endif
358d6c0b56eSmrg       default:
359d6c0b56eSmrg		return FALSE;
360d6c0b56eSmrg	}
361d6c0b56eSmrg}
362d6c0b56eSmrg
363d6c0b56eSmrg#ifdef XSERVER_PLATFORM_BUS
364d6c0b56eSmrgstatic Bool
365d6c0b56eSmrgamdgpu_platform_probe(DriverPtr pDriver,
366d6c0b56eSmrg		      int entity_num, int flags,
367d6c0b56eSmrg		      struct xf86_platform_device *dev, intptr_t match_data)
368d6c0b56eSmrg{
369d6c0b56eSmrg	ScrnInfoPtr pScrn;
370d6c0b56eSmrg	int scr_flags = 0;
371d6c0b56eSmrg
372d6c0b56eSmrg	if (!dev->pdev)
373d6c0b56eSmrg		return FALSE;
374d6c0b56eSmrg
375d6c0b56eSmrg	if (flags & PLATFORM_PROBE_GPU_SCREEN)
376d6c0b56eSmrg		scr_flags = XF86_ALLOCATE_GPU_SCREEN;
377d6c0b56eSmrg
378d6c0b56eSmrg	pScrn = xf86AllocateScreen(pDriver, scr_flags);
379d6c0b56eSmrg	if (xf86IsEntitySharable(entity_num))
380d6c0b56eSmrg		xf86SetEntityShared(entity_num);
381d6c0b56eSmrg	xf86AddEntityToScreen(pScrn, entity_num);
382d6c0b56eSmrg
38346845023Smrg	return amdgpu_probe(pScrn, entity_num, NULL, dev);
384d6c0b56eSmrg}
385d6c0b56eSmrg#endif
386d6c0b56eSmrg
38711bf0794Smrgstatic const struct pci_id_match amdgpu_device_match[] = {
38811bf0794Smrg    {0x1002, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
38911bf0794Smrg    {0, 0, 0},
39011bf0794Smrg};
39111bf0794Smrg
39235d5b7c7SmrgDriverRec AMDGPU = {
393d6c0b56eSmrg	AMDGPU_VERSION_CURRENT,
394d6c0b56eSmrg	AMDGPU_DRIVER_NAME,
395d6c0b56eSmrg	AMDGPUIdentify,
396d6c0b56eSmrg	NULL,
397d6c0b56eSmrg	AMDGPUAvailableOptions,
398d6c0b56eSmrg	NULL,
399d6c0b56eSmrg	0,
400d6c0b56eSmrg	AMDGPUDriverFunc,
401d6c0b56eSmrg	amdgpu_device_match,
402d6c0b56eSmrg	amdgpu_pci_probe,
403d6c0b56eSmrg#ifdef XSERVER_PLATFORM_BUS
404d6c0b56eSmrg	amdgpu_platform_probe
405d6c0b56eSmrg#endif
406d6c0b56eSmrg};
407