Commit 0c18184d authored by Orlando Chamberlain's avatar Orlando Chamberlain Committed by Hans de Goede

platform/x86: apple-gmux: support MMIO gmux on T2 Macs

In some newer dual gpu MacBooks, the T2 Coprocessor functions as the
gmux, and the Intel side can interract with this new gmux type through
MMIO. Add support for these gmux controllers to the apple-gmux driver.

We start using the GMSP(0) acpi method on these gmux's when clearing
interrupts, as this prevents a flood of status=0 interrupts that can't
be cleared. It's unknown if this helps or hinders older gmux types, so
it isn't enabled for those.

Interestingly, the ACPI table only allocates 8 bytes for GMUX, but we
actually need 16, and as such we request 16 with request_mem_region.

Reading and writing from ports:
    16 bytes from 0xfe0b0200 are used. 0x0 to 0x4 are where data
    to read appears, and where data to write goes. Writing to 0xe
    sets the gmux port being accessed, and writing to 0xf sends commands.

    These commands are 0x40 & data_length for write, and data_length for
    read, where data_length is 1, 2 or 4. Once byte base+0xf is 0, the
    command is done.

Issues:
    As with other retina models, we can't switch DDC lines so
    switching at runtime doesn't work if the inactive gpu driver
    already disabled eDP due to it not being connected when that
    driver loaded.

    Additionally, turning on the dgpu back on on the MacBookPro16,1 does
    not work.
Reviewed-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarOrlando Chamberlain <orlandoch.dev@gmail.com>
Link: https://lore.kernel.org/r/20230303112842.3094-4-orlandoch.dev@gmail.comSigned-off-by: default avatarHans de Goede <hdegoede@redhat.com>
parent 96ec2d98
This diff is collapsed.
...@@ -34,11 +34,18 @@ ...@@ -34,11 +34,18 @@
#define GMUX_PORT_READ 0xd0 #define GMUX_PORT_READ 0xd0
#define GMUX_PORT_WRITE 0xd4 #define GMUX_PORT_WRITE 0xd4
#define GMUX_MMIO_PORT_SELECT 0x0e
#define GMUX_MMIO_COMMAND_SEND 0x0f
#define GMUX_MMIO_READ 0x00
#define GMUX_MMIO_WRITE 0x40
#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
enum apple_gmux_type { enum apple_gmux_type {
APPLE_GMUX_TYPE_PIO, APPLE_GMUX_TYPE_PIO,
APPLE_GMUX_TYPE_INDEXED, APPLE_GMUX_TYPE_INDEXED,
APPLE_GMUX_TYPE_MMIO,
}; };
#if IS_ENABLED(CONFIG_APPLE_GMUX) #if IS_ENABLED(CONFIG_APPLE_GMUX)
...@@ -57,6 +64,24 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) ...@@ -57,6 +64,24 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart)
return false; return false;
} }
static inline bool apple_gmux_is_mmio(unsigned long iostart)
{
u8 *__iomem iomem_base = ioremap(iostart, 16);
u8 val;
if (!iomem_base)
return false;
/*
* If this is 0xff, then gmux must not be present, as the gmux would
* reset it to 0x00, or it would be one of 0x1, 0x4, 0x41, 0x44 if a
* command is currently being processed.
*/
val = ioread8(iomem_base + GMUX_MMIO_COMMAND_SEND);
iounmap(iomem_base);
return (val != 0xff);
}
/** /**
* apple_gmux_detect() - detect if gmux is built into the machine * apple_gmux_detect() - detect if gmux is built into the machine
* *
...@@ -93,9 +118,7 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty ...@@ -93,9 +118,7 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty
} }
res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0); res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0);
if (!res || resource_size(res) < GMUX_MIN_IO_LEN) if (res && resource_size(res) >= GMUX_MIN_IO_LEN) {
goto out;
/* /*
* Invalid version information may indicate either that the gmux * Invalid version information may indicate either that the gmux
* device isn't present or that it's a new one that uses indexed io. * device isn't present or that it's a new one that uses indexed io.
...@@ -109,6 +132,13 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty ...@@ -109,6 +132,13 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty
else else
goto out; goto out;
} }
} else {
res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0);
if (res && apple_gmux_is_mmio(res->start))
type = APPLE_GMUX_TYPE_MMIO;
else
goto out;
}
if (type_ret) if (type_ret)
*type_ret = type; *type_ret = type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment