/* If you boot an IGP board with a discrete card as the primary, * the IGP rom is not accessible via the rom bar as the IGP rom is * part of the system bios. On boot, the system bios puts a * copy of the igp rom at the start of vram if a discrete card is * present. */ static bool igp_read_bios_from_vram(struct radeon_device *rdev) { uint8_t __iomem *bios; resource_size_t vram_base; resource_size_t size = 256 * 1024; /* ??? */ if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) return false; rdev->bios = NULL; vram_base = pci_resource_start(rdev->pdev, 0); bios = ioremap(vram_base, size); if (!bios) { return false; } if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { iounmap(bios); return false; } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) { iounmap(bios); return false; } memcpy_fromio(rdev->bios, bios, size); iounmap(bios); return true; }
static bool igp_read_bios_from_vram(struct radeon_device *rdev) { uint8_t __iomem *bios; bus_size_t size = 256 * 1024; /* ??? */ bus_space_handle_t bsh; bus_space_tag_t bst = rdev->memt; if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) return false; rdev->bios = NULL; if (bus_space_map(bst, rdev->fb_aper_offset, size, BUS_SPACE_MAP_LINEAR, &bsh) != 0) return false; bios = bus_space_vaddr(rdev->memt, bsh); if (bios == NULL) { bus_space_unmap(bst, bsh, size); return false; } if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { bus_space_unmap(bst, bsh, size); return false; } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) { bus_space_unmap(bst, bsh, size); return false; } memcpy_fromio(rdev->bios, bios, size); bus_space_unmap(bst, bsh, size); return true; }
/* If you boot an IGP board with a discrete card as the primary, * the IGP rom is not accessible via the rom bar as the IGP rom is * part of the system bios. On boot, the system bios puts a * copy of the igp rom at the start of vram if a discrete card is * present. */ static bool igp_read_bios_from_vram(struct radeon_device *rdev) { struct drm_local_map bios_map; uint8_t __iomem *bios; resource_size_t vram_base; resource_size_t size = 256 * 1024; /* ??? */ DRM_INFO("%s: ===> Try IGP's VRAM...\n", __func__); if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) { DRM_INFO("%s: not POSTed discrete card detected, skipping this method...\n", __func__); return false; } rdev->bios = NULL; vram_base = drm_get_resource_start(rdev->ddev, 0); DRM_INFO("%s: VRAM base address: 0x%jx\n", __func__, (uintmax_t)vram_base); bios_map.offset = vram_base; bios_map.size = size; bios_map.type = 0; bios_map.flags = 0; bios_map.mtrr = 0; drm_core_ioremap(&bios_map, rdev->ddev); if (bios_map.handle == NULL) { DRM_INFO("%s: failed to ioremap\n", __func__); return false; } bios = bios_map.handle; size = bios_map.size; DRM_INFO("%s: Map address: %p (%ju bytes)\n", __func__, bios, (uintmax_t)size); if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { if (size == 0) { DRM_INFO("%s: Incorrect BIOS size\n", __func__); } else { DRM_INFO("%s: Incorrect BIOS signature: 0x%02X%02X\n", __func__, bios[0], bios[1]); } drm_core_ioremapfree(&bios_map, rdev->ddev); return false; } rdev->bios = malloc(size, DRM_MEM_DRIVER, M_NOWAIT); if (rdev->bios == NULL) { drm_core_ioremapfree(&bios_map, rdev->ddev); return false; } memcpy_fromio(rdev->bios, bios, size); drm_core_ioremapfree(&bios_map, rdev->ddev); return true; }
/* If you boot an IGP board with a discrete card as the primary, * the IGP rom is not accessible via the rom bar as the IGP rom is * part of the system bios. On boot, the system bios puts a * copy of the igp rom at the start of vram if a discrete card is * present. */ static bool igp_read_bios_from_vram(struct radeon_device *rdev) { uint8_t __iomem *bios; resource_size_t vram_base; resource_size_t size = 256 * 1024; /* ??? */ if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) return false; rdev->bios = NULL; <<<<<<< HEAD
static bool radeon_read_platform_bios(struct radeon_device *rdev) { #if defined(__amd64__) || defined(__i386__) || defined(__loongson__) uint8_t __iomem *bios; bus_size_t size = 256 * 1024; /* ??? */ uint8_t *found = NULL; int i; if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) return false; rdev->bios = NULL; #if defined(__loongson__) if (loongson_videobios == NULL) return false; bios = loongson_videobios; #else bios = (u8 *)ISA_HOLE_VADDR(0xc0000); #endif for (i = 0; i + 2 < size; i++) { if (bios[i] == 0x55 && bios[i + 1] == 0xaa) { found = bios + i; break; } } if (found == NULL) { DRM_ERROR("bios size zero or checksum mismatch\n"); return false; } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) return false; memcpy(rdev->bios, found, size); return true; #endif return false; }
/* Plan is to move initialization in that function and use * helper function so that radeon_device_init pretty much * do nothing more than calling asic specific function. This * should also allow to remove a bunch of callback function * like vram_info. */ int cayman_init(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r; /* Read BIOS */ if (!radeon_get_bios(rdev)) { if (ASIC_IS_AVIVO(rdev)) return -EINVAL; } /* Must be an ATOMBIOS */ if (!rdev->is_atom_bios) { dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); return -EINVAL; } r = radeon_atombios_init(rdev); if (r) return r; /* Post card if necessary */ if (!radeon_card_posted(rdev)) { if (!rdev->bios) { dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); return -EINVAL; } DRM_INFO("GPU not posted. posting now...\n"); atom_asic_init(rdev->mode_info.atom_context); } /* Initialize scratch registers */ r600_scratch_init(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); /* Fence driver */ r = radeon_fence_driver_init(rdev); if (r) return r; /* initialize memory controller */ r = evergreen_mc_init(rdev); if (r) return r; /* Memory manager */ r = radeon_bo_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); if (r) return r; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); r = r600_pcie_gart_init(rdev); if (r) return r; r = radeon_ib_pool_init(rdev); rdev->accel_working = true; if (r) { dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; } r = radeon_vm_manager_init(rdev); if (r) { dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); } r = cayman_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); cayman_cp_fini(rdev); r600_irq_fini(rdev); if (rdev->flags & RADEON_IS_IGP) si_rlc_fini(rdev); radeon_wb_fini(rdev); r100_ib_fini(rdev); radeon_vm_manager_fini(rdev); radeon_irq_kms_fini(rdev); cayman_pcie_gart_fini(rdev); rdev->accel_working = false; } /* Don't start up if the MC ucode is missing. * The default clocks and voltages before the MC ucode * is loaded are not suffient for advanced operations. * * We can skip this check for TN, because there is no MC * ucode. */ if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { DRM_ERROR("radeon: MC ucode required for NI+.\n"); return -EINVAL; } return 0; }