bool amdgpu_get_bios(struct amdgpu_device *adev) { bool r; uint16_t tmp, bios_header_start; r = amdgpu_atrm_get_bios(adev); if (r == false) r = amdgpu_acpi_vfct_bios(adev); if (r == false) r = igp_read_bios_from_vram(adev); if (r == false) r = amdgpu_read_bios(adev); if (r == false) { r = amdgpu_read_bios_from_rom(adev); } if (r == false) { r = amdgpu_read_disabled_bios(adev); } if (r == false) { r = amdgpu_read_platform_bios(adev); } if (r == false || adev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); adev->bios = NULL; return false; } if (!AMD_IS_VALID_VBIOS(adev->bios)) { printk("BIOS signature incorrect %x %x\n", adev->bios[0], adev->bios[1]); goto free_bios; } tmp = RBIOS16(0x18); if (RBIOS8(tmp + 0x14) != 0x0) { DRM_INFO("Not an x86 BIOS ROM, not using.\n"); goto free_bios; } bios_header_start = RBIOS16(0x48); if (!bios_header_start) { goto free_bios; } tmp = bios_header_start + 4; if (!memcmp(adev->bios + tmp, "ATOM", 4) || !memcmp(adev->bios + tmp, "MOTA", 4)) { adev->is_atom_bios = true; } else { adev->is_atom_bios = false; } DRM_DEBUG("%sBIOS detected\n", adev->is_atom_bios ? "ATOM" : "COM"); return true; free_bios: kfree(adev->bios); adev->bios = NULL; return false; }
bool radeon_get_bios(struct radeon_device *rdev) { bool r; uint16_t tmp; r = radeon_atrm_get_bios(rdev); if (r == false) r = radeon_acpi_vfct_bios(rdev); if (r == false) r = igp_read_bios_from_vram(rdev); if (r == false) r = radeon_read_bios(rdev); if (r == false) { r = radeon_read_disabled_bios(rdev); } if (r == false) { r = radeon_read_platform_bios(rdev); } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; return false; } if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { printk("BIOS signature incorrect %x %x\n", rdev->bios[0], rdev->bios[1]); goto free_bios; } tmp = RBIOS16(0x18); if (RBIOS8(tmp + 0x14) != 0x0) { DRM_INFO("Not an x86 BIOS ROM, not using.\n"); goto free_bios; } rdev->bios_header_start = RBIOS16(0x48); if (!rdev->bios_header_start) { goto free_bios; } tmp = rdev->bios_header_start + 4; if (!memcmp(rdev->bios + tmp, "ATOM", 4) || !memcmp(rdev->bios + tmp, "MOTA", 4)) { rdev->is_atom_bios = true; } else { rdev->is_atom_bios = false; } DRM_DEBUG("%sBIOS detected\n", rdev->is_atom_bios ? "ATOM" : "COM"); return true; free_bios: kfree(rdev->bios); rdev->bios = NULL; return false; }
bool radeon_get_bios(struct radeon_device *rdev) { bool r; uint16_t tmp; if (rdev->flags & RADEON_IS_IGP) { r = igp_read_bios_from_vram(rdev); if (r == false) r = radeon_read_bios(rdev); } else r = radeon_read_bios(rdev); if (r == false) { r = radeon_read_disabled_bios(rdev); } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; return false; } if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) { goto free_bios; } rdev->bios_header_start = RBIOS16(0x48); if (!rdev->bios_header_start) { goto free_bios; } tmp = rdev->bios_header_start + 4; if (!memcmp(rdev->bios + tmp, "ATOM", 4) || !memcmp(rdev->bios + tmp, "MOTA", 4)) { rdev->is_atom_bios = true; } else { rdev->is_atom_bios = false; } DRM_DEBUG("%sBIOS detected\n", rdev->is_atom_bios ? "ATOM" : "COM"); return true; free_bios: kfree(rdev->bios); rdev->bios = NULL; return false; }
bool RadeonMonitor::start(IOService * provider) { HWSensorsDebugLog("Starting..."); if (!super::start(provider)) return false; if (!(card.pdev = (IOPCIDevice*)provider)) return false; if (OSData *data = OSDynamicCast(OSData, provider->getProperty("device-id"))) { card.chip_id = *(UInt32*)data->getBytesNoCopy(); } else { HWSensorsFatalLog("device-id property not found"); return false; } card.pdev->setMemoryEnable(true); for (UInt32 i = 0; (card.mmio = card.pdev->mapDeviceMemoryWithIndex(i)); i++) { long unsigned int mmio_base_phys = card.mmio->getPhysicalAddress(); // Make sure we select MMIO registers if (((card.mmio->getLength()) <= 0x00020000) && (mmio_base_phys != 0)) break; } if (!card.mmio) { HWSensorsInfoLog("failed to map device memory"); return false; } card.family = CHIP_FAMILY_UNKNOW; card.int_thermal_type = THERMAL_TYPE_NONE; card.card_index = takeVacantGPUIndex(); if (card.card_index < 0) { radeon_fatal(&card, "failed to obtain vacant GPU index\n"); return false; } RADEONCardInfo *devices = RADEONCards; while (devices->device_id != NULL) { if ((devices->device_id & 0xffff) == (card.chip_id & 0xffff)) { card.family = devices->ChipFamily; card.info.device_id = devices->device_id; card.info.ChipFamily = devices->ChipFamily; card.info.igp = devices->igp; card.info.is_mobility = devices->is_mobility; radeon_info(&card, "found ATI Radeon 0x%04x\n", card.chip_id & 0xffff); break; } devices++; } if (card.family == CHIP_FAMILY_UNKNOW) { radeon_fatal(&card, "unknown card 0x%04x\n", card.chip_id & 0xffff); //return false; } //try to load bios from ATY,bin_image property of GPU registry node if (OSData *vbios = OSDynamicCast(OSData, provider->getProperty("ATY,bin_image"))) { card.bios_size = vbios->getLength(); card.bios = (UInt8*)IOMalloc(vbios->getLength()); memcpy(card.bios, vbios->getBytesNoCopy(), card.bios_size); if (card.bios[0] == 0x55 && card.bios[1] == 0xaa) { radeon_device *rdev = &card; UInt16 tmp = RBIOS16(0x18); if (RBIOS8(tmp + 0x14) == 0x0) { if ((card.bios_header_start = RBIOS16(0x48))) { tmp = card.bios_header_start + 4; if (!memcmp(card.bios + tmp, "ATOM", 4) || !memcmp(card.bios + tmp, "MOTA", 4)) { card.is_atom_bios = true; } else { card.is_atom_bios = false; } radeon_info(&card, "%sBIOS detected\n", card.is_atom_bios ? "ATOM" : "COM"); } } else radeon_error(&card, "not an x86 BIOS ROM, not using\n"); } else radeon_error(&card, "BIOS signature incorrect %x %x\n", card.bios[0], card.bios[1]); } else radeon_error(&card, "unable to locate ATY,bin_image\n"); if (!card.bios_header_start) { // Free memory for bios image if it was allocated if (card.bios && card.bios_size) { IOFree(card.bios, card.bios_size); card.bios = 0; card.bios_size = 0; } } else if (atom_parse(&card)) { radeon_atombios_get_power_modes(&card); } // Use temperature sensor type based on BIOS name if (card.int_thermal_type == THERMAL_TYPE_NONE && card.bios && card.bios_size) { if (!strncasecmp("R600", card.bios_name, 64) || !strncasecmp("RV610", card.bios_name, 64) || !strncasecmp("RV630", card.bios_name, 64) || !strncasecmp("RV620", card.bios_name, 64) || !strncasecmp("RV635", card.bios_name, 64) || !strncasecmp("RV670", card.bios_name, 64) || !strncasecmp("RS780", card.bios_name, 64) || !strncasecmp("RS880", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_RV6XX; } else if (!strncasecmp("RV770", card.bios_name, 64) || !strncasecmp("RV730", card.bios_name, 64) || !strncasecmp("RV710", card.bios_name, 64) || !strncasecmp("RV740", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_RV770; } else if (!strncasecmp("CEDAR", card.bios_name, 64) || !strncasecmp("REDWOOD", card.bios_name, 64) || !strncasecmp("JUNIPER", card.bios_name, 64) || !strncasecmp("CYPRESS", card.bios_name, 64) || !strncasecmp("PALM", card.bios_name, 64) || !strncasecmp("Wrestler", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_EVERGREEN; } else if (!strncasecmp("SUMO", card.bios_name, 64) || !strncasecmp("SUMO2", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_SUMO; } else if (!strncasecmp("ARUBA", card.bios_name, 64) || !strncasecmp("BARTS", card.bios_name, 64) || !strncasecmp("TURKS", card.bios_name, 64) || !strncasecmp("CAICOS", card.bios_name, 64) || !strncasecmp("CAYMAN", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_NI; } else if (!strncasecmp("CAPE VERDE", card.bios_name, 64) || !strncasecmp("PITCAIRN", card.bios_name, 64) || !strncasecmp("TAHITI", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_SI; } } // Use driver's configuration to resolve temperature sensor type if (card.int_thermal_type == THERMAL_TYPE_NONE) { radeon_info(&card, "using device-id to resolve temperature sensor type\n"); // Enable temperature monitoring switch (card.family) { case CHIP_FAMILY_R600: /* r600 */ case CHIP_FAMILY_RV610: case CHIP_FAMILY_RV630: case CHIP_FAMILY_RV670: case CHIP_FAMILY_RV620: case CHIP_FAMILY_RV635: case CHIP_FAMILY_RS780: case CHIP_FAMILY_RS880: card.int_thermal_type = THERMAL_TYPE_RV6XX; break; case CHIP_FAMILY_RV770: /* r700 */ case CHIP_FAMILY_RV730: case CHIP_FAMILY_RV710: case CHIP_FAMILY_RV740: card.int_thermal_type = THERMAL_TYPE_RV770; break; case CHIP_FAMILY_CEDAR: /* evergreen */ case CHIP_FAMILY_REDWOOD: case CHIP_FAMILY_JUNIPER: case CHIP_FAMILY_CYPRESS: case CHIP_FAMILY_HEMLOCK: case CHIP_FAMILY_PALM: card.int_thermal_type = THERMAL_TYPE_EVERGREEN; break; case CHIP_FAMILY_BARTS: case CHIP_FAMILY_TURKS: case CHIP_FAMILY_CAICOS: case CHIP_FAMILY_CAYMAN: case CHIP_FAMILY_ARUBA: card.int_thermal_type = THERMAL_TYPE_NI; break; case CHIP_FAMILY_SUMO: case CHIP_FAMILY_SUMO2: card.int_thermal_type = THERMAL_TYPE_SUMO; break; case CHIP_FAMILY_TAHITI: case CHIP_FAMILY_PITCAIRN: case CHIP_FAMILY_VERDE: card.int_thermal_type = THERMAL_TYPE_SI; break; // default: // radeon_fatal(&card, "card 0x%04x is unsupported\n", card.chip_id & 0xffff); // return false; } } // Setup temperature sensor if (card.int_thermal_type != THERMAL_TYPE_NONE ) { switch (card.int_thermal_type) { case THERMAL_TYPE_RV6XX: card.get_core_temp = rv6xx_get_temp; radeon_info(&card, "adding rv6xx thermal sensor\n"); break; case THERMAL_TYPE_RV770: card.get_core_temp = rv770_get_temp; radeon_info(&card, "adding rv770 thermal sensor\n"); break; case THERMAL_TYPE_EVERGREEN: case THERMAL_TYPE_NI: card.get_core_temp = evergreen_get_temp; radeon_info(&card, "adding EverGreen thermal sensor\n"); break; case THERMAL_TYPE_SUMO: card.get_core_temp = sumo_get_temp; radeon_info(&card, "adding Sumo thermal sensor\n"); break; case THERMAL_TYPE_SI: card.get_core_temp = si_get_temp; radeon_info(&card, "adding Southern Islands thermal sensor\n"); break; default: radeon_fatal(&card, "card 0x%04x is unsupported\n", card.chip_id & 0xffff); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } } if (card.get_core_temp) { char key[5]; snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); if (!addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, 0)) { //radeon_error(&card, "failed to register temperature sensor for key %s\n", key); radeon_fatal(&card, "failed to register temperature sensor for key %s\n", key); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } } registerService(); return true; }