diff options
-rw-r--r-- | src/soc/intel/apollolake/i2c.c | 18 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/iomap.h | 3 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/i2c.c | 20 | ||||
-rw-r--r-- | src/soc/intel/common/block/i2c/Makefile.inc | 6 | ||||
-rw-r--r-- | src/soc/intel/common/block/i2c/i2c.c | 110 | ||||
-rw-r--r-- | src/soc/intel/common/block/i2c/i2c_early.c | 96 | ||||
-rw-r--r-- | src/soc/intel/skylake/i2c.c | 17 |
7 files changed, 112 insertions, 158 deletions
diff --git a/src/soc/intel/apollolake/i2c.c b/src/soc/intel/apollolake/i2c.c index bb14df2a0e..bf378bce34 100644 --- a/src/soc/intel/apollolake/i2c.c +++ b/src/soc/intel/apollolake/i2c.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright 2016 Google Inc. + * Copyright (C) 2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,27 +14,10 @@ * GNU General Public License for more details. */ -#include <console/console.h> #include <device/device.h> #include <device/pci_def.h> #include <drivers/i2c/designware/dw_i2c.h> -#include <intelblocks/chip.h> -#include <soc/iomap.h> #include <soc/pci_devs.h> -#include "chip.h" - -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) -{ - const struct soc_intel_common_config *common_config; - common_config = chip_get_common_soc_structure(); - - return &common_config->i2c[bus]; -} - -uintptr_t dw_i2c_get_soc_early_base(unsigned int bus) -{ - return PRERAM_I2C_BASE_ADDRESS(bus); -} /* Convert I2C bus number to PCI device and function */ int dw_i2c_soc_bus_to_devfn(unsigned int bus) diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h index 7e6a795c58..9a2500cd45 100644 --- a/src/soc/intel/apollolake/include/soc/iomap.h +++ b/src/soc/intel/apollolake/include/soc/iomap.h @@ -51,6 +51,7 @@ #define EARLY_GSPI_BASE_ADDRESS 0xfe011000 /* Temporary BAR for early I2C bus access */ -#define PRERAM_I2C_BASE_ADDRESS(x) (0xfe020000 + (0x1000 * (x))) +#define EARLY_I2C_BASE_ADDRESS 0xfe020000 +#define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) #endif /* _SOC_APOLLOLAKE_IOMAP_H_ */ diff --git a/src/soc/intel/cannonlake/i2c.c b/src/soc/intel/cannonlake/i2c.c index b53d5a0c1c..6983be1c30 100644 --- a/src/soc/intel/cannonlake/i2c.c +++ b/src/soc/intel/cannonlake/i2c.c @@ -2,7 +2,7 @@ * This file is part of the coreboot project. * * Copyright 2016 Google Inc. - * Copyright (C) 2017 Intel Corporation. + * Copyright (C) 2017-2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,27 +14,9 @@ * GNU General Public License for more details. */ -#include <console/console.h> #include <device/device.h> -#include <device/pci_def.h> #include <drivers/i2c/designware/dw_i2c.h> -#include <intelblocks/chip.h> -#include <soc/iomap.h> #include <soc/pci_devs.h> -#include "chip.h" - -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) -{ - const struct soc_intel_common_config *common_config; - common_config = chip_get_common_soc_structure(); - - return &common_config->i2c[bus]; -} - -uintptr_t dw_i2c_get_soc_early_base(unsigned int bus) -{ - return EARLY_I2C_BASE(bus); -} int dw_i2c_soc_devfn_to_bus(unsigned int devfn) { diff --git a/src/soc/intel/common/block/i2c/Makefile.inc b/src/soc/intel/common/block/i2c/Makefile.inc index 58feb5f781..9683210123 100644 --- a/src/soc/intel/common/block/i2c/Makefile.inc +++ b/src/soc/intel/common/block/i2c/Makefile.inc @@ -1,8 +1,8 @@ ifeq ($(CONFIG_SOC_INTEL_COMMON_BLOCK_I2C),y) -bootblock-y += i2c_early.c -romstage-y += i2c_early.c -verstage-y += i2c_early.c +bootblock-y += i2c.c +romstage-y += i2c.c +verstage-y += i2c.c ramstage-y += i2c.c endif diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index 7dd40db146..11bd018c8b 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -13,10 +13,113 @@ * GNU General Public License for more details. */ +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/i2c_simple.h> #include <device/pci.h> #include <device/pci_def.h> #include <device/pci_ids.h> #include <drivers/i2c/designware/dw_i2c.h> +#include <intelblocks/chip.h> +#include <intelblocks/lpss.h> +#include <soc/iomap.h> +#include <soc/pci_devs.h> + +int dw_i2c_soc_dev_to_bus(struct device *dev) +{ + pci_devfn_t devfn = dev->path.pci.devfn; + return dw_i2c_soc_devfn_to_bus(devfn); +} + +/* Getting I2C bus configuration from devicetree config */ +const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) +{ + const struct soc_intel_common_config *common_config; + common_config = chip_get_common_soc_structure(); + + return &common_config->i2c[bus]; +} + +/* Get base address for early init of I2C controllers. */ +uintptr_t dw_i2c_get_soc_early_base(unsigned int bus) +{ + return EARLY_I2C_BASE(bus); +} + +#if !ENV_RAMSTAGE +static int lpss_i2c_early_init_bus(unsigned int bus) +{ + const struct dw_i2c_bus_config *config; + const struct device *tree_dev; + pci_devfn_t dev; + int devfn; + uintptr_t base; + + /* Find the PCI device for this bus controller */ + devfn = dw_i2c_soc_bus_to_devfn(bus); + if (devfn < 0) { + printk(BIOS_ERR, "I2C%u device not found\n", bus); + return -1; + } + + /* Look up the controller device in the devicetree */ + dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); + tree_dev = dev_find_slot(0, devfn); + if (!tree_dev || !tree_dev->enabled) { + printk(BIOS_ERR, "I2C%u device not enabled\n", bus); + return -1; + } + + /* Skip if not enabled for early init */ + config = dw_i2c_get_soc_cfg(bus); + if (!config || !config->early_init) { + printk(BIOS_DEBUG, "I2C%u not enabled for early init\n", bus); + return -1; + } + + /* Prepare early base address for access before memory */ + base = dw_i2c_get_soc_early_base(bus); + pci_write_config32(dev, PCI_BASE_ADDRESS_0, base); + pci_write_config32(dev, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + /* Take device out of reset */ + lpss_reset_release(base); + + /* Initialize the controller */ + if (dw_i2c_init(bus, config) < 0) { + printk(BIOS_ERR, "I2C%u failed to initialize\n", bus); + return -1; + } + + return 0; +} + +uintptr_t dw_i2c_base_address(unsigned int bus) +{ + int devfn; + pci_devfn_t dev; + uintptr_t base; + + /* Find device+function for this controller */ + devfn = dw_i2c_soc_bus_to_devfn(bus); + if (devfn < 0) + return (uintptr_t)NULL; + + /* Form a PCI address for this device */ + dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + /* Read the first base address for this device */ + base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16); + + /* Attempt to initialize bus if base is not set yet */ + if (!base && !lpss_i2c_early_init_bus(bus)) + base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), + 16); + return base; +} +#else uintptr_t dw_i2c_base_address(unsigned int bus) { @@ -43,12 +146,6 @@ uintptr_t dw_i2c_base_address(unsigned int bus) return (uintptr_t)NULL; } -int dw_i2c_soc_dev_to_bus(struct device *dev) -{ - pci_devfn_t devfn = dev->path.pci.devfn; - return dw_i2c_soc_devfn_to_bus(devfn); -} - static struct device_operations i2c_dev_ops = { .read_resources = &pci_dev_read_resources, .set_resources = &pci_dev_set_resources, @@ -101,3 +198,4 @@ static const struct pci_driver pch_i2c __pci_driver = { .vendor = PCI_VENDOR_ID_INTEL, .devices = pci_device_ids, }; +#endif diff --git a/src/soc/intel/common/block/i2c/i2c_early.c b/src/soc/intel/common/block/i2c/i2c_early.c deleted file mode 100644 index c4af55967a..0000000000 --- a/src/soc/intel/common/block/i2c/i2c_early.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2016 Google Inc. - * Copyright 2017 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <arch/io.h> -#include <console/console.h> -#include <device/device.h> -#include <device/i2c_simple.h> -#include <device/pci.h> -#include <device/pci_def.h> -#include <drivers/i2c/designware/dw_i2c.h> -#include <intelblocks/lpss.h> - -static int lpss_i2c_early_init_bus(unsigned int bus) -{ - const struct dw_i2c_bus_config *config; - const struct device *tree_dev; - pci_devfn_t dev; - int devfn; - uintptr_t base; - - /* Find the PCI device for this bus controller */ - devfn = dw_i2c_soc_bus_to_devfn(bus); - if (devfn < 0) { - printk(BIOS_ERR, "I2C%u device not found\n", bus); - return -1; - } - - /* Look up the controller device in the devicetree */ - dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); - tree_dev = dev_find_slot(0, devfn); - if (!tree_dev || !tree_dev->enabled) { - printk(BIOS_ERR, "I2C%u device not enabled\n", bus); - return -1; - } - - /* Skip if not enabled for early init */ - config = dw_i2c_get_soc_cfg(bus); - if (!config || !config->early_init) { - printk(BIOS_DEBUG, "I2C%u not enabled for early init\n", bus); - return -1; - } - - /* Prepare early base address for access before memory */ - base = dw_i2c_get_soc_early_base(bus); - pci_write_config32(dev, PCI_BASE_ADDRESS_0, base); - pci_write_config32(dev, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Take device out of reset */ - lpss_reset_release(base); - - /* Initialize the controller */ - if (dw_i2c_init(bus, config) < 0) { - printk(BIOS_ERR, "I2C%u failed to initialize\n", bus); - return -1; - } - - return 0; -} - -uintptr_t dw_i2c_base_address(unsigned int bus) -{ - int devfn; - pci_devfn_t dev; - uintptr_t base; - - /* Find device+function for this controller */ - devfn = dw_i2c_soc_bus_to_devfn(bus); - if (devfn < 0) - return (uintptr_t)NULL; - - /* Form a PCI address for this device */ - dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); - - /* Read the first base address for this device */ - base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16); - - /* Attempt to initialize bus if base is not set yet */ - if (!base && !lpss_i2c_early_init_bus(bus)) - base = ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), - 16); - return base; -} diff --git a/src/soc/intel/skylake/i2c.c b/src/soc/intel/skylake/i2c.c index c9070fe5a0..9fd9bf39e6 100644 --- a/src/soc/intel/skylake/i2c.c +++ b/src/soc/intel/skylake/i2c.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright 2016 Google Inc. + * Copyright (C) 2018 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,26 +14,10 @@ * GNU General Public License for more details. */ -#include <console/console.h> #include <device/device.h> #include <intelblocks/chip.h> #include <drivers/i2c/designware/dw_i2c.h> -#include <soc/iomap.h> #include <soc/pci_devs.h> -#include "chip.h" - -const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus) -{ - const struct soc_intel_common_config *common_config; - common_config = chip_get_common_soc_structure(); - - return &common_config->i2c[bus]; -} - -uintptr_t dw_i2c_get_soc_early_base(unsigned int bus) -{ - return EARLY_I2C_BASE(bus); -} int dw_i2c_soc_devfn_to_bus(unsigned int devfn) { |