Skip to content

Commit

Permalink
Add AMD support (#530)
Browse files Browse the repository at this point in the history
  • Loading branch information
VisualEhrmanntraut committed Jun 24, 2023
1 parent 17a5f58 commit f9f703b
Show file tree
Hide file tree
Showing 10 changed files with 241 additions and 84 deletions.
19 changes: 19 additions & 0 deletions VoodooI2C/VoodooI2C/Info.plist
Expand Up @@ -491,6 +491,25 @@
<key>IOProviderClass</key>
<string>IOService</string>
</dict>
<key>VoodooI2CACPIControllerAMD</key>
<dict>
<key>AccessIntrMaskWorkaround</key>
<true/>
<key>CFBundleIdentifier</key>
<string>com.alexandred.VoodooI2C</string>
<key>IOClass</key>
<string>VoodooI2CACPIController</string>
<key>IONameMatch</key>
<array>
<string>AMD0010</string>
<string>AMDI0010</string>
<string>AMDI0510</string>
</array>
<key>IOProbeScore</key>
<integer>9999</integer>
<key>IOProviderClass</key>
<string>IOService</string>
</dict>
<key>VoodooI2CControllerDriver</key>
<dict>
<key>CFBundleIdentifier</key>
Expand Down
Expand Up @@ -54,6 +54,12 @@ bool VoodooI2CACPIController::start(IOService* provider) {

physical_device.acpi_device = OSDynamicCast(IOACPIPlatformDevice, provider);

OSBoolean *access_intr_mask_workaround = OSDynamicCast(OSBoolean, this->getProperty("AccessIntrMaskWorkaround"));
if (access_intr_mask_workaround) {
physical_device.access_intr_mask_workaround = access_intr_mask_workaround->getValue();
IOLog("%s::%s AccessIntrMaskWorkaround: %d\n", getName(), physical_device.name, physical_device.access_intr_mask_workaround);
}

setACPIPowerState(kVoodooI2CStateOn);

if (mapMemory() != kIOReturnSuccess) {
Expand Down
Expand Up @@ -11,7 +11,7 @@

#include "VoodooI2CController.hpp"

/* Implements an ACPI Intel LPSS Designware I2C Controller
/* Implements an ACPI Synopsys DesignWare I2C Controller
*
* The members of this class are responsible for low-level interfacing with the physical ACPI hardware.
*/
Expand All @@ -22,7 +22,7 @@ class EXPORT VoodooI2CACPIController : public VoodooI2CController {
private:
/* @inherit */

IOReturn setPowerState(unsigned long whichState, IOService * whatDevice);
IOReturn setPowerState(unsigned long whichState, IOService * whatDevice) override;

/* Instructs the controller to enter a specific power state by evaluating the ACPI power state methods
* @enabled The power state the device is expected to enter represented by either <kVoodooI2CStateOn> or
Expand All @@ -35,11 +35,11 @@ class EXPORT VoodooI2CACPIController : public VoodooI2CController {

/* @inherit */

bool start(IOService* provider);
bool start(IOService* provider) override;

/* @inherit */

void stop(IOService* provider);
void stop(IOService* provider) override;
};

#endif /* VoodooI2CACPIController_hpp */
21 changes: 12 additions & 9 deletions VoodooI2C/VoodooI2C/VoodooI2CController/VoodooI2CController.cpp
Expand Up @@ -59,6 +59,7 @@ VoodooI2CController* VoodooI2CController::probe(IOService* provider, SInt32* sco
IOReturn VoodooI2CController::publishNub() {
IOLog("%s::%s Publishing nub\n", getName(), physical_device.name);
nub = OSTypeAlloc(VoodooI2CControllerNub);

if (!nub || !nub->init()) {
IOLog("%s::%s Could not initialise nub\n", getName(), physical_device.name);
goto exit;
Expand All @@ -85,13 +86,14 @@ IOReturn VoodooI2CController::publishNub() {

UInt32 VoodooI2CController::readRegister(int offset) {
if (physical_device.mmap != 0) {
IOVirtualAddress address = physical_device.mmap->getVirtualAddress();
if (address != 0)
return *(const volatile UInt32 *)(address + offset);
else
TryLog("%s::%s readRegister at offset 0x%x failed to get a virtual address\n", getName(), physical_device.name, offset);
IOVirtualAddress address = physical_device.mmap->getVirtualAddress();
if (address != 0) {
return *(volatile UInt32 *)(address + offset);
} else {
TryLog("%s::%s readRegister at offset 0x%x failed to get a virtual address\n", getName(), physical_device.name, offset);
}
} else {
TryLog("%s::%s readRegister at offset 0x%x failed since mamory was not mapped\n", getName(), physical_device.name, offset);
TryLog("%s::%s readRegister at offset 0x%x failed since memory was not mapped\n", getName(), physical_device.name, offset);
}
return 0;
}
Expand Down Expand Up @@ -155,11 +157,12 @@ void VoodooI2CController::stop(IOService* provider) {
void VoodooI2CController::writeRegister(UInt32 value, int offset) {
if (physical_device.mmap != 0) {
IOVirtualAddress address = physical_device.mmap->getVirtualAddress();
if (address != 0)
if (address != 0) {
*(volatile UInt32 *)(address + offset) = value;
else
} else {
TryLog("%s::%s writeRegister at 0x%x failed to get a virtual address\n", getName(), physical_device.name, offset);
}
} else {
TryLog("%s::%s writeRegister at 0x%x failed since mamory was not mapped\n", getName(), physical_device.name, offset);
TryLog("%s::%s writeRegister at 0x%x failed since memory was not mapped\n", getName(), physical_device.name, offset);
}
}
Expand Up @@ -26,16 +26,17 @@ typedef struct {
IOPCIDevice* pci_device;
IOMemoryMap* mmap;
IOService* provider;
bool access_intr_mask_workaround = false;
} VoodooI2CControllerPhysicalDevice;

class VoodooI2CControllerNub;

/* Implements an Intel LPSS Designware I2C Controller
/* Implements a Synopsys DesignWare I2C Controller
*
* This is the base class from which all implementations of a physical
* Intel LPSS Designware I2C Controller should inherit from. The members of this class
* Synopsys DesignWare I2C Controller should inherit from. The members of this class
* are responsible for low-level interfacing with the physical hardware. For the driver implementing
* the properiety Designware I2C controller interface, see <VoodooI2CControllerDriver>.
* the proprietary Synopsys DesignWare I2C controller interface, see <VoodooI2CControllerDriver>.
*/
class EXPORT VoodooI2CController : public IOService {
OSDeclareDefaultStructors(VoodooI2CController);
Expand Down Expand Up @@ -162,7 +163,7 @@ class EXPORT VoodooI2CController : public IOService {
* This function is called by the operating system's power management services
* to instruct the controller to enter a certain power state.
*
* @return *kIOPMAckImplied* on succesful state change, *kIOReturnError* otherwise
* @return *kIOPMAckImplied* on successful state change, *kIOReturnError* otherwise
*/

IOReturn setPowerState(unsigned long whichState, IOService* whatDevice) override;
Expand Down
Expand Up @@ -64,36 +64,29 @@
#define DW_IC_RXFLR 0x78
#define DW_IC_SDA_HOLD 0x7c
#define DW_IC_TX_ABRT_SOURCE 0x80
#define DW_IC_DMA_CR 0x88
#define DW_IC_DMA_TDLR 0x8c
#define DW_IC_DMA_RDLR 0x90
#define DW_IC_SDA_SETUP 0x94
#define DW_IC_ENABLE_STATUS 0x9c
#define DW_IC_FS_SPKLEN 0xA0
#define DW_IC_CLR_RESTART_DET 0xa8
#define DW_IC_COMP_PARAM_1 0xf4
#define DW_IC_COMP_VERSION 0xf8
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */
#define DW_IC_COMP_TYPE 0xfc
#define DW_IC_COMP_TYPE_VALUE 0x44570140

#define DW_IC_INTR_RX_UNDER 0x001
#define DW_IC_INTR_RX_OVER 0x002
#define DW_IC_INTR_RX_FULL 0x004
#define DW_IC_INTR_TX_OVER 0x008
#define DW_IC_INTR_TX_EMPTY 0x010
#define DW_IC_INTR_RD_REQ 0x020
#define DW_IC_INTR_TX_ABRT 0x040
#define DW_IC_INTR_RX_DONE 0x080
#define DW_IC_INTR_ACTIVITY 0x100
#define DW_IC_INTR_STOP_DET 0x200
#define DW_IC_INTR_START_DET 0x400
#define DW_IC_INTR_GEN_CALL 0x800

#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
DW_IC_INTR_TX_EMPTY | \
DW_IC_INTR_TX_ABRT | \
DW_IC_INTR_STOP_DET | \
DW_IC_INTR_START_DET)
#define DW_IC_COMP_TYPE_VALUE 0x44570140 /* "DW" + 0x0140 */

#define DW_IC_INTR_RX_UNDER BIT(0)
#define DW_IC_INTR_RX_OVER BIT(1)
#define DW_IC_INTR_RX_FULL BIT(2)
#define DW_IC_INTR_TX_OVER BIT(3)
#define DW_IC_INTR_TX_EMPTY BIT(4)
#define DW_IC_INTR_RD_REQ BIT(5)
#define DW_IC_INTR_TX_ABRT BIT(6)
#define DW_IC_INTR_RX_DONE BIT(7)
#define DW_IC_INTR_ACTIVITY BIT(8)
#define DW_IC_INTR_STOP_DET BIT(9)
#define DW_IC_INTR_START_DET BIT(10)
#define DW_IC_INTR_GEN_CALL BIT(11)
#define DW_IC_INTR_RESTART_DET BIT(12)

#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET | DW_IC_INTR_TX_EMPTY)

#define DW_IC_ERR_TX_ABRT 0x1

Expand All @@ -105,7 +98,7 @@ DW_IC_INTR_START_DET)
#define I2C_M_RD 0x0001
#define I2C_M_RECV_LEN 0x0400

#define DW_IC_TAR_10BITADDR_MASTER BIT(12);
#define DW_IC_TAR_10BITADDR_MASTER BIT(12)

#define BIT(nr) (1UL << (nr))

Expand Down Expand Up @@ -143,5 +136,18 @@ DW_IC_TX_ABRT_GCALL_NOACK)

#define DW_IC_STATUS_ACTIVITY 0x1

#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11)

#if defined(__LP64__) && __LP64__
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif

#define GENMASK(h, l) \
(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))

#define DW_IC_SDA_HOLD_RX_SHIFT 16
#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16)

#endif /* VoodooI2CControllerConstants_h */

0 comments on commit f9f703b

Please sign in to comment.