1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2025 Advanced Micro Devices, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: AMD 24 * 25 */ 26 27 #include <linux/dmi.h> 28 29 #include "amdgpu.h" 30 #include "amdgpu_dm.h" 31 32 struct amdgpu_dm_quirks { 33 bool aux_hpd_discon; 34 bool support_edp0_on_dp1; 35 }; 36 37 static struct amdgpu_dm_quirks quirk_entries = { 38 .aux_hpd_discon = false, 39 .support_edp0_on_dp1 = false 40 }; 41 42 static int edp0_on_dp1_callback(const struct dmi_system_id *id) 43 { 44 quirk_entries.support_edp0_on_dp1 = true; 45 return 0; 46 } 47 48 static int aux_hpd_discon_callback(const struct dmi_system_id *id) 49 { 50 quirk_entries.aux_hpd_discon = true; 51 return 0; 52 } 53 54 static const struct dmi_system_id dmi_quirk_table[] = { 55 { 56 .callback = aux_hpd_discon_callback, 57 .matches = { 58 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 59 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"), 60 }, 61 }, 62 { 63 .callback = aux_hpd_discon_callback, 64 .matches = { 65 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 66 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"), 67 }, 68 }, 69 { 70 .callback = aux_hpd_discon_callback, 71 .matches = { 72 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 73 DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), 74 }, 75 }, 76 { 77 .callback = aux_hpd_discon_callback, 78 .matches = { 79 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 80 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), 81 }, 82 }, 83 { 84 .callback = aux_hpd_discon_callback, 85 .matches = { 86 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 87 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), 88 }, 89 }, 90 { 91 .callback = aux_hpd_discon_callback, 92 .matches = { 93 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 94 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), 95 }, 96 }, 97 { 98 .callback = aux_hpd_discon_callback, 99 .matches = { 100 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 101 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), 102 }, 103 }, 104 { 105 .callback = aux_hpd_discon_callback, 106 .matches = { 107 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 108 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), 109 }, 110 }, 111 { 112 .callback = aux_hpd_discon_callback, 113 .matches = { 114 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 115 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), 116 }, 117 }, 118 { 119 .callback = edp0_on_dp1_callback, 120 .matches = { 121 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 122 DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"), 123 }, 124 }, 125 { 126 .callback = edp0_on_dp1_callback, 127 .matches = { 128 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 129 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 645 14 inch G11 Notebook PC"), 130 }, 131 }, 132 { 133 .callback = edp0_on_dp1_callback, 134 .matches = { 135 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 136 DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"), 137 }, 138 }, 139 { 140 .callback = edp0_on_dp1_callback, 141 .matches = { 142 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 143 DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 445 14 inch G11 Notebook PC"), 144 }, 145 }, 146 { 147 .callback = edp0_on_dp1_callback, 148 .matches = { 149 DMI_MATCH(DMI_SYS_VENDOR, "HP"), 150 DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook 465 16 inch G11 Notebook PC"), 151 }, 152 }, 153 {} 154 /* TODO: refactor this from a fixed table to a dynamic option */ 155 }; 156 157 void retrieve_dmi_info(struct amdgpu_display_manager *dm) 158 { 159 struct drm_device *dev = dm->ddev; 160 int dmi_id; 161 162 dm->aux_hpd_discon_quirk = false; 163 dm->edp0_on_dp1_quirk = false; 164 165 dmi_id = dmi_check_system(dmi_quirk_table); 166 167 if (!dmi_id) 168 return; 169 170 if (quirk_entries.aux_hpd_discon) { 171 dm->aux_hpd_discon_quirk = true; 172 drm_info(dev, "aux_hpd_discon_quirk attached\n"); 173 } 174 if (quirk_entries.support_edp0_on_dp1) { 175 dm->edp0_on_dp1_quirk = true; 176 drm_info(dev, "support_edp0_on_dp1 attached\n"); 177 } 178 } 179