11ff4f321SSimon Glass /*
21ff4f321SSimon Glass * Copyright (C) 2014 Google, Inc
31ff4f321SSimon Glass *
41ff4f321SSimon Glass * SPDX-License-Identifier: GPL-2.0+
51ff4f321SSimon Glass */
61ff4f321SSimon Glass
71ff4f321SSimon Glass #include <common.h>
81ff4f321SSimon Glass #include <dm.h>
91ff4f321SSimon Glass #include <pch.h>
101ff4f321SSimon Glass
11*ec2af6f8SBin Meng #define GPIO_BASE 0x44
121ff4f321SSimon Glass #define BIOS_CTRL 0xd8
131ff4f321SSimon Glass
pch7_get_spi_base(struct udevice * dev,ulong * sbasep)143e389d8bSBin Meng static int pch7_get_spi_base(struct udevice *dev, ulong *sbasep)
151ff4f321SSimon Glass {
161ff4f321SSimon Glass u32 rcba;
171ff4f321SSimon Glass
181ff4f321SSimon Glass dm_pci_read_config32(dev, PCH_RCBA, &rcba);
191ff4f321SSimon Glass /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */
201ff4f321SSimon Glass rcba = rcba & 0xffffc000;
211ff4f321SSimon Glass *sbasep = rcba + 0x3020;
221ff4f321SSimon Glass
231ff4f321SSimon Glass return 0;
241ff4f321SSimon Glass }
251ff4f321SSimon Glass
pch7_set_spi_protect(struct udevice * dev,bool protect)261ff4f321SSimon Glass static int pch7_set_spi_protect(struct udevice *dev, bool protect)
271ff4f321SSimon Glass {
281ff4f321SSimon Glass uint8_t bios_cntl;
291ff4f321SSimon Glass
301ff4f321SSimon Glass /* Adjust the BIOS write protect to dis/allow write commands */
311ff4f321SSimon Glass dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl);
321ff4f321SSimon Glass if (protect)
331ff4f321SSimon Glass bios_cntl &= ~BIOS_CTRL_BIOSWE;
341ff4f321SSimon Glass else
351ff4f321SSimon Glass bios_cntl |= BIOS_CTRL_BIOSWE;
361ff4f321SSimon Glass dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl);
371ff4f321SSimon Glass
381ff4f321SSimon Glass return 0;
391ff4f321SSimon Glass }
401ff4f321SSimon Glass
pch7_get_gpio_base(struct udevice * dev,u32 * gbasep)41*ec2af6f8SBin Meng static int pch7_get_gpio_base(struct udevice *dev, u32 *gbasep)
42*ec2af6f8SBin Meng {
43*ec2af6f8SBin Meng u32 base;
44*ec2af6f8SBin Meng
45*ec2af6f8SBin Meng /*
46*ec2af6f8SBin Meng * GPIO_BASE moved to its current offset with ICH6, but prior to
47*ec2af6f8SBin Meng * that it was unused (or undocumented). Check that it looks
48*ec2af6f8SBin Meng * okay: not all ones or zeros.
49*ec2af6f8SBin Meng *
50*ec2af6f8SBin Meng * Note we don't need check bit0 here, because the Tunnel Creek
51*ec2af6f8SBin Meng * GPIO base address register bit0 is reserved (read returns 0),
52*ec2af6f8SBin Meng * while on the Ivybridge the bit0 is used to indicate it is an
53*ec2af6f8SBin Meng * I/O space.
54*ec2af6f8SBin Meng */
55*ec2af6f8SBin Meng dm_pci_read_config32(dev, GPIO_BASE, &base);
56*ec2af6f8SBin Meng if (base == 0x00000000 || base == 0xffffffff) {
57*ec2af6f8SBin Meng debug("%s: unexpected BASE value\n", __func__);
58*ec2af6f8SBin Meng return -ENODEV;
59*ec2af6f8SBin Meng }
60*ec2af6f8SBin Meng
61*ec2af6f8SBin Meng /*
62*ec2af6f8SBin Meng * Okay, I guess we're looking at the right device. The actual
63*ec2af6f8SBin Meng * GPIO registers are in the PCI device's I/O space, starting
64*ec2af6f8SBin Meng * at the offset that we just read. Bit 0 indicates that it's
65*ec2af6f8SBin Meng * an I/O address, not a memory address, so mask that off.
66*ec2af6f8SBin Meng */
67*ec2af6f8SBin Meng *gbasep = base & 1 ? base & ~3 : base & ~15;
68*ec2af6f8SBin Meng
69*ec2af6f8SBin Meng return 0;
70*ec2af6f8SBin Meng }
71*ec2af6f8SBin Meng
721ff4f321SSimon Glass static const struct pch_ops pch7_ops = {
733e389d8bSBin Meng .get_spi_base = pch7_get_spi_base,
741ff4f321SSimon Glass .set_spi_protect = pch7_set_spi_protect,
75*ec2af6f8SBin Meng .get_gpio_base = pch7_get_gpio_base,
761ff4f321SSimon Glass };
771ff4f321SSimon Glass
781ff4f321SSimon Glass static const struct udevice_id pch7_ids[] = {
791ff4f321SSimon Glass { .compatible = "intel,pch7" },
801ff4f321SSimon Glass { }
811ff4f321SSimon Glass };
821ff4f321SSimon Glass
831ff4f321SSimon Glass U_BOOT_DRIVER(pch7_drv) = {
841ff4f321SSimon Glass .name = "intel-pch7",
851ff4f321SSimon Glass .id = UCLASS_PCH,
861ff4f321SSimon Glass .of_match = pch7_ids,
871ff4f321SSimon Glass .ops = &pch7_ops,
881ff4f321SSimon Glass };
89