From 38f17b01cece5c144889985a64d3f155409cc713 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Wed, 28 Sep 2016 15:46:14 -0500 Subject: [PATCH] radeon_hd: Polaris10 power distribution fix * Helps prevent mainboard explosions and other bad stuff. * ...maybe not explosions, but bad things. * The RX 480 reference design can pull as much as 90W from its PCIe slot at load. PCIe is rated for 75W. * This change overloads the PCIe power cables vs the PCIe slot. The PCIe power cables can handle going over spec. * Untested since we really can't come close to loading a RX 480 without hardware OpenGL ^_^ * Should be able to test on real hardware within a week. --- .../private/graphics/radeon_hd/radeon_hd.h | 3 +- .../accelerants/radeon_hd/accelerant.cpp | 3 ++ src/add-ons/accelerants/radeon_hd/gpu.cpp | 43 +++++++++++++++++++ src/add-ons/accelerants/radeon_hd/gpu.h | 8 +++- .../drivers/graphics/radeon_hd/radeon_hd.cpp | 1 + 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/headers/private/graphics/radeon_hd/radeon_hd.h b/headers/private/graphics/radeon_hd/radeon_hd.h index a832b1d1c2..6583df4826 100644 --- a/headers/private/graphics/radeon_hd/radeon_hd.h +++ b/headers/private/graphics/radeon_hd/radeon_hd.h @@ -190,7 +190,8 @@ struct overlay_registers; struct radeon_shared_info { uint32 deviceIndex; // accelerant index - uint32 pciID; // device pciid + uint32 pciID; // device pci id + uint32 pciRev; // device pci revision area_id mode_list_area; // area containing display mode list uint32 mode_count; diff --git a/src/add-ons/accelerants/radeon_hd/accelerant.cpp b/src/add-ons/accelerants/radeon_hd/accelerant.cpp index 199b193d43..727a3ca38a 100644 --- a/src/add-ons/accelerants/radeon_hd/accelerant.cpp +++ b/src/add-ons/accelerants/radeon_hd/accelerant.cpp @@ -258,6 +258,9 @@ radeon_init_accelerant(int device) // probe firmware information radeon_gpu_probe(); + // apply GPU quirks + radeon_gpu_quirks(); + // find GPIO pins from AtomBIOS gpio_populate(); diff --git a/src/add-ons/accelerants/radeon_hd/gpu.cpp b/src/add-ons/accelerants/radeon_hd/gpu.cpp index 3cd4e3b124..7c93559dc2 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.cpp +++ b/src/add-ons/accelerants/radeon_hd/gpu.cpp @@ -223,6 +223,49 @@ radeon_gpu_reset() } +status_t +radeon_gpu_quirks() +{ + radeon_shared_info &info = *gInfo->shared_info; + + // Fix PCIe power distribution issue for Polaris10 XT + // aka "Card draws >75W from PCIe bus" + if (info.chipsetID == RADEON_POLARIS && info.pciRev == 0xc7) { + ERROR("%s: Applying Polaris10 power distribution fix.\n", + __func__); + radeon_gpu_i2c_cmd(0x10, 0x96, 0x1e, 0xdd); + radeon_gpu_i2c_cmd(0x10, 0x96, 0x1f, 0xd0); + } + + return B_OK; +} + + +status_t +radeon_gpu_i2c_cmd(uint16 slaveAddr, uint16 lineNumber, uint8 offset, + uint8 data) +{ + TRACE("%s\n", __func__); + + PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; + memset(&args, 0, sizeof(args)); + + int index = GetIndexIntoMasterTable(COMMAND, + ProcessI2cChannelTransaction); + + args.ucRegIndex = offset; + args.lpI2CDataOut = data; + args.ucFlag = HW_I2C_WRITE; + args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; + args.ucTransBytes = 1; + args.ucSlaveAddr = slaveAddr; + args.ucLineNumber = lineNumber; + + atom_execute_table(gAtomContext, index, (uint32*)&args); + return B_OK; +} + + void radeon_gpu_mc_halt(gpu_state* gpuState) { diff --git a/src/add-ons/accelerants/radeon_hd/gpu.h b/src/add-ons/accelerants/radeon_hd/gpu.h index d39d7a4ca8..80c4fc140f 100644 --- a/src/add-ons/accelerants/radeon_hd/gpu.h +++ b/src/add-ons/accelerants/radeon_hd/gpu.h @@ -165,9 +165,16 @@ #define SOFT_RESET_VGT (1 << 14) #define SOFT_RESET_IA (1 << 15) +#define TARGET_HW_I2C_CLOCK 50 status_t radeon_gpu_probe(); status_t radeon_gpu_reset(); +status_t radeon_gpu_quirks(); + +status_t radeon_gpu_i2c_cmd(uint16 slaveAddr, uint16 lineNumber, uint8 offset, + uint8 data); + + void radeon_gpu_mc_halt(struct gpu_state *gpuState); void radeon_gpu_mc_resume(struct gpu_state *gpuState); status_t radeon_gpu_mc_idlewait(); @@ -177,5 +184,4 @@ status_t radeon_gpu_ring_boot(uint32 ringType); status_t radeon_gpu_ss_control(pll_info* pll, bool enable); - #endif diff --git a/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp b/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp index 5769b112cc..ceac6c82da 100644 --- a/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp +++ b/src/add-ons/kernel/drivers/graphics/radeon_hd/radeon_hd.cpp @@ -650,6 +650,7 @@ radeon_hd_init(radeon_info &info) // Pass common information to accelerant info.shared_info->deviceIndex = info.id; info.shared_info->pciID = info.pciID; + info.shared_info->pciRev = info.pci->revision; info.shared_info->chipsetID = info.chipsetID; info.shared_info->chipsetFlags = info.chipsetFlags; info.shared_info->dceMajor = info.dceMajor;