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 #define AMD_VBIOS_SIGNATURE " 761295520" 39 #define AMD_VBIOS_SIGNATURE_OFFSET 0x30 40 #define AMD_VBIOS_SIGNATURE_SIZE sizeof(AMD_VBIOS_SIGNATURE) 41 #define AMD_VBIOS_SIGNATURE_END (AMD_VBIOS_SIGNATURE_OFFSET + AMD_VBIOS_SIGNATURE_SIZE) 42 #define AMD_IS_VALID_VBIOS(p) ((p)[0] == 0x55 && (p)[1] == 0xAA) 43 #define AMD_VBIOS_LENGTH(p) ((p)[2] << 9) 44 45 /* If you boot an IGP board with a discrete card as the primary, 46 * the IGP rom is not accessible via the rom bar as the IGP rom is 47 * part of the system bios. On boot, the system bios puts a 48 * copy of the igp rom at the start of vram if a discrete card is 49 * present. 50 */ 51 static bool igp_read_bios_from_vram(struct amdgpu_device *adev) 52 { 53 uint8_t __iomem *bios; 54 resource_size_t vram_base; 55 resource_size_t size = 256 * 1024; /* ??? */ 56 57 if (!(adev->flags & AMD_IS_APU)) 58 if (!amdgpu_card_posted(adev)) 59 return false; 60 61 adev->bios = NULL; 62 vram_base = pci_resource_start(adev->pdev, 0); 63 bios = ioremap(vram_base, size); 64 if (!bios) { 65 return false; 66 } 67 68 if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { 69 iounmap(bios); 70 return false; 71 } 72 adev->bios = kmalloc(size, GFP_KERNEL); 73 if (adev->bios == NULL) { 74 iounmap(bios); 75 return false; 76 } 77 memcpy_fromio(adev->bios, bios, size); 78 iounmap(bios); 79 return true; 80 } 81 82 bool amdgpu_read_bios(struct amdgpu_device *adev) 83 { 84 uint8_t __iomem *bios, val[2]; 85 size_t size; 86 87 adev->bios = NULL; 88 /* XXX: some cards may return 0 for rom size? ddx has a workaround */ 89 bios = pci_map_rom(adev->pdev, &size); 90 if (!bios) { 91 return false; 92 } 93 94 val[0] = readb(&bios[0]); 95 val[1] = readb(&bios[1]); 96 97 if (size == 0 || !AMD_IS_VALID_VBIOS(val)) { 98 pci_unmap_rom(adev->pdev, bios); 99 return false; 100 } 101 adev->bios = kzalloc(size, GFP_KERNEL); 102 if (adev->bios == NULL) { 103 pci_unmap_rom(adev->pdev, bios); 104 return false; 105 } 106 memcpy_fromio(adev->bios, bios, size); 107 pci_unmap_rom(adev->pdev, bios); 108 return true; 109 } 110 111 static bool amdgpu_read_bios_from_rom(struct amdgpu_device *adev) 112 { 113 u8 header[AMD_VBIOS_SIGNATURE_END+1] = {0}; 114 int len; 115 116 if (!adev->asic_funcs->read_bios_from_rom) 117 return false; 118 119 /* validate VBIOS signature */ 120 if (amdgpu_asic_read_bios_from_rom(adev, &header[0], sizeof(header)) == false) 121 return false; 122 header[AMD_VBIOS_SIGNATURE_END] = 0; 123 124 if ((!AMD_IS_VALID_VBIOS(header)) || 125 0 != memcmp((char *)&header[AMD_VBIOS_SIGNATURE_OFFSET], 126 AMD_VBIOS_SIGNATURE, 127 strlen(AMD_VBIOS_SIGNATURE))) 128 return false; 129 130 /* valid vbios, go on */ 131 len = AMD_VBIOS_LENGTH(header); 132 len = ALIGN(len, 4); 133 adev->bios = kmalloc(len, GFP_KERNEL); 134 if (!adev->bios) { 135 DRM_ERROR("no memory to allocate for BIOS\n"); 136 return false; 137 } 138 139 /* read complete BIOS */ 140 return amdgpu_asic_read_bios_from_rom(adev, adev->bios, len); 141 } 142 143 static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) 144 { 145 uint8_t __iomem *bios; 146 size_t size; 147 148 adev->bios = NULL; 149 150 bios = pci_platform_rom(adev->pdev, &size); 151 if (!bios) { 152 return false; 153 } 154 155 if (size == 0 || !AMD_IS_VALID_VBIOS(bios)) { 156 return false; 157 } 158 adev->bios = kmemdup(bios, size, GFP_KERNEL); 159 if (adev->bios == NULL) { 160 return false; 161 } 162 163 return true; 164 } 165 166 #ifdef CONFIG_ACPI 167 /* ATRM is used to get the BIOS on the discrete cards in 168 * dual-gpu systems. 169 */ 170 /* retrieve the ROM in 4k blocks */ 171 #define ATRM_BIOS_PAGE 4096 172 /** 173 * amdgpu_atrm_call - fetch a chunk of the vbios 174 * 175 * @atrm_handle: acpi ATRM handle 176 * @bios: vbios image pointer 177 * @offset: offset of vbios image data to fetch 178 * @len: length of vbios image data to fetch 179 * 180 * Executes ATRM to fetch a chunk of the discrete 181 * vbios image on PX systems (all asics). 182 * Returns the length of the buffer fetched. 183 */ 184 static int amdgpu_atrm_call(acpi_handle atrm_handle, uint8_t *bios, 185 int offset, int len) 186 { 187 acpi_status status; 188 union acpi_object atrm_arg_elements[2], *obj; 189 struct acpi_object_list atrm_arg; 190 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL}; 191 192 atrm_arg.count = 2; 193 atrm_arg.pointer = &atrm_arg_elements[0]; 194 195 atrm_arg_elements[0].type = ACPI_TYPE_INTEGER; 196 atrm_arg_elements[0].integer.value = offset; 197 198 atrm_arg_elements[1].type = ACPI_TYPE_INTEGER; 199 atrm_arg_elements[1].integer.value = len; 200 201 status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer); 202 if (ACPI_FAILURE(status)) { 203 printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status)); 204 return -ENODEV; 205 } 206 207 obj = (union acpi_object *)buffer.pointer; 208 memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); 209 len = obj->buffer.length; 210 kfree(buffer.pointer); 211 return len; 212 } 213 214 static bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) 215 { 216 int ret; 217 int size = 256 * 1024; 218 int i; 219 struct pci_dev *pdev = NULL; 220 acpi_handle dhandle, atrm_handle; 221 acpi_status status; 222 bool found = false; 223 224 /* ATRM is for the discrete card only */ 225 if (adev->flags & AMD_IS_APU) 226 return false; 227 228 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) { 229 dhandle = ACPI_HANDLE(&pdev->dev); 230 if (!dhandle) 231 continue; 232 233 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); 234 if (!ACPI_FAILURE(status)) { 235 found = true; 236 break; 237 } 238 } 239 240 if (!found) { 241 while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { 242 dhandle = ACPI_HANDLE(&pdev->dev); 243 if (!dhandle) 244 continue; 245 246 status = acpi_get_handle(dhandle, "ATRM", &atrm_handle); 247 if (!ACPI_FAILURE(status)) { 248 found = true; 249 break; 250 } 251 } 252 } 253 254 if (!found) 255 return false; 256 257 adev->bios = kmalloc(size, GFP_KERNEL); 258 if (!adev->bios) { 259 DRM_ERROR("Unable to allocate bios\n"); 260 return false; 261 } 262 263 for (i = 0; i < size / ATRM_BIOS_PAGE; i++) { 264 ret = amdgpu_atrm_call(atrm_handle, 265 adev->bios, 266 (i * ATRM_BIOS_PAGE), 267 ATRM_BIOS_PAGE); 268 if (ret < ATRM_BIOS_PAGE) 269 break; 270 } 271 272 if (i == 0 || !AMD_IS_VALID_VBIOS(adev->bios)) { 273 kfree(adev->bios); 274 return false; 275 } 276 return true; 277 } 278 #else 279 static inline bool amdgpu_atrm_get_bios(struct amdgpu_device *adev) 280 { 281 return false; 282 } 283 #endif 284 285 static bool amdgpu_read_disabled_bios(struct amdgpu_device *adev) 286 { 287 if (adev->flags & AMD_IS_APU) 288 return igp_read_bios_from_vram(adev); 289 else 290 return amdgpu_asic_read_disabled_bios(adev); 291 } 292 293 #ifdef CONFIG_ACPI 294 static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) 295 { 296 bool ret = false; 297 struct acpi_table_header *hdr; 298 acpi_size tbl_size; 299 UEFI_ACPI_VFCT *vfct; 300 GOP_VBIOS_CONTENT *vbios; 301 VFCT_IMAGE_HEADER *vhdr; 302 303 if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size))) 304 return false; 305 if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { 306 DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); 307 goto out_unmap; 308 } 309 310 vfct = (UEFI_ACPI_VFCT *)hdr; 311 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) { 312 DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); 313 goto out_unmap; 314 } 315 316 vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset); 317 vhdr = &vbios->VbiosHeader; 318 DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n", 319 vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction, 320 vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength); 321 322 if (vhdr->PCIBus != adev->pdev->bus->number || 323 vhdr->PCIDevice != PCI_SLOT(adev->pdev->devfn) || 324 vhdr->PCIFunction != PCI_FUNC(adev->pdev->devfn) || 325 vhdr->VendorID != adev->pdev->vendor || 326 vhdr->DeviceID != adev->pdev->device) { 327 DRM_INFO("ACPI VFCT table is not for this card\n"); 328 goto out_unmap; 329 } 330 331 if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) { 332 DRM_ERROR("ACPI VFCT image truncated\n"); 333 goto out_unmap; 334 } 335 336 adev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); 337 ret = !!adev->bios; 338 339 out_unmap: 340 return ret; 341 } 342 #else 343 static inline bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev) 344 { 345 return false; 346 } 347 #endif 348 349 bool amdgpu_get_bios(struct amdgpu_device *adev) 350 { 351 bool r; 352 uint16_t tmp; 353 354 r = amdgpu_atrm_get_bios(adev); 355 if (r == false) 356 r = amdgpu_acpi_vfct_bios(adev); 357 if (r == false) 358 r = igp_read_bios_from_vram(adev); 359 if (r == false) 360 r = amdgpu_read_bios(adev); 361 if (r == false) { 362 r = amdgpu_read_bios_from_rom(adev); 363 } 364 if (r == false) { 365 r = amdgpu_read_disabled_bios(adev); 366 } 367 if (r == false) { 368 r = amdgpu_read_platform_bios(adev); 369 } 370 if (r == false || adev->bios == NULL) { 371 DRM_ERROR("Unable to locate a BIOS ROM\n"); 372 adev->bios = NULL; 373 return false; 374 } 375 if (!AMD_IS_VALID_VBIOS(adev->bios)) { 376 printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]); 377 goto free_bios; 378 } 379 380 tmp = RBIOS16(0x18); 381 if (RBIOS8(tmp + 0x14) != 0x0) { 382 DRM_INFO("Not an x86 BIOS ROM, not using.\n"); 383 goto free_bios; 384 } 385 386 adev->bios_header_start = RBIOS16(0x48); 387 if (!adev->bios_header_start) { 388 goto free_bios; 389 } 390 tmp = adev->bios_header_start + 4; 391 if (!memcmp(adev->bios + tmp, "ATOM", 4) || 392 !memcmp(adev->bios + tmp, "MOTA", 4)) { 393 adev->is_atom_bios = true; 394 } else { 395 adev->is_atom_bios = false; 396 } 397 398 DRM_DEBUG("%sBIOS detected\n", adev->is_atom_bios ? "ATOM" : "COM"); 399 return true; 400 free_bios: 401 kfree(adev->bios); 402 adev->bios = NULL; 403 return false; 404 } 405