public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
From: Hans de Goede <hansg@kernel.org>
To: Thierry Chatard <tchatard@gmail.com>, linux-kernel@vger.kernel.org
Cc: linux-media@vger.kernel.org, platform-driver-x86@vger.kernel.org,
	lee@kernel.org, djrscally@gmail.com,
	ilpo.jarvinen@linux.intel.com, mchehab@kernel.org,
	sakari.ailus@linux.intel.com, jacopo.mondi@ideasonboard.com,
	nicholas@rothemail.net, kernel test robot <lkp@intel.com>
Subject: Re: [PATCH v2 2/3] platform/x86: int3472: tps68470: fix GNVS clock fields for Dell Latitude 5285
Date: Mon, 13 Apr 2026 13:02:20 +0200	[thread overview]
Message-ID: <4ef5f305-0234-4193-a190-edbfe770ea04@kernel.org> (raw)
In-Reply-To: <20260324214129.17300-3-tchatard@gmail.com>

Hi,

On 24-Mar-26 10:41 PM, Thierry Chatard wrote:
> The Dell Latitude 5285 BIOS leaves the GNVS fields C0TP, L0CL, and L1CL
> at zero at boot. The TPS68470 clock driver reads L0CL and L1CL to select
> the output frequency; with both fields zero the clock outputs are disabled,
> and neither camera sensor can communicate over I2C.
> 
> Additionally, when C0TP=0 the ACPI _DEP method on INT3479 returns PCI0 as
> its dependency instead of CLP0 (the INT3472 device), causing ipu_bridge to
> never create the i2c-INT3479:00 client for the front camera.
> 
> Add a DMI-gated fixup that runs at TPS68470 probe time and writes 0x02
> (19.2 MHz) into C0TP, L0CL, and L1CL.
> 
> The GNVS physical address is discovered at run time by scanning the raw
> AML of the DSDT (and any SSDTs) for the GNVS SystemMemory OperationRegion
> definition (opcode sequence 0x5B 0x80 "GNVS" 0x00). The parsed address is
> then mapped with acpi_os_map_memory(), which is safe because ACPI NVS
> memory is reserved by the firmware and already mapped by the OS. No
> hard-coded physical addresses are used.
> 
> Field byte offsets within the GNVS region (verified against DSDT
> disassembly on this platform, region size 0x0725 bytes):
>   C0TP: 0x43A   L0CL: 0x4F7   L1CL: 0x549
> 
> Signed-off-by: Thierry Chatard <tchatard@gmail.com>
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202603211747.Z6xudmNd-lkp@intel.com/

I'm sorry but the ACPI table / GNVS poking going on here really is not
acceptable. I can see you've done your best to make this safe, but this is
still something which I think we should not do. Writing to GNVS is troublesome
because the old values there might have already been used for 

The first thing to try here is make sure you have the latest BIOS and then select
"load setup defaults" or something similar and then "save settings". These sort
of GVNS problems often come from the layout of GVNS having changed with a BIOS
update, but the BIOS not automatically re-applying the new default settings
(which include many hidden settings) to its saved settings.

This may also change the I2C4 controller from being in ACPI enumeration mode
to being in PCI enumeration mode as one would expect of this generation of
"laptop".

If loading + saving the BIOS default settings does not help then for the
tps68470 clk problem I would suggest to just add clk data to struct
int3472_tps68470_board_data and if the clk data is set use that instead of
the values from ACPI.

Which would leave the when C0TP=0 the ACPI _DEP method on INT3479 returns PCI0
problem. Can you describe that in a bit more detail? You write:

> returns PCI0 as
> its dependency instead of CLP0 (the INT3472 device), causing ipu_bridge to
> never create the i2c-INT3479:00 client for the front camera.

but it is not ipu-bridge which is creating the i2c-INT3479:00 client, that
is done by the APCI + I2C core code, when all _DEP dependencies are marked
as available.

