/* * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * author: Jerome Glisse */ #ifndef AMD_PCI_HELPER_H #define AMD_PCI_HELPER_H #include #include #include #include #include enum radeon_family { CHIP_UNKNOWN, CHIP_R600, CHIP_RV610, CHIP_RV630, CHIP_RV670, CHIP_RV620, CHIP_RV635, CHIP_RS780, CHIP_RS880, CHIP_RV770, CHIP_RV730, CHIP_RV710, CHIP_RV740, CHIP_CEDAR, CHIP_REDWOOD, CHIP_JUNIPER, CHIP_CYPRESS, CHIP_HEMLOCK, CHIP_PALM, CHIP_SUMO, CHIP_SUMO2, CHIP_BARTS, CHIP_TURKS, CHIP_CAICOS, CHIP_CAYMAN, CHIP_LAST, }; static const char *amd_chip_name(unsigned family) { switch (family) { case CHIP_R600: return "r600"; case CHIP_RV610: return "rv610"; case CHIP_RV630: return "rv630"; case CHIP_RV670: return "rv670"; case CHIP_RV620: return "rv620"; case CHIP_RV635: return "rv635"; case CHIP_RS780: return "rs780"; case CHIP_RS880: return "rs880"; case CHIP_RV770: return "rv770"; case CHIP_RV730: return "rv730"; case CHIP_RV710: return "rv710"; case CHIP_RV740: return "rv740"; case CHIP_CEDAR: return "cedar"; case CHIP_REDWOOD: return "redwood"; case CHIP_JUNIPER: return "juniper"; case CHIP_CYPRESS: return "cypress"; case CHIP_HEMLOCK: return "hemlock"; case CHIP_PALM: return "palm"; case CHIP_SUMO: return "sumo"; case CHIP_SUMO2: return "sumo2"; case CHIP_BARTS: return "barts"; case CHIP_TURKS: return "turks"; case CHIP_CAICOS: return "caicos"; case CHIP_CAYMAN: return "cayman"; case CHIP_UNKNOWN: default: return "unknown"; } } static const char *amd_family_name(unsigned family) { switch (family) { case CHIP_R600: case CHIP_RV610: case CHIP_RV630: case CHIP_RV670: case CHIP_RV620: case CHIP_RV635: case CHIP_RS780: case CHIP_RS880: return "hd2xxx"; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: return "hd4xxx"; case CHIP_CEDAR: case CHIP_REDWOOD: case CHIP_JUNIPER: case CHIP_CYPRESS: case CHIP_HEMLOCK: case CHIP_PALM: case CHIP_SUMO: case CHIP_SUMO2: case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: case CHIP_CAYMAN: return "hd5xxx"; case CHIP_UNKNOWN: default: return "unknown"; } } struct amd_info { unsigned vendor; unsigned device; unsigned family; }; static const struct amd_info amd_infos[] = { {0x1002, 0x9610, CHIP_RS780}, {0x1002, 0x9611, CHIP_RS780}, {0x1002, 0x9612, CHIP_RS780}, {0x1002, 0x9613, CHIP_RS780}, {0x1002, 0x9614, CHIP_RS780}, {0x1002, 0x9615, CHIP_RS780}, {0x1002, 0x9616, CHIP_RS780}, {0x1002, 0x9710, CHIP_RS880}, {0x1002, 0x9711, CHIP_RS880}, {0x1002, 0x9712, CHIP_RS880}, {0x1002, 0x9713, CHIP_RS880}, {0x1002, 0x9714, CHIP_RS880}, {0x1002, 0x9715, CHIP_RS880}, {0x1002, 0x9400, CHIP_R600}, {0x1002, 0x9401, CHIP_R600}, {0x1002, 0x9402, CHIP_R600}, {0x1002, 0x9403, CHIP_R600}, {0x1002, 0x9405, CHIP_R600}, {0x1002, 0x940A, CHIP_R600}, {0x1002, 0x940B, CHIP_R600}, {0x1002, 0x940F, CHIP_R600}, {0x1002, 0x94C0, CHIP_RV610}, {0x1002, 0x94C1, CHIP_RV610}, {0x1002, 0x94C3, CHIP_RV610}, {0x1002, 0x94C4, CHIP_RV610}, {0x1002, 0x94C5, CHIP_RV610}, {0x1002, 0x94C6, CHIP_RV610}, {0x1002, 0x94C7, CHIP_RV610}, {0x1002, 0x94C8, CHIP_RV610}, {0x1002, 0x94C9, CHIP_RV610}, {0x1002, 0x94CB, CHIP_RV610}, {0x1002, 0x94CC, CHIP_RV610}, {0x1002, 0x94CD, CHIP_RV610}, {0x1002, 0x95C0, CHIP_RV620}, {0x1002, 0x95C2, CHIP_RV620}, {0x1002, 0x95C4, CHIP_RV620}, {0x1002, 0x95C5, CHIP_RV620}, {0x1002, 0x95C6, CHIP_RV620}, {0x1002, 0x95C7, CHIP_RV620}, {0x1002, 0x95C9, CHIP_RV620}, {0x1002, 0x95CC, CHIP_RV620}, {0x1002, 0x95CD, CHIP_RV620}, {0x1002, 0x95CE, CHIP_RV620}, {0x1002, 0x95CF, CHIP_RV620}, {0x1002, 0x9580, CHIP_RV630}, {0x1002, 0x9581, CHIP_RV630}, {0x1002, 0x9583, CHIP_RV630}, {0x1002, 0x9586, CHIP_RV630}, {0x1002, 0x9587, CHIP_RV630}, {0x1002, 0x9588, CHIP_RV630}, {0x1002, 0x9589, CHIP_RV630}, {0x1002, 0x958A, CHIP_RV630}, {0x1002, 0x958B, CHIP_RV630}, {0x1002, 0x958C, CHIP_RV630}, {0x1002, 0x958D, CHIP_RV630}, {0x1002, 0x958E, CHIP_RV630}, {0x1002, 0x958F, CHIP_RV630}, {0x1002, 0x9590, CHIP_RV635}, {0x1002, 0x9591, CHIP_RV635}, {0x1002, 0x9593, CHIP_RV635}, {0x1002, 0x9595, CHIP_RV635}, {0x1002, 0x9596, CHIP_RV635}, {0x1002, 0x9597, CHIP_RV635}, {0x1002, 0x9598, CHIP_RV635}, {0x1002, 0x9599, CHIP_RV635}, {0x1002, 0x959B, CHIP_RV635}, {0x1002, 0x9500, CHIP_RV670}, {0x1002, 0x9501, CHIP_RV670}, {0x1002, 0x9504, CHIP_RV670}, {0x1002, 0x9505, CHIP_RV670}, {0x1002, 0x9506, CHIP_RV670}, {0x1002, 0x9507, CHIP_RV670}, {0x1002, 0x9508, CHIP_RV670}, {0x1002, 0x9509, CHIP_RV670}, {0x1002, 0x950F, CHIP_RV670}, {0x1002, 0x9511, CHIP_RV670}, {0x1002, 0x9515, CHIP_RV670}, {0x1002, 0x9517, CHIP_RV670}, {0x1002, 0x9519, CHIP_RV670}, {0x1002, 0x9540, CHIP_RV710}, {0x1002, 0x9541, CHIP_RV710}, {0x1002, 0x9542, CHIP_RV710}, {0x1002, 0x954E, CHIP_RV710}, {0x1002, 0x954F, CHIP_RV710}, {0x1002, 0x9552, CHIP_RV710}, {0x1002, 0x9553, CHIP_RV710}, {0x1002, 0x9555, CHIP_RV710}, {0x1002, 0x9557, CHIP_RV710}, {0x1002, 0x9480, CHIP_RV730}, {0x1002, 0x9487, CHIP_RV730}, {0x1002, 0x9488, CHIP_RV730}, {0x1002, 0x9489, CHIP_RV730}, {0x1002, 0x948F, CHIP_RV730}, {0x1002, 0x9490, CHIP_RV730}, {0x1002, 0x9491, CHIP_RV730}, {0x1002, 0x9495, CHIP_RV730}, {0x1002, 0x9498, CHIP_RV730}, {0x1002, 0x949C, CHIP_RV730}, {0x1002, 0x949E, CHIP_RV730}, {0x1002, 0x949F, CHIP_RV730}, {0x1002, 0x94A0, CHIP_RV740}, {0x1002, 0x94A1, CHIP_RV740}, {0x1002, 0x94A3, CHIP_RV740}, {0x1002, 0x94B1, CHIP_RV740}, {0x1002, 0x94B3, CHIP_RV740}, {0x1002, 0x94B4, CHIP_RV740}, {0x1002, 0x94B5, CHIP_RV740}, {0x1002, 0x94B9, CHIP_RV740}, {0x1002, 0x9440, CHIP_RV770}, {0x1002, 0x9441, CHIP_RV770}, {0x1002, 0x9442, CHIP_RV770}, {0x1002, 0x9443, CHIP_RV770}, {0x1002, 0x9444, CHIP_RV770}, {0x1002, 0x9446, CHIP_RV770}, {0x1002, 0x944A, CHIP_RV770}, {0x1002, 0x944B, CHIP_RV770}, {0x1002, 0x944C, CHIP_RV770}, {0x1002, 0x944E, CHIP_RV770}, {0x1002, 0x9450, CHIP_RV770}, {0x1002, 0x9452, CHIP_RV770}, {0x1002, 0x9456, CHIP_RV770}, {0x1002, 0x945A, CHIP_RV770}, {0x1002, 0x945B, CHIP_RV770}, {0x1002, 0x9460, CHIP_RV770}, {0x1002, 0x9462, CHIP_RV770}, {0x1002, 0x946A, CHIP_RV770}, {0x1002, 0x946B, CHIP_RV770}, {0x1002, 0x947A, CHIP_RV770}, {0x1002, 0x947B, CHIP_RV770}, {0x1002, 0x68e0, CHIP_CEDAR}, {0x1002, 0x68e1, CHIP_CEDAR}, {0x1002, 0x68e4, CHIP_CEDAR}, {0x1002, 0x68e5, CHIP_CEDAR}, {0x1002, 0x68e8, CHIP_CEDAR}, {0x1002, 0x68e9, CHIP_CEDAR}, {0x1002, 0x68f1, CHIP_CEDAR}, {0x1002, 0x68f8, CHIP_CEDAR}, {0x1002, 0x68f9, CHIP_CEDAR}, {0x1002, 0x68fe, CHIP_CEDAR}, {0x1002, 0x68c0, CHIP_REDWOOD}, {0x1002, 0x68c1, CHIP_REDWOOD}, {0x1002, 0x68c8, CHIP_REDWOOD}, {0x1002, 0x68c9, CHIP_REDWOOD}, {0x1002, 0x68d8, CHIP_REDWOOD}, {0x1002, 0x68d9, CHIP_REDWOOD}, {0x1002, 0x68da, CHIP_REDWOOD}, {0x1002, 0x68de, CHIP_REDWOOD}, {0x1002, 0x68a0, CHIP_JUNIPER}, {0x1002, 0x68a1, CHIP_JUNIPER}, {0x1002, 0x68a8, CHIP_JUNIPER}, {0x1002, 0x68a9, CHIP_JUNIPER}, {0x1002, 0x68b0, CHIP_JUNIPER}, {0x1002, 0x68b8, CHIP_JUNIPER}, {0x1002, 0x68b9, CHIP_JUNIPER}, {0x1002, 0x68be, CHIP_JUNIPER}, {0x1002, 0x689e, CHIP_CYPRESS}, {0x1002, 0x6880, CHIP_CYPRESS}, {0x1002, 0x6888, CHIP_CYPRESS}, {0x1002, 0x6889, CHIP_CYPRESS}, {0x1002, 0x688A, CHIP_CYPRESS}, {0x1002, 0x6898, CHIP_CYPRESS}, {0x1002, 0x6899, CHIP_CYPRESS}, {0x1002, 0x689c, CHIP_HEMLOCK}, {0x1002, 0x689d, CHIP_HEMLOCK}, {0x1002, 0x9802, CHIP_PALM}, {0x1002, 0x9803, CHIP_PALM}, {0x1002, 0x9804, CHIP_PALM}, {0x1002, 0x9805, CHIP_PALM}, {0x1002, 0x9806, CHIP_PALM}, {0x1002, 0x9807, CHIP_PALM}, {0x1002, 0x9808, CHIP_PALM}, {0x1002, 0x9809, CHIP_PALM}, {0x1002, 0x980A, CHIP_PALM}, {0x1002, 0x9640, CHIP_SUMO}, {0x1002, 0x9641, CHIP_SUMO}, {0x1002, 0x9642, CHIP_SUMO2}, {0x1002, 0x9643, CHIP_SUMO2}, {0x1002, 0x9644, CHIP_SUMO2}, {0x1002, 0x9645, CHIP_SUMO2}, {0x1002, 0x9647, CHIP_SUMO}, {0x1002, 0x9648, CHIP_SUMO}, {0x1002, 0x9649, CHIP_SUMO}, {0x1002, 0x964a, CHIP_SUMO}, {0x1002, 0x964b, CHIP_SUMO}, {0x1002, 0x964c, CHIP_SUMO}, {0x1002, 0x964e, CHIP_SUMO}, {0x1002, 0x964f, CHIP_SUMO}, {0x1002, 0x6720, CHIP_BARTS}, {0x1002, 0x6721, CHIP_BARTS}, {0x1002, 0x6722, CHIP_BARTS}, {0x1002, 0x6723, CHIP_BARTS}, {0x1002, 0x6724, CHIP_BARTS}, {0x1002, 0x6725, CHIP_BARTS}, {0x1002, 0x6726, CHIP_BARTS}, {0x1002, 0x6727, CHIP_BARTS}, {0x1002, 0x6728, CHIP_BARTS}, {0x1002, 0x6729, CHIP_BARTS}, {0x1002, 0x6738, CHIP_BARTS}, {0x1002, 0x6739, CHIP_BARTS}, {0x1002, 0x673E, CHIP_BARTS}, {0x1002, 0x6700, CHIP_CAYMAN}, {0x1002, 0x6701, CHIP_CAYMAN}, {0x1002, 0x6702, CHIP_CAYMAN}, {0x1002, 0x6703, CHIP_CAYMAN}, {0x1002, 0x6704, CHIP_CAYMAN}, {0x1002, 0x6705, CHIP_CAYMAN}, {0x1002, 0x6706, CHIP_CAYMAN}, {0x1002, 0x6707, CHIP_CAYMAN}, {0x1002, 0x6708, CHIP_CAYMAN}, {0x1002, 0x6709, CHIP_CAYMAN}, {0x1002, 0x6718, CHIP_CAYMAN}, {0x1002, 0x6719, CHIP_CAYMAN}, {0x1002, 0x671C, CHIP_CAYMAN}, {0x1002, 0x671D, CHIP_CAYMAN}, {0x1002, 0x671F, CHIP_CAYMAN}, {0x1002, 0x6740, CHIP_TURKS}, {0x1002, 0x6741, CHIP_TURKS}, {0x1002, 0x6742, CHIP_TURKS}, {0x1002, 0x6743, CHIP_TURKS}, {0x1002, 0x6744, CHIP_TURKS}, {0x1002, 0x6745, CHIP_TURKS}, {0x1002, 0x6746, CHIP_TURKS}, {0x1002, 0x6747, CHIP_TURKS}, {0x1002, 0x6748, CHIP_TURKS}, {0x1002, 0x6749, CHIP_TURKS}, {0x1002, 0x674A, CHIP_TURKS}, {0x1002, 0x6750, CHIP_TURKS}, {0x1002, 0x6751, CHIP_TURKS}, {0x1002, 0x6758, CHIP_TURKS}, {0x1002, 0x6759, CHIP_TURKS}, {0x1002, 0x675B, CHIP_TURKS}, {0x1002, 0x675D, CHIP_TURKS}, {0x1002, 0x675F, CHIP_TURKS}, {0x1002, 0x6840, CHIP_TURKS}, {0x1002, 0x6841, CHIP_TURKS}, {0x1002, 0x6842, CHIP_TURKS}, {0x1002, 0x6843, CHIP_TURKS}, {0x1002, 0x6849, CHIP_TURKS}, {0x1002, 0x6850, CHIP_TURKS}, {0x1002, 0x6858, CHIP_TURKS}, {0x1002, 0x6859, CHIP_TURKS}, {0, 0}, }; void amd_info_match(struct amd_info *info) { info->family = CHIP_UNKNOWN; for (unsigned i = 0; ; i++) { if (!amd_infos[i].vendor) { return; } if (info->device == amd_infos[i].device) { *info = amd_infos[i]; return; } } } struct amd_device { struct pci_device *device; struct amd_info info; }; static int amd_pci_probe(struct amd_device *adev) { struct pci_slot_match match; struct pci_device_iterator *iter; struct pci_device *device; int r; adev->device = NULL; r = pci_system_init(); if (r) { fprintf(stderr, "error: failed to initialise libpciaccess: %s\n", strerror(r)); return r; } match.domain = PCI_MATCH_ANY; match.bus = PCI_MATCH_ANY; match.dev = PCI_MATCH_ANY; match.func = 0; match.match_data = 0; iter = pci_slot_match_iterator_create(&match); while ((device = pci_device_next(iter))) { pci_device_probe(device); if (device->vendor_id != 0x1002) { continue; } if ((device->device_class & 0x00ffff00) != 0x00030000 && (device->device_class & 0x00ffff00) != 0x00038000) { continue; } break; } pci_iterator_destroy(iter); if (device == NULL) { fprintf(stderr, "cannot find amd gpu device\n"); return -ENODEV; } adev->device = device; adev->info.vendor = device->vendor_id; adev->info.device = device->device_id; amd_info_match(&adev->info); return 0; } #endif