Skip to content

Commit

Permalink
mfd: lpc_ich: Add support for Intel Apollo Lake SoC
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
Acked-by: Marek Vasut <marek.vasut@gmail.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
  • Loading branch information
westeri authored and Lee Jones committed Jan 3, 2017
1 parent ff00d7a commit 87eb832
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions drivers/mfd/lpc_ich.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
* document number TBD : Wildcat Point-LP
* document number TBD : 9 Series
* document number TBD : Lewisburg
* document number TBD : Apollo Lake SoC
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
Expand Down Expand Up @@ -92,6 +93,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
Expand Down Expand Up @@ -239,6 +242,7 @@ enum lpc_chipsets {
LPC_BRASWELL, /* Braswell SoC */
LPC_LEWISBURG, /* Lewisburg */
LPC_9S, /* 9 Series */
LPC_APL, /* Apollo Lake SoC */
};

static struct lpc_ich_info lpc_chipset_info[] = {
Expand Down Expand Up @@ -561,6 +565,10 @@ static struct lpc_ich_info lpc_chipset_info[] = {
.iTCO_version = 2,
.gpio_version = ICH_V5_GPIO,
},
[LPC_APL] = {
.name = "Apollo Lake SoC",
.spi_type = INTEL_SPI_BXT,
},
};

/*
Expand Down Expand Up @@ -709,6 +717,7 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x3b14), LPC_3420},
{ PCI_VDEVICE(INTEL, 0x3b16), LPC_3450},
{ PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579},
{ PCI_VDEVICE(INTEL, 0x5ae8), LPC_APL},
{ PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT},
Expand Down Expand Up @@ -1128,6 +1137,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(bus, p2sb, 0xe1, 0x1);
break;
}

default:
return -EINVAL;
}
Expand Down

0 comments on commit 87eb832

Please sign in to comment.