I guess a problem with the wrong _DEP being returned is mostly a problem
for the int3472 code which uses the _DEP relation to find out which sensor
to add regulator lookups, etc. to. But we could do a DMI quirk to simply
lookup the sensor firmware-node by its ACPI path on this 2-in-1 model ?

Also can you share an acpidump of the tables for this device please ?

Regards,

Hans



> ---
>  drivers/platform/x86/intel/int3472/tps68470.c | 201 ++++++++++++++++++
>  1 file changed, 201 insertions(+)
> 
> diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c
> index a496075c0..c9686426f 100644
> --- a/drivers/platform/x86/intel/int3472/tps68470.c
> +++ b/drivers/platform/x86/intel/int3472/tps68470.c
> @@ -2,8 +2,10 @@
>  /* Author: Dan Scally <djrscally@gmail.com> */
>  
>  #include <linux/acpi.h>
> +#include <linux/dmi.h>
>  #include <linux/i2c.h>
>  #include <linux/kernel.h>
> +#include <linux/unaligned.h>
>  #include <linux/mfd/core.h>
>  #include <linux/mfd/tps68470.h>
>  #include <linux/platform_device.h>
> @@ -140,6 +142,203 @@ skl_int3472_fill_clk_pdata(struct device *dev, struct tps68470_clk_platform_data
>  	return n_consumers;
>  }
>  
> +/* Dell Latitude 5285 GNVS fix
> + *
> + * The BIOS leaves GNVS fields C0TP, L0CL and L1CL at zero after POST.
> + * With C0TP=0 the ACPI _DEP on INT3479 resolves to PCI0 instead of CLP0
> + * (INT3472), so ipu_bridge never creates i2c-INT3479:00 (OV5670 front cam).
> + * With L0CL=L1CL=0 the TPS68470 clock driver disables all clock outputs,
> + * making both sensors unreachable over I2C.
> + *
> + * Fix: at TPS68470 probe time, locate the GNVS SystemMemory OperationRegion
> + * by scanning the DSDT/SSDTs for its AML definition, map the region, and
> + * write 0x02 (19.2 MHz) into C0TP, L0CL and L1CL.
> + *
> + * Field byte offsets (verified from DSDT disassembly, GNVS size 0x0725):
> + *   C0TP: 0x43A   L0CL: 0x4F7   L1CL: 0x549
> + */
> +#define DELL5285_C0TP_OFF	0x43A
> +#define DELL5285_L0CL_OFF	0x4F7
> +#define DELL5285_L1CL_OFF	0x549
> +/* Minimum GNVS region size: last field (L1CL) is 1 byte at 0x549 */
> +#define DELL5285_GNVS_MIN_SIZE	(DELL5285_L1CL_OFF + 1)
> +
> +/* AML integer opcodes (ACPI 6.4, section 20.2.3) */
> +#define AML_ZERO_OP		0x00
> +#define AML_ONE_OP		0x01
> +#define AML_BYTE_PREFIX		0x0A
> +#define AML_WORD_PREFIX		0x0B
> +#define AML_DWORD_PREFIX	0x0C
> +#define AML_QWORD_PREFIX	0x0E
> +
> +/**
> + * aml_parse_int - Parse one AML integer opcode at @p.
> + * @p:   Pointer to the current position in the AML byte stream.
> + * @end: One past the last valid byte of the AML buffer.
> + * @val: Output: the parsed integer value.
> + *
> + * Returns the number of bytes consumed, or 0 on failure.
> + */
> +static int aml_parse_int(const u8 *p, const u8 *end, u64 *val)
> +{
> +	if (p >= end)
> +		return 0;
> +	switch (*p) {
> +	case AML_ZERO_OP:
> +		*val = 0;
> +		return 1;
> +	case AML_ONE_OP:
> +		*val = 1;
> +		return 1;
> +	case AML_BYTE_PREFIX:
> +		if (p + 2 > end)
> +			return 0;
> +		*val = p[1];
> +		return 2;
> +	case AML_WORD_PREFIX:
> +		if (p + 3 > end)
> +			return 0;
> +		*val = get_unaligned_le16(p + 1);
> +		return 3;
> +	case AML_DWORD_PREFIX:
> +		if (p + 5 > end)
> +			return 0;
> +		*val = get_unaligned_le32(p + 1);
> +		return 5;
> +	case AML_QWORD_PREFIX:
> +		if (p + 9 > end)
> +			return 0;
> +		*val = get_unaligned_le64(p + 1);
> +		return 9;
> +	}
> +	return 0;
> +}
> +
> +/**
> + * dell5285_gnvs_from_table - Scan one ACPI table for the GNVS OperationRegion.
> + * @tbl:  ACPI table header; the AML body is scanned for the GNVS signature.
> + * @addr: Output: physical base address of the GNVS region.
> + * @size: Output: byte length of the GNVS region.
> + *
> + * Searches the AML body of @tbl for the byte sequence:
> + *   ExtOp(0x5B) OpRegionOp(0x80) NameSeg("GNVS") RegionSpace(SystemMemory=0x00)
> + * followed by two AML integers (region address and length).
> + *
> + * Returns true and fills @addr / @size if found and plausible.
> + */
> +static bool dell5285_gnvs_from_table(const struct acpi_table_header *tbl,
> +				     phys_addr_t *addr, u32 *size)
> +{
> +	/* AML: ExtOp OpRegionOp NameSeg("GNVS") SystemMemory */
> +	static const u8 sig[] = { 0x5B, 0x80, 'G', 'N', 'V', 'S', 0x00 };
> +	const u8 *aml = (const u8 *)tbl + sizeof(*tbl);
> +	const u8 *end = (const u8 *)tbl + tbl->length;
> +	const u8 *p;
> +
> +	for (p = aml; p + sizeof(sig) < end; p++) {
> +		u64 region_addr, region_size;
> +		int consumed;
> +
> +		if (memcmp(p, sig, sizeof(sig)) != 0)
> +			continue;
> +
> +		p += sizeof(sig);
> +		consumed = aml_parse_int(p, end, &region_addr);
> +		if (!consumed || !region_addr)
> +			continue;
> +
> +		p += consumed;
> +		consumed = aml_parse_int(p, end, &region_size);
> +		if (!consumed || region_size < DELL5285_GNVS_MIN_SIZE)
> +			continue;
> +
> +		*addr = (phys_addr_t)region_addr;
> +		*size = (u32)region_size;
> +		return true;
> +	}
> +	return false;
> +}
> +
> +/**
> + * dell5285_gnvs_find - Locate the GNVS OperationRegion by scanning DSDT and SSDTs.
> + * @addr: Output: physical base address of the GNVS region.
> + * @size: Output: byte length of the GNVS region.
> + *
> + * Returns true if the GNVS region was found in any ACPI table.
> + */
> +static bool dell5285_gnvs_find(phys_addr_t *addr, u32 *size)
> +{
> +	struct acpi_table_header *tbl;
> +	u32 i;
> +
> +	/* DSDT */
> +	if (ACPI_SUCCESS(acpi_get_table(ACPI_SIG_DSDT, 1, &tbl))) {
> +		bool found = dell5285_gnvs_from_table(tbl, addr, size);
> +
> +		acpi_put_table(tbl);
> +		if (found)
> +			return true;
> +	}
> +
> +	/* SSDTs (instance numbers start at 1, stop at first failure) */
> +	for (i = 1; i <= 32; i++) {
> +		bool found;
> +
> +		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_SSDT, i, &tbl)))
> +			break;
> +		found = dell5285_gnvs_from_table(tbl, addr, size);
> +		acpi_put_table(tbl);
> +		if (found)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +static const struct dmi_system_id dell5285_gnvs_dmi[] = {
> +	{
> +		.matches = {
> +			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
> +			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5285"),
> +		},
> +	},
> +	{ }
> +};
> +
> +static void dell5285_gnvs_fix(void)
> +{
> +	phys_addr_t gnvs_addr;
> +	u32 gnvs_size;
> +	void *gnvs;
> +
> +	if (!dmi_check_system(dell5285_gnvs_dmi))
> +		return;
> +
> +	if (!dell5285_gnvs_find(&gnvs_addr, &gnvs_size)) {
> +		pr_err("int3472-tps68470: Dell 5285: GNVS OperationRegion not found in DSDT/SSDTs\n");
> +		return;
> +	}
> +
> +	gnvs = acpi_os_map_memory(gnvs_addr, gnvs_size);
> +	if (!gnvs) {
> +		pr_err("int3472-tps68470: Dell 5285: failed to map GNVS at %pa\n",
> +		       &gnvs_addr);
> +		return;
> +	}
> +
> +	pr_info("int3472-tps68470: Dell 5285 GNVS fix at %pa: C0TP=0x%02x L0CL=0x%02x L1CL=0x%02x -> 0x02\n",
> +		&gnvs_addr,
> +		*(u8 *)(gnvs + DELL5285_C0TP_OFF),
> +		*(u8 *)(gnvs + DELL5285_L0CL_OFF),
> +		*(u8 *)(gnvs + DELL5285_L1CL_OFF));
> +
> +	*(u8 *)(gnvs + DELL5285_C0TP_OFF) = 0x02;
> +	*(u8 *)(gnvs + DELL5285_L0CL_OFF) = 0x02;
> +	*(u8 *)(gnvs + DELL5285_L1CL_OFF) = 0x02;
> +
> +	acpi_os_unmap_memory(gnvs, gnvs_size);
> +}
> +
>  static int skl_int3472_tps68470_probe(struct i2c_client *client)
>  {
>  	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
> @@ -155,6 +354,8 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client)
>  	if (!adev)
>  		return -ENODEV;
>  
> +	dell5285_gnvs_fix();
> +
>  	n_consumers = skl_int3472_fill_clk_pdata(&client->dev, &clk_pdata);
>  	if (n_consumers < 0)
>  		return n_consumers;


  reply	other threads:[~2026-04-13 11:02 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-20  0:09 [PATCH 0/5] Enable dual cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-03-20  0:09 ` [PATCH 1/5] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-03-20  0:09 ` [PATCH 2/5] platform/x86: int3472: tps68470: fix GNVS clock fields " Thierry Chatard
2026-03-21  9:44   ` kernel test robot
2026-03-20  0:09 ` [PATCH 3/5] platform/x86: int3472: tps68470: add board data " Thierry Chatard
2026-03-20  0:09 ` [PATCH 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-03-20  0:09 ` [PATCH 5/5] media: ov8858: add ACPI device ID INT3477 and vsio power supply Thierry Chatard
2026-03-24 21:41 ` [PATCH v2 0/5] Enable dual cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-03-24 21:41   ` [PATCH v2 1/3] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-04-13  9:48     ` Hans de Goede
2026-03-24 21:41   ` [PATCH v2 2/3] platform/x86: int3472: tps68470: fix GNVS clock fields " Thierry Chatard
2026-04-13 11:02     ` Hans de Goede [this message]
2026-04-17 16:32       ` [PATCH v3 0/5] Enable cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-04-17 16:32         ` [PATCH v3 1/5] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-04-17 17:35           ` Hans de Goede
2026-04-18  6:31           ` Sakari Ailus
2026-04-17 16:32         ` [PATCH v3 2/5] platform/x86: int3472: tps68470: fix clock consumer registration " Thierry Chatard
2026-04-17 17:40           ` Hans de Goede
2026-04-18  6:29           ` Sakari Ailus
2026-04-17 16:32         ` [PATCH v3 3/5] platform/x86: int3472: tps68470: add board data " Thierry Chatard
2026-04-17 18:54           ` Hans de Goede
2026-04-18  7:16             ` Sakari Ailus
2026-04-21 22:52               ` [PATCH v4 0/5] Enable cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-04-21 22:52                 ` [PATCH v4 1/5] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-04-22  6:54                   ` Sakari Ailus
2026-04-21 22:52                 ` [PATCH v4 2/5] platform/x86: int3472: tps68470: fix clock consumer registration " Thierry Chatard
2026-04-22  7:07                   ` Sakari Ailus
2026-04-25  5:13                     ` [PATCH v5 0/5] Enable cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-04-25  5:13                       ` [PATCH v5 1/5] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-04-25  5:13                       ` [PATCH v5 2/5] platform/x86: int3472: tps68470: fix clock consumer registration " Thierry Chatard
2026-04-25  5:13                       ` [PATCH v5 3/5] platform/x86: int3472: tps68470: add board data " Thierry Chatard
2026-04-25  5:13                       ` [PATCH v5 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-04-25  5:13                       ` [PATCH v5 5/5] media: ov8858: add ACPI device ID INT3477 Thierry Chatard
2026-04-25 16:31                     ` [PATCH v6 0/5] Enable cameras on Dell Latitude 5285 2-in-1 Thierry Chatard
2026-04-25 16:31                       ` [PATCH v6 1/5] platform/x86: intel_lpss: add resource conflict quirk for Dell Latitude 5285 Thierry Chatard
2026-04-25 16:31                       ` [PATCH v6 2/5] platform/x86: int3472: tps68470: fix clock consumer registration " Thierry Chatard
2026-04-27  7:48                         ` Sakari Ailus
2026-04-25 16:31                       ` [PATCH v6 3/5] platform/x86: int3472: tps68470: add board data " Thierry Chatard
2026-04-25 16:31                       ` [PATCH v6 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-04-25 16:31                       ` [PATCH v6 5/5] media: ov8858: add ACPI device ID INT3477 Thierry Chatard
2026-04-27  7:49                         ` Sakari Ailus
2026-04-27 12:06                         ` Hans de Goede
2026-04-21 22:52                 ` [PATCH v4 3/5] platform/x86: int3472: tps68470: add board data for Dell Latitude 5285 Thierry Chatard
2026-04-22  7:11                   ` Sakari Ailus
2026-04-22  7:13                     ` Sakari Ailus
2026-04-21 22:52                 ` [PATCH v4 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-04-21 22:52                 ` [PATCH v4 5/5] media: ov8858: add ACPI device ID INT3477 Thierry Chatard
2026-04-22  7:15                   ` Sakari Ailus
2026-04-17 16:32         ` [PATCH v3 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-04-17 18:56           ` Hans de Goede
2026-04-18  7:18           ` Sakari Ailus
2026-04-17 16:32         ` [PATCH v3 5/5] media: ov8858: add ACPI device ID INT3477 and vsio power supply Thierry Chatard
2026-04-17 18:59           ` Hans de Goede
2026-04-17 16:35       ` [PATCH v2 2/3] platform/x86: int3472: tps68470: fix GNVS clock fields for Dell Latitude 5285 tchatard
2026-03-24 21:41   ` [PATCH v2 3/3] platform/x86: int3472: tps68470: add board data " Thierry Chatard
2026-03-24 21:41   ` [PATCH v2 4/5] media: ipu-bridge: add sensor configuration for OV8858 (INT3477) Thierry Chatard
2026-03-24 21:41   ` [PATCH v2 5/5] media: ov8858: add ACPI device ID INT3477 and vsio power supply Thierry Chatard
2026-04-13  9:45   ` [PATCH v2 0/5] Enable dual cameras on Dell Latitude 5285 2-in-1 Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4ef5f305-0234-4193-a190-edbfe770ea04@kernel.org \
    --to=hansg@kernel.org \
    --cc=djrscally@gmail.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jacopo.mondi@ideasonboard.com \
    --cc=lee@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=mchehab@kernel.org \
    --cc=nicholas@rothemail.net \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=sakari.ailus@linux.intel.com \
    --cc=tchatard@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox