xref: /OK3568_Linux_fs/kernel/drivers/iommu/amd/quirks.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun /*
4*4882a593Smuzhiyun  * Quirks for AMD IOMMU
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2019 Kai-Heng Feng <kai.heng.feng@canonical.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifdef CONFIG_DMI
10*4882a593Smuzhiyun #include <linux/dmi.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include "amd_iommu.h"
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #define IVHD_SPECIAL_IOAPIC		1
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun struct ivrs_quirk_entry {
17*4882a593Smuzhiyun 	u8 id;
18*4882a593Smuzhiyun 	u16 devid;
19*4882a593Smuzhiyun };
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun enum {
22*4882a593Smuzhiyun 	DELL_INSPIRON_7375 = 0,
23*4882a593Smuzhiyun 	DELL_LATITUDE_5495,
24*4882a593Smuzhiyun 	LENOVO_IDEAPAD_330S_15ARR,
25*4882a593Smuzhiyun };
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun static const struct ivrs_quirk_entry ivrs_ioapic_quirks[][3] __initconst = {
28*4882a593Smuzhiyun 	/* ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 */
29*4882a593Smuzhiyun 	[DELL_INSPIRON_7375] = {
30*4882a593Smuzhiyun 		{ .id = 4, .devid = 0xa0 },
31*4882a593Smuzhiyun 		{ .id = 5, .devid = 0x2 },
32*4882a593Smuzhiyun 		{}
33*4882a593Smuzhiyun 	},
34*4882a593Smuzhiyun 	/* ivrs_ioapic[4]=00:14.0 */
35*4882a593Smuzhiyun 	[DELL_LATITUDE_5495] = {
36*4882a593Smuzhiyun 		{ .id = 4, .devid = 0xa0 },
37*4882a593Smuzhiyun 		{}
38*4882a593Smuzhiyun 	},
39*4882a593Smuzhiyun 	/* ivrs_ioapic[32]=00:14.0 */
40*4882a593Smuzhiyun 	[LENOVO_IDEAPAD_330S_15ARR] = {
41*4882a593Smuzhiyun 		{ .id = 32, .devid = 0xa0 },
42*4882a593Smuzhiyun 		{}
43*4882a593Smuzhiyun 	},
44*4882a593Smuzhiyun 	{}
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
ivrs_ioapic_quirk_cb(const struct dmi_system_id * d)47*4882a593Smuzhiyun static int __init ivrs_ioapic_quirk_cb(const struct dmi_system_id *d)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun 	const struct ivrs_quirk_entry *i;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	for (i = d->driver_data; i->id != 0 && i->devid != 0; i++)
52*4882a593Smuzhiyun 		add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u16 *)&i->devid, 0);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	return 0;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun static const struct dmi_system_id ivrs_quirks[] __initconst = {
58*4882a593Smuzhiyun 	{
59*4882a593Smuzhiyun 		.callback = ivrs_ioapic_quirk_cb,
60*4882a593Smuzhiyun 		.ident = "Dell Inspiron 7375",
61*4882a593Smuzhiyun 		.matches = {
62*4882a593Smuzhiyun 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
63*4882a593Smuzhiyun 			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7375"),
64*4882a593Smuzhiyun 		},
65*4882a593Smuzhiyun 		.driver_data = (void *)&ivrs_ioapic_quirks[DELL_INSPIRON_7375],
66*4882a593Smuzhiyun 	},
67*4882a593Smuzhiyun 	{
68*4882a593Smuzhiyun 		.callback = ivrs_ioapic_quirk_cb,
69*4882a593Smuzhiyun 		.ident = "Dell Latitude 5495",
70*4882a593Smuzhiyun 		.matches = {
71*4882a593Smuzhiyun 			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
72*4882a593Smuzhiyun 			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 5495"),
73*4882a593Smuzhiyun 		},
74*4882a593Smuzhiyun 		.driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
75*4882a593Smuzhiyun 	},
76*4882a593Smuzhiyun 	{
77*4882a593Smuzhiyun 		/*
78*4882a593Smuzhiyun 		 * Acer Aspire A315-41 requires the very same workaround as
79*4882a593Smuzhiyun 		 * Dell Latitude 5495
80*4882a593Smuzhiyun 		 */
81*4882a593Smuzhiyun 		.callback = ivrs_ioapic_quirk_cb,
82*4882a593Smuzhiyun 		.ident = "Acer Aspire A315-41",
83*4882a593Smuzhiyun 		.matches = {
84*4882a593Smuzhiyun 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
85*4882a593Smuzhiyun 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-41"),
86*4882a593Smuzhiyun 		},
87*4882a593Smuzhiyun 		.driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
88*4882a593Smuzhiyun 	},
89*4882a593Smuzhiyun 	{
90*4882a593Smuzhiyun 		.callback = ivrs_ioapic_quirk_cb,
91*4882a593Smuzhiyun 		.ident = "Lenovo ideapad 330S-15ARR",
92*4882a593Smuzhiyun 		.matches = {
93*4882a593Smuzhiyun 			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
94*4882a593Smuzhiyun 			DMI_MATCH(DMI_PRODUCT_NAME, "81FB"),
95*4882a593Smuzhiyun 		},
96*4882a593Smuzhiyun 		.driver_data = (void *)&ivrs_ioapic_quirks[LENOVO_IDEAPAD_330S_15ARR],
97*4882a593Smuzhiyun 	},
98*4882a593Smuzhiyun 	{}
99*4882a593Smuzhiyun };
100*4882a593Smuzhiyun 
amd_iommu_apply_ivrs_quirks(void)101*4882a593Smuzhiyun void __init amd_iommu_apply_ivrs_quirks(void)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun 	dmi_check_system(ivrs_quirks);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun #endif
106