From 96ec2d9868c4afd3cea17f4ee18b84ccc1cde20f Mon Sep 17 00:00:00 2001 From: Orlando Chamberlain Date: Fri, 3 Mar 2023 22:28:41 +1100 Subject: platform/x86: apple-gmux: refactor gmux types Add apple_gmux_config struct containing operations and data specific to each mux type. This is in preparation for adding a third, MMIO based, gmux type. Reviewed-by: Hans de Goede Signed-off-by: Orlando Chamberlain Link: https://lore.kernel.org/r/20230303112842.3094-3-orlandoch.dev@gmail.com Signed-off-by: Hans de Goede --- include/linux/apple-gmux.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h index 1f68b49bcd68..147dc1c52e08 100644 --- a/include/linux/apple-gmux.h +++ b/include/linux/apple-gmux.h @@ -36,6 +36,11 @@ #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) +enum apple_gmux_type { + APPLE_GMUX_TYPE_PIO, + APPLE_GMUX_TYPE_INDEXED, +}; + #if IS_ENABLED(CONFIG_APPLE_GMUX) static inline bool apple_gmux_is_indexed(unsigned long iostart) { @@ -65,13 +70,13 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) * Return: %true if a supported gmux ACPI device is detected and the kernel * was configured with CONFIG_APPLE_GMUX, %false otherwise. */ -static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret) +static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_type *type_ret) { u8 ver_major, ver_minor, ver_release; struct device *dev = NULL; struct acpi_device *adev; struct resource *res; - bool indexed = false; + enum apple_gmux_type type = APPLE_GMUX_TYPE_PIO; bool ret = false; if (!pnp_dev) { @@ -99,13 +104,14 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret) ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR); ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE); if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { - indexed = apple_gmux_is_indexed(res->start); - if (!indexed) + if (apple_gmux_is_indexed(res->start)) + type = APPLE_GMUX_TYPE_INDEXED; + else goto out; } - if (indexed_ret) - *indexed_ret = indexed; + if (type_ret) + *type_ret = type; ret = true; out: -- cgit v1.2.3 From 0c18184de990e63f708b090bcb9fc6c0fbc427cd Mon Sep 17 00:00:00 2001 From: Orlando Chamberlain Date: Fri, 3 Mar 2023 22:28:42 +1100 Subject: 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: Hans de Goede Signed-off-by: Orlando Chamberlain Link: https://lore.kernel.org/r/20230303112842.3094-4-orlandoch.dev@gmail.com Signed-off-by: Hans de Goede --- include/linux/apple-gmux.h | 56 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h index 147dc1c52e08..272f63f8fd7c 100644 --- a/include/linux/apple-gmux.h +++ b/include/linux/apple-gmux.h @@ -34,11 +34,18 @@ #define GMUX_PORT_READ 0xd0 #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) enum apple_gmux_type { APPLE_GMUX_TYPE_PIO, APPLE_GMUX_TYPE_INDEXED, + APPLE_GMUX_TYPE_MMIO, }; #if IS_ENABLED(CONFIG_APPLE_GMUX) @@ -57,6 +64,24 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) 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 * @@ -93,19 +118,24 @@ static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_ty } res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0); - if (!res || resource_size(res) < GMUX_MIN_IO_LEN) - goto out; - - /* - * Invalid version information may indicate either that the gmux - * device isn't present or that it's a new one that uses indexed io. - */ - ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR); - ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR); - ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE); - if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { - if (apple_gmux_is_indexed(res->start)) - type = APPLE_GMUX_TYPE_INDEXED; + if (res && resource_size(res) >= GMUX_MIN_IO_LEN) { + /* + * Invalid version information may indicate either that the gmux + * device isn't present or that it's a new one that uses indexed io. + */ + ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR); + ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR); + ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE); + if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { + if (apple_gmux_is_indexed(res->start)) + type = APPLE_GMUX_TYPE_INDEXED; + else + 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; } -- cgit v1.2.3 From ad3d0ee8dca5fa4a656057e20f9605bbe7ff067c Mon Sep 17 00:00:00 2001 From: Orlando Chamberlain Date: Thu, 9 Mar 2023 21:43:54 +1100 Subject: platform/x86: apple-gmux: Update apple_gmux_detect documentation Commit fc83fbc80e1a ("platform/x86: apple-gmux: refactor gmux types") neglected to update the documentation of apple_gmux_detect's arguments. Update the documentation to reflect that commit's changes. include/linux/apple-gmux.h:99: warning: Function parameter or member 'type_ret' not described in 'apple_gmux_detect' include/linux/apple-gmux.h:99: warning: Excess function parameter 'indexed_ret' description in 'apple_gmux_detect' Reported-by: Stephen Rothwell Link: https://lore.kernel.org/lkml/20230309122822.77435e33@canb.auug.org.au/ Fixes: fc83fbc80e1a ("platform/x86: apple-gmux: refactor gmux types") Signed-off-by: Orlando Chamberlain Link: https://lore.kernel.org/r/20230309104353.10905-1-orlandoch.dev@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- include/linux/apple-gmux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h index 272f63f8fd7c..a7a7d430024b 100644 --- a/include/linux/apple-gmux.h +++ b/include/linux/apple-gmux.h @@ -86,7 +86,7 @@ static inline bool apple_gmux_is_mmio(unsigned long iostart) * apple_gmux_detect() - detect if gmux is built into the machine * * @pnp_dev: Device to probe or NULL to use the first matching device - * @indexed_ret: Returns (by reference) if the gmux is indexed or not + * @type_ret: Returns (by reference) the apple_gmux_type of the device * * Detect if a supported gmux device is present by actually probing it. * This avoids the false positives returned on some models by -- cgit v1.2.3 From 3608a2cd818a8d97bd3d4dc32f6c0afaf09b15ec Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 7 Mar 2023 13:05:40 +0100 Subject: backlight: apple_bl: Use acpi_video_get_backlight_type() On some MacBooks both the apple_bl and the apple-gmux backlight drivers may be able to export a /sys/class/backlight device. To avoid having 2 backlight devices for one LCD panel until now the apple-gmux driver has been calling apple_bl_unregister() to move the apple_bl backlight device out of the way when it loads. Similar problems exist on other x86 laptops and all backlight drivers which may be used on x86 laptops have moved to using acpi_video_get_backlight_type() to determine whether they should load or not. Switch apple_bl to this model too, so that it is consistent with all the other x86 backlight drivers. Besides code-simplification and consistency this has 2 other benefits: 1) It removes a race during boot where userspace will briefly see an apple_bl backlight and then have it disappear again, leading to e.g.: https://bbs.archlinux.org/viewtopic.php?id=269920 2) This allows user to switch between the drivers by passing acpi_backlight=apple_gmux or acpi_backlight=vendor on the kernel commandline. Signed-off-by: Hans de Goede Reviewed-by: Daniel Thompson Acked-by: Lee Jones Link: https://lore.kernel.org/r/20230307120540.389920-1-hdegoede@redhat.com --- include/linux/apple_bl.h | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 include/linux/apple_bl.h (limited to 'include/linux') diff --git a/include/linux/apple_bl.h b/include/linux/apple_bl.h deleted file mode 100644 index 445af2e3cc21..000000000000 --- a/include/linux/apple_bl.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * apple_bl exported symbols - */ - -#ifndef _LINUX_APPLE_BL_H -#define _LINUX_APPLE_BL_H - -#if defined(CONFIG_BACKLIGHT_APPLE) || defined(CONFIG_BACKLIGHT_APPLE_MODULE) - -extern int apple_bl_register(void); -extern void apple_bl_unregister(void); - -#else /* !CONFIG_BACKLIGHT_APPLE */ - -static inline int apple_bl_register(void) -{ - return 0; -} - -static inline void apple_bl_unregister(void) -{ -} - -#endif /* !CONFIG_BACKLIGHT_APPLE */ - -#endif /* _LINUX_APPLE_BL_H */ -- cgit v1.2.3 From fb131c472df92b2885262e747906c0a4038c82e5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 4 Apr 2023 13:19:55 +0200 Subject: platform/x86: apple-gmux: Fix iomem_base __iomem annotation Fix the __iomem annotation of the iomem_base pointers in the apple-gmux code. The __iomem should go before the *. This fixes a bunch of sparse warnings like this one: drivers/platform/x86/apple-gmux.c:224:48: sparse: expected void const [noderef] __iomem * got unsigned char [usertype] * Fixes: 0c18184de990 ("platform/x86: apple-gmux: support MMIO gmux on T2 Macs") Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202304040401.IMxt7Ubi-lkp@intel.com/ Suggested-by: Dan Carpenter Signed-off-by: Hans de Goede Reviewed-by: Orlando Chamberlain Link: https://lore.kernel.org/r/20230404111955.43266-1-hdegoede@redhat.com --- include/linux/apple-gmux.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h index a7a7d430024b..206d97ffda79 100644 --- a/include/linux/apple-gmux.h +++ b/include/linux/apple-gmux.h @@ -66,7 +66,7 @@ static inline bool apple_gmux_is_indexed(unsigned long iostart) static inline bool apple_gmux_is_mmio(unsigned long iostart) { - u8 *__iomem iomem_base = ioremap(iostart, 16); + u8 __iomem *iomem_base = ioremap(iostart, 16); u8 val; if (!iomem_base) -- cgit v1.2.3