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