1 /* 2 * Copyright 2008 Advanced Micro Devices, Inc. 3 * Copyright 2008 Red Hat Inc. 4 * Copyright 2009 Jerome Glisse. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Dave Airlie 25 * Alex Deucher 26 * Jerome Glisse 27 */ 28 #include <drm/drmP.h> 29 #include "amdgpu.h" 30 #include "atom.h" 31 32 #include <linux/slab.h> 33 #include <linux/acpi.h> 34 /* 35 * BIOS. 36 */ 37 38 /* If you boot an IGP board with a discrete card as the primary, 39 * the IGP rom is not accessible via the rom bar as the IGP rom is 40 * part of the system bios. On boot, the system bios puts a 41 * copy of the igp rom at the start of vram if a discrete card is 42 * present. 43 */ 44 static bool igp_read_bios_from_vram(struct amdgpu_device *adev) 45 { 46 uint8_t __iomem *bios; 47 resource_size_t vram_base; 48 resource_size_t size = 256 * 1024; /* ??? */ 49 50 if (!(adev->flags & AMD_IS_APU)) 51 if (!amdgpu_card_posted(adev)) 52 return false; 53 54 adev->bios = NULL; 55 vram_base = pci_resource_start(adev->pdev, 0); 56 bios = ioremap(vram_base, size); 57 if (!bios) { 58 return false; 59 } 60 61 if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { 62 iounmap(bios); 63 return false; 64 } 65 adev->bios = kmalloc(size, GFP_KERNEL); 66 if (adev->bios == NULL) { 67 iounmap(bios); 68 return false; 69 } 70 memcpy_fromio(adev->bios, bios, size); 71 iounmap(bios); 72 return true; 73 } 74 75 bool amdgpu_read_bios(struct amdgpu_device *adev) 76 { 77 uint8_t __iomem *bios, val1, val2; 78 size_t size; 79 80 adev->bios = NULL; 81 /* XXX: some cards may return 0 for rom size? ddx has a workaround */ 82 bios = pci_map_rom(adev->pdev, &size); 83 if (!bios) { 84 return false; 85 } 86 87 val1 = readb(&bios[0]); 88 val2 = readb(&bios[1]); 89 90 if (size == 0 || val1 != 0x55 || val2 != 0xaa) { 91 pci_unmap_rom(adev->pdev, bios); 92 return false; 93 } 94 adev->bios = kzalloc(size, GFP_KERNEL); 95 if (adev->bios == NULL) { 96 pci_unmap_rom(adev->pdev, bios); 97 return false; 98 } 99 memcpy_fromio(adev->bios, bios, size); 100 pci_unmap_rom(adev->pdev, bios); 101 return true; 102 } 103 104 static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) 105 { 106 uint8_t __iomem *bios; 107 size_t size; 108 109 adev->bios = NULL; 110 111 bios = pci_platform_rom(adev->pdev, &size); 112 if (!bios) { 113 return false; 114 } 115 116 if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { 117 return false; 118 } 119 adev->bios = kmemdup(bios, size, GFP_KERNEL); 120 if (adev->bios == NULL) { 121 return false; 122 } 123 124 return true; 125 } 126 127 #ifdef CONFIG_ACPI 128 /* ATRM is used to get the BIOS on the discrete cards in 129 * dual-gpu systems. 130 */ 131 /* retrieve the ROM in 4k blocks */ 132 #define ATRM_BIOS_PAGE 4096 133 /** 134 * amdgpu_atrm_call - fetch a chunk of the vbios 135 * 136 * @atrm_handle: acpi ATRM handle 137 * @bios: vbios image pointer 138 * @offset: offset of vbios image data to fetch 139 * @len: length of vbios image data to fetch 140 * 141 * Executes ATRM to fetch a chunk of the discrete 142 * vbios image on PX systems (all asics). 143 * Returns the length of the buffer fetched. 144 */ 145 static int amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios, 146 int offset, int len) 147 { 148 acpi_status status; 149 union acpi_object atrm_arg_elements[2], *obj; 150 struct acpi_object_list atrm_arg; 151 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; 152 153 atrm_arg.count = 2; 154 atrm_arg.pointer = &atrm_arg_elements[0]; 155 156 atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; 157 atrm_arg_elements[0].integer.value = offset; 158 159 atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; 160 atrm_arg_elements[1].integer.value = len; 161 162 status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); 163 if (ACPI_FAILURE(status)) { 164 printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); 165 return -ENODEV; 166 } 167 168 obj = (union acpi_object *)buffer.pointer; 169 memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); 170 len = obj->buffer.length; 171 kfree(buffer.pointer); 172 return len; 173 } 174 175 static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) 176 { 177 int ret; 178 int size = 256 * 1024; 179 int i; 180 struct pci_dev *pdev = NULL; 181 acpi_handle dhandle, atrm_handle; 182 acpi_status status; 183 bool found = false; 184 185 /* ATRM is for the discrete card only */ 186 if (adev->flags & AMD_IS_APU) 187 return false; 188 189 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 190 dhandle = ACPI_HANDLE(&pdev->dev); 191 if (!dhandle) 192 continue; 193 194 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); 195 if (!ACPI_FAILURE(status)) { 196 found = true; 197 break; 198 } 199 } 200 201 if (!found) { 202 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { 203 dhandle = ACPI_HANDLE(&pdev->dev); 204 if (!dhandle) 205 continue; 206 207 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); 208 if (!ACPI_FAILURE(status)) { 209 found = true; 210 break; 211 } 212 } 213 } 214 215 if (!found) 216 return false; 217 218 adev->bios = kmalloc(size, GFP_KERNEL); 219 if (!adev->bios) { 220 DRM_ERROR("Unable to allocate bios\n"); 221 return false; 222 } 223 224 for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { 225 ret = amdgpu_atrm_call(atrm_handle, 226 adev->bios, 227 (i * ATRM_BIOS_PAGE), 228 ATRM_BIOS_PAGE); 229 if (ret < ATRM_BIOS_PAGE) 230 break; 231 } 232 233 if (i == 0 || adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { 234 kfree(adev->bios); 235 return false; 236 } 237 return true; 238 } 239 #else 240 static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) 241 { 242 return false; 243 } 244 #endif 245 246 static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev) 247 { 248 if (adev->flags & AMD_IS_APU) 249 return igp_read_bios_from_vram(adev); 250 else 251 return amdgpu_asic_read_disabled_bios(adev); 252 } 253 254 #ifdef CONFIG_ACPI 255 static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) 256 { 257 bool ret = false; 258 struct acpi_table_header *hdr; 259 acpi_size tbl_size; 260 UEFI_ACPI_VFCT *vfct; 261 GOP_VBIOS_CONTENT *vbios; 262 VFCT_IMAGE_HEADER *vhdr; 263 264 if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) 265 return false; 266 if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { 267 DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); 268 goto out_unmap; 269 } 270 271 vfct = (UEFI_ACPI_VFCT *)hdr; 272 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { 273 DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); 274 goto out_unmap; 275 } 276 277 vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); 278 vhdr = &vbios->VbiosHeader; 279 DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", 280 vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, 281 vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); 282 283 if (vhdr->PCIBus != adev->pdev->bus->number || 284 vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) || 285 vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn) || 286 vhdr->VendorID != adev->pdev->vendor || 287 vhdr->DeviceID != adev->pdev->device) { 288 DRM_INFO("ACPI VFCT table is not for this card\n"); 289 goto out_unmap; 290 } 291 292 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { 293 DRM_ERROR("ACPI VFCT image truncated\n"); 294 goto out_unmap; 295 } 296 297 adev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); 298 ret = !!adev->bios; 299 300 out_unmap: 301 return ret; 302 } 303 #else 304 static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) 305 { 306 return false; 307 } 308 #endif 309 310 bool amdgpu_get_bios(struct amdgpu_device *adev) 311 { 312 bool r; 313 uint16_t tmp; 314 315 r = amdgpu_atrm_get_bios(adev); 316 if (r == false) 317 r = amdgpu_acpi_vfct_bios(adev); 318 if (r == false) 319 r = igp_read_bios_from_vram(adev); 320 if (r == false) 321 r = amdgpu_read_bios(adev); 322 if (r == false) { 323 r = amdgpu_read_disabled_bios(adev); 324 } 325 if (r == false) { 326 r = amdgpu_read_platform_bios(adev); 327 } 328 if (r == false || adev->bios == NULL) { 329 DRM_ERROR("Unable to locate a BIOS ROM\n"); 330 adev->bios = NULL; 331 return false; 332 } 333 if (adev->bios[0] != 0x55 || adev->bios[1] != 0xaa) { 334 printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]); 335 goto free_bios; 336 } 337 338 tmp = RBIOS16(0x18); 339 if (RBIOS8(tmp + 0x14) != 0x0) { 340 DRM_INFO("Not an x86 BIOS ROM, not using.\n"); 341 goto free_bios; 342 } 343 344 adev->bios_header_start = RBIOS16(0x48); 345 if (!adev->bios_header_start) { 346 goto free_bios; 347 } 348 tmp = adev->bios_header_start + 4; 349 if (!memcmp(adev->bios + tmp, "ATOM", 4) || 350 !memcmp(adev->bios + tmp, "MOTA", 4)) { 351 adev->is_atom_bios = true; 352 } else { 353 adev->is_atom_bios = false; 354 } 355 356 DRM_DEBUG("%sBIOS detected\n", adev->is_atom_bios ? "ATOM" : "COM"); 357 return true; 358 free_bios: 359 kfree(adev->bios); 360 adev->bios = NULL; 361 return false; 362 } 363