Add support for IT87952E EC on Gigabyte boards (#1091)

* Rename IT8795E to IT87952E

IT8795E and IT87952E are distinct chips (with their own IC markings).
The IT8795E, as the IT8791E and IT8792E, reports chip ID 0x8733 whereas
the IT87952E identifies as 0x8695.

* Gigabyte EC: Fix typo in LPC register restore

When the AMD LPC Bridge registers are restored after configuring memory
mapping, restore the correct value for the "Memory Address for LPC
target cycles" register.

* Add IT87952E fan control for Gigabyte boards

IT87952E (ID 0x8695) has a third byte in SuperIO config space
(LDN 0x0F) that determines more bits of the host address for LPC memory
mapping.

Also the base address for Gigabyte boards is 0xFC000000 instead of
0xFF000000 (as is the case with IT8790/1/2/5).
This should make additional fan controls work on Gigabyte mainboards
where the settings had no effect previously, e.g: X570S AORUS MASTER
and X670E AORUS MASTER. (cf. Issue #251)
It does not yet work for Intel boards as the LPC bridge requires
different programming.

* Update LpcIO.cs

---------

Co-authored-by: PhyxionNL <7643972+PhyxionNL@users.noreply.github.com>
This commit is contained in:
Maximilian Rehkopf
2023-06-13 13:44:24 +02:00
committed by GitHub
co-authored by PhyxionNL
parent e9d091cc88
commit 701e8ad514
5 changed files with 29 additions and 14 deletions
@@ -48,8 +48,8 @@ internal enum Chip : ushort
IT8771E = 0x8771,
IT8772E = 0x8772,
IT8790E = 0x8790,
IT8792E = 0x8733, // Could also be IT8791E
IT8795E = 0x8695,
IT8792E = 0x8733, // Could also be IT8791E, IT8795E
IT87952E = 0x8695,
NCT610XD = 0xC452,
NCT6771F = 0xB470,
@@ -120,8 +120,8 @@ internal class ChipName
case Chip.IT8771E: return "ITE IT8771E";
case Chip.IT8772E: return "ITE IT8772E";
case Chip.IT8790E: return "ITE IT8790E";
case Chip.IT8792E: return "ITE IT8791E/IT8792E";
case Chip.IT8795E: return "ITE IT8795E";
case Chip.IT8792E: return "ITE IT8791E/IT8792E/IT8795E";
case Chip.IT87952E: return "ITE IT87952E";
case Chip.NCT610XD: return "Nuvoton NCT6102D/NCT6104D/NCT6106D";
case Chip.NCT6771F: return "Nuvoton NCT6771F";
@@ -95,7 +95,7 @@ internal class GigabyteController
if (!originalMmIoEnabled)
{
Ring0.WritePciConfig(amdIsaBridgeAddress, ioOrMemoryPortDecodeEnableRegister, originalDecodeEnableRegister);
Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, originalRomAddressRegister);
Ring0.WritePciConfig(amdIsaBridgeAddress, pciMemoryAddressForLpcTargetCyclesRegister, originalPciMemoryAddressRegister);
Ring0.WritePciConfig(amdIsaBridgeAddress, romAddressRange2Register, originalRomAddressRegister);
}
@@ -88,7 +88,7 @@ internal class IT87XX : ISuperIO
Chip.IT8686E or
Chip.IT8688E or
Chip.IT8689E or
Chip.IT8795E or
Chip.IT87952E or
Chip.IT8628E or
Chip.IT8625E or
Chip.IT8620E or
@@ -148,7 +148,7 @@ internal class IT87XX : ISuperIO
Controls = new float?[6];
break;
case Chip.IT8795E:
case Chip.IT87952E:
Voltages = new float?[6];
Temperatures = new float?[3];
Fans = new float?[3];
@@ -191,7 +191,7 @@ internal class IT87XX : ISuperIO
_voltageGain = chip switch
{
Chip.IT8613E or Chip.IT8620E or Chip.IT8628E or Chip.IT8631E or Chip.IT8721F or Chip.IT8728F or Chip.IT8771E or Chip.IT8772E or Chip.IT8686E or Chip.IT8688E or Chip.IT8689E => 0.012f,
Chip.IT8625E or Chip.IT8792E or Chip.IT8795E => 0.011f,
Chip.IT8625E or Chip.IT8792E or Chip.IT87952E => 0.011f,
Chip.IT8655E or Chip.IT8665E => 0.0109f,
_ => 0.016f
};
@@ -1,4 +1,4 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright (C) LibreHardwareMonitor and Contributors.
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
@@ -563,7 +563,7 @@ internal class LpcIO
0x8772 => Chip.IT8772E,
0x8790 => Chip.IT8790E,
0x8733 => Chip.IT8792E,
0x8695 => Chip.IT8795E,
0x8695 => Chip.IT87952E,
_ => Chip.Unknown
};
@@ -642,7 +642,7 @@ internal class LpcIO
// The controller only affects the 2nd ITE chip if present, and only a few
// models are known to use this controller.
// IT8795E likely to need this too, but may use different registers.
if (motherboard.Manufacturer != Manufacturer.Gigabyte || port.RegisterPort != 0x4E || chip is not (Chip.IT8790E or Chip.IT8792E))
if (motherboard.Manufacturer != Manufacturer.Gigabyte || port.RegisterPort != 0x4E || chip is not (Chip.IT8790E or Chip.IT8792E or Chip.IT87952E))
return null;
port.Select(IT87XX_SMFI_LDN);
@@ -657,15 +657,29 @@ internal class LpcIO
return null;
// Read the host RAM address that maps to the Embedded Controller's RAM (two registers).
uint addressHi = 0;
uint addressHiVerify = 0;
uint address = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER);
if (chip == Chip.IT87952E)
addressHi = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH);
Thread.Sleep(1);
uint addressVerify = port.ReadWord(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER);
if (chip == Chip.IT87952E)
addressHiVerify = port.ReadByte(IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH);
if (address != addressVerify)
if ((address != addressVerify) || (addressHi != addressHiVerify))
return null;
// Address is xryy, Host Address is FFyyx000
uint hostAddress = 0xFF000000 | (address & 0xF000) | (address & 0xFF) << 0x10;
// For IT87952E, Address is rzxryy, Host Address is (0xFC000000 | 0x0zyyx000)
uint hostAddress;
if (chip == Chip.IT87952E)
hostAddress = 0xFC000000;
else
hostAddress = 0xFF000000;
hostAddress |= (address & 0xF000) | ((address & 0xFF) << 16) | ((addressHi & 0xF) << 24);
return new GigabyteController(hostAddress, DetectVendor());
@@ -702,6 +716,7 @@ internal class LpcIO
private const byte FINTEK_VENDOR_ID_REGISTER = 0x23;
private const byte IT87_CHIP_VERSION_REGISTER = 0x22;
private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER = 0xF5;
private const byte IT87_SMFI_HLPC_RAM_BASE_ADDRESS_REGISTER_HIGH = 0xFC;
private const byte IT87_LD_ACTIVE_REGISTER = 0x30;
private readonly ushort[] REGISTER_PORTS = { 0x2E, 0x4E };
@@ -233,7 +233,7 @@ internal sealed class SuperIOHardware : Hardware
GetIteConfigurationsB(superIO, manufacturer, model, v, t, f, c);
break;
case Chip.IT8795E:
case Chip.IT87952E:
case Chip.IT8792E:
case Chip.IT8790E:
GetIteConfigurationsC(superIO, manufacturer, model, v, t, f, c);