xref: /linux/sound/soc/intel/common/soc-intel-quirks.h (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1e149ca29SPierre-Louis Bossart /* SPDX-License-Identifier: GPL-2.0-only */
2536cfd2fSPierre-Louis Bossart /*
3536cfd2fSPierre-Louis Bossart  * soc-intel-quirks.h - prototypes for quirk autodetection
4536cfd2fSPierre-Louis Bossart  *
5536cfd2fSPierre-Louis Bossart  * Copyright (c) 2019, Intel Corporation.
6536cfd2fSPierre-Louis Bossart  *
7536cfd2fSPierre-Louis Bossart  */
8536cfd2fSPierre-Louis Bossart 
9536cfd2fSPierre-Louis Bossart #ifndef _SND_SOC_INTEL_QUIRKS_H
10536cfd2fSPierre-Louis Bossart #define _SND_SOC_INTEL_QUIRKS_H
11536cfd2fSPierre-Louis Bossart 
12cd45c9bfSHans de Goede #include <linux/platform_data/x86/soc.h>
13cd45c9bfSHans de Goede 
14*9931f7d5SPierre-Louis Bossart #if IS_REACHABLE(CONFIG_IOSF_MBI)
15536cfd2fSPierre-Louis Bossart 
168ade6d8bSHans de Goede #include <linux/dmi.h>
17536cfd2fSPierre-Louis Bossart #include <asm/iosf_mbi.h>
18536cfd2fSPierre-Louis Bossart 
soc_intel_is_byt_cr(struct platform_device * pdev)19536cfd2fSPierre-Louis Bossart static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
20536cfd2fSPierre-Louis Bossart {
218ade6d8bSHans de Goede 	/*
228ade6d8bSHans de Goede 	 * List of systems which:
238ade6d8bSHans de Goede 	 * 1. Use a non CR version of the Bay Trail SoC
248ade6d8bSHans de Goede 	 * 2. Contain at least 6 interrupt resources so that the
258ade6d8bSHans de Goede 	 *    platform_get_resource(pdev, IORESOURCE_IRQ, 5) check below
268ade6d8bSHans de Goede 	 *    succeeds
278ade6d8bSHans de Goede 	 * 3. Despite 1. and 2. still have their IPC IRQ at index 0 rather then 5
288ade6d8bSHans de Goede 	 *
298ade6d8bSHans de Goede 	 * This needs to be here so that it can be shared between the SST and
308ade6d8bSHans de Goede 	 * SOF drivers. We rely on the compiler to optimize this out in files
318ade6d8bSHans de Goede 	 * where soc_intel_is_byt_cr is not used.
328ade6d8bSHans de Goede 	 */
338ade6d8bSHans de Goede 	static const struct dmi_system_id force_bytcr_table[] = {
348ade6d8bSHans de Goede 		{	/* Lenovo Yoga Tablet 2 series */
358ade6d8bSHans de Goede 			.matches = {
368ade6d8bSHans de Goede 				DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
378ade6d8bSHans de Goede 				DMI_MATCH(DMI_PRODUCT_FAMILY, "YOGATablet2"),
388ade6d8bSHans de Goede 			},
398ade6d8bSHans de Goede 		},
408ade6d8bSHans de Goede 		{}
418ade6d8bSHans de Goede 	};
42536cfd2fSPierre-Louis Bossart 	struct device *dev = &pdev->dev;
43536cfd2fSPierre-Louis Bossart 	int status = 0;
44536cfd2fSPierre-Louis Bossart 
45536cfd2fSPierre-Louis Bossart 	if (!soc_intel_is_byt())
46536cfd2fSPierre-Louis Bossart 		return false;
47536cfd2fSPierre-Louis Bossart 
488ade6d8bSHans de Goede 	if (dmi_check_system(force_bytcr_table))
498ade6d8bSHans de Goede 		return true;
508ade6d8bSHans de Goede 
51536cfd2fSPierre-Louis Bossart 	if (iosf_mbi_available()) {
52536cfd2fSPierre-Louis Bossart 		u32 bios_status;
53536cfd2fSPierre-Louis Bossart 
54536cfd2fSPierre-Louis Bossart 		status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
55536cfd2fSPierre-Louis Bossart 				       MBI_REG_READ, /* 0x10 */
56536cfd2fSPierre-Louis Bossart 				       0x006, /* BIOS_CONFIG */
57536cfd2fSPierre-Louis Bossart 				       &bios_status);
58536cfd2fSPierre-Louis Bossart 
59536cfd2fSPierre-Louis Bossart 		if (status) {
60536cfd2fSPierre-Louis Bossart 			dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
61536cfd2fSPierre-Louis Bossart 		} else {
62536cfd2fSPierre-Louis Bossart 			/* bits 26:27 mirror PMIC options */
63536cfd2fSPierre-Louis Bossart 			bios_status = (bios_status >> 26) & 3;
64536cfd2fSPierre-Louis Bossart 
65536cfd2fSPierre-Louis Bossart 			if (bios_status == 1 || bios_status == 3) {
66536cfd2fSPierre-Louis Bossart 				dev_info(dev, "Detected Baytrail-CR platform\n");
67536cfd2fSPierre-Louis Bossart 				return true;
68536cfd2fSPierre-Louis Bossart 			}
69536cfd2fSPierre-Louis Bossart 
70536cfd2fSPierre-Louis Bossart 			dev_info(dev, "BYT-CR not detected\n");
71536cfd2fSPierre-Louis Bossart 		}
72536cfd2fSPierre-Louis Bossart 	} else {
73536cfd2fSPierre-Louis Bossart 		dev_info(dev, "IOSF_MBI not available, no BYT-CR detection\n");
74536cfd2fSPierre-Louis Bossart 	}
75536cfd2fSPierre-Louis Bossart 
76536cfd2fSPierre-Louis Bossart 	if (!platform_get_resource(pdev, IORESOURCE_IRQ, 5)) {
77536cfd2fSPierre-Louis Bossart 		/*
78536cfd2fSPierre-Louis Bossart 		 * Some devices detected as BYT-T have only a single IRQ listed,
79536cfd2fSPierre-Louis Bossart 		 * causing platform_get_irq with index 5 to return -ENXIO.
80536cfd2fSPierre-Louis Bossart 		 * The correct IRQ in this case is at index 0, as on BYT-CR.
81536cfd2fSPierre-Louis Bossart 		 */
82536cfd2fSPierre-Louis Bossart 		dev_info(dev, "Falling back to Baytrail-CR platform\n");
83536cfd2fSPierre-Louis Bossart 		return true;
84536cfd2fSPierre-Louis Bossart 	}
85536cfd2fSPierre-Louis Bossart 
86536cfd2fSPierre-Louis Bossart 	return false;
87536cfd2fSPierre-Louis Bossart }
88536cfd2fSPierre-Louis Bossart 
89536cfd2fSPierre-Louis Bossart #else
90536cfd2fSPierre-Louis Bossart 
soc_intel_is_byt_cr(struct platform_device * pdev)91536cfd2fSPierre-Louis Bossart static inline bool soc_intel_is_byt_cr(struct platform_device *pdev)
92536cfd2fSPierre-Louis Bossart {
93536cfd2fSPierre-Louis Bossart 	return false;
94536cfd2fSPierre-Louis Bossart }
95536cfd2fSPierre-Louis Bossart 
96536cfd2fSPierre-Louis Bossart #endif
97536cfd2fSPierre-Louis Bossart 
98536cfd2fSPierre-Louis Bossart #endif /* _SND_SOC_INTEL_QUIRKS_H */
99