From: Lim Key Seong <key.seong....@intel.com>

Intel Apollo Lake SoC exposes serial SPI flash through the LPC device. The
SPI flash host controller is not discoverable through PCI config cycles
because P2SB (function 0 of the device 13) is hidden by the BIOS. We unhide
the device briefly in order to read BAR 0 of the SPI host controller.

This is backport of v2 of "mfd: lpc_ich: Add support for Intel Apollo Lake
SoC" from Mika

Signed-off-by: Mika Westerberg <mika.westerb...@linux.intel.com>
Signed-off-by: Lim Key Seong <key.seong....@intel.com>
---
 drivers/mfd/lpc_ich-core.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/mfd/lpc_ich-core.c b/drivers/mfd/lpc_ich-core.c
index eeb1162..349376b 100644
--- a/drivers/mfd/lpc_ich-core.c
+++ b/drivers/mfd/lpc_ich-core.c
@@ -55,6 +55,7 @@
  *     document number TBD : Coleto Creek
  *     document number TBD : Wildcat Point-LP
  *     document number TBD : 9 Series
+ *     document number TBD : Apollo Lake SoC
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -94,6 +95,8 @@
 #define BCR                    0xdc
 #define BCR_WPD                        BIT(0)
 
+#define SPIBASE_APL_SZ         4096
+
 #define GPIOBASE_ICH0          0x58
 #define GPIOCTRL_ICH0          0x5C
 #define GPIOBASE_ICH6          0x48
@@ -575,6 +578,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
        [LPC_APL]  = {
                .name = "Apollo Lake SoC",
                .iTCO_version = 5,
+               .spi_type = INTEL_SPI_BXT,
        },
 };
 
@@ -1229,6 +1233,36 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
                }
                break;
 
+       case INTEL_SPI_BXT: {
+               unsigned int p2sb = PCI_DEVFN(13, 0);
+               unsigned int spi = PCI_DEVFN(13, 2);
+               struct pci_bus *bus = dev->bus;
+
+               /*
+                * The P2SB is hidden by BIOS and we need to unhide it in
+                * order to read BAR of the SPI flash device. Once that is
+                * done we hide it again.
+                */
+               pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x0);
+               pci_bus_read_config_dword(bus, spi, PCI_BASE_ADDRESS_0,
+                                         &spi_base);
+               if (spi_base != ~0) {
+                       res->start = spi_base & 0xfffffff0;
+                       res->end = res->start + SPIBASE_APL_SZ - 1;
+
+                       pci_bus_read_config_dword(bus, spi, BCR, &bcr);
+                       if (!(bcr & BCR_WPD)) {
+                               bcr |= BCR_WPD;
+                               pci_bus_write_config_dword(bus, spi, BCR, bcr);
+                               pci_bus_read_config_dword(bus, spi, BCR, &bcr);
+                       }
+                       info->writeable = !!(bcr & BCR_WPD);
+               }
+
+               pci_bus_write_config_byte(dev->bus, p2sb, 0xe1, 0x1);
+               break;
+       }
+
        default:
                return -EINVAL;
        }
-- 
2.7.3

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to