[U-Boot] [PATCH v3 00/10] x86: minnowmax: Add interrupt support

This series brings in interrupt support for Minnowmax, so that PCI interrupts are correctly set up for Linux. It also includes a few small improvements to FSP support.
Changes in v3: - Drop the inner while() loop in skip_to_next_device() - it isn't needed - Drop unnecessary blank lines - Add PCIe root ports from bayleybay - Drop interrupt.h header include - Add new patch to add a simple interrupt script to the README
Changes in v2: - Correct 'Driver mode' typo - Add blank line after dm_pci_read_config() declaration - Add a comment as to why we need to scan multiple PCI controllers - Rebase to mainline - Fix handling of duplicate entries - Add new patch to allow pirq_init() to return an error - Use pirq_init() instead of custom code - Add new patch to tidy up interrupt and FSP init - Add new patch to support running as an EFI payload
Simon Glass (10): dm: pci: Provide friendly config access functions dm: pci: Add a way to iterate through all PCI devices x86: Re-order efi-x86_defconfig x86: Tidy up the PIRQ routing code a little x86: Split out fsp_init_phase_pci() code into a new function x86: Allow pirq_init() to return an error x86: minnowmax: Define and enable interrupt setup x86: baytrail: Tidy up interrupt and FSP init x86: Add a simple interrupt script to the README x86: baytrail: Support running as an EFI payload
arch/x86/cpu/baytrail/valleyview.c | 11 ++- arch/x86/cpu/irq.c | 58 ++++++-------- arch/x86/cpu/qemu/qemu.c | 4 +- arch/x86/cpu/quark/quark.c | 4 +- arch/x86/cpu/queensbay/tnc.c | 4 +- arch/x86/dts/minnowmax.dts | 59 +++++++++++++- arch/x86/include/asm/fsp/fsp_support.h | 7 ++ arch/x86/include/asm/irq.h | 4 +- arch/x86/lib/fsp/fsp_common.c | 11 ++- configs/efi-x86_defconfig | 10 +-- configs/minnowmax_defconfig | 10 +-- doc/README.x86 | 14 ++++ drivers/pci/pci-uclass.c | 136 +++++++++++++++++++++++++++++++++ include/configs/minnowmax.h | 1 + include/pci.h | 43 +++++++++++ 15 files changed, 314 insertions(+), 62 deletions(-)

At present there are no PCI functions which allow access to PCI configuration using a struct udevice. This is a sad situation for driver model as it makes use of PCI harder. Add these functions.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: - Correct 'Driver mode' typo - Add blank line after dm_pci_read_config() declaration
drivers/pci/pci-uclass.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 18 ++++++++++++ 2 files changed, 94 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 6262f35..b79927e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -210,6 +210,17 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, return pci_bus_write_config(bus, bdf, offset, value, size); }
+int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value, + enum pci_size_t size) +{ + struct udevice *bus; + + for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) + bus = bus->parent; + return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size); +} + + int pci_write_config32(pci_dev_t bdf, int offset, u32 value) { return pci_write_config(bdf, offset, value, PCI_SIZE_32); @@ -225,6 +236,21 @@ int pci_write_config8(pci_dev_t bdf, int offset, u8 value) return pci_write_config(bdf, offset, value, PCI_SIZE_8); }
+int dm_pci_write_config8(struct udevice *dev, int offset, u8 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_8); +} + +int dm_pci_write_config16(struct udevice *dev, int offset, u16 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_16); +} + +int dm_pci_write_config32(struct udevice *dev, int offset, u32 value) +{ + return dm_pci_write_config(dev, offset, value, PCI_SIZE_32); +} + int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long *valuep, enum pci_size_t size) { @@ -249,6 +275,17 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, return pci_bus_read_config(bus, bdf, offset, valuep, size); }
+int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep, + enum pci_size_t size) +{ + struct udevice *bus; + + for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;) + bus = bus->parent; + return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep, + size); +} + int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) { unsigned long value; @@ -288,6 +325,45 @@ int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep) return 0; }
+int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_8); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_16); + if (ret) + return ret; + *valuep = value; + + return 0; +} + +int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep) +{ + unsigned long value; + int ret; + + ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_32); + if (ret) + return ret; + *valuep = value; + + return 0; +} + int pci_auto_config_devices(struct udevice *bus) { struct pci_controller *hose = bus->uclass_priv; diff --git a/include/pci.h b/include/pci.h index 628ede0..d1e2765 100644 --- a/include/pci.h +++ b/include/pci.h @@ -988,6 +988,24 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long value, enum pci_size_t size);
+/** + * Driver model PCI config access functions. Use these in preference to others + * when you have a valid device + */ +int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep, + enum pci_size_t size); + +int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep); +int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep); +int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep); + +int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value, + enum pci_size_t size); + +int dm_pci_write_config8(struct udevice *dev, int offset, u8 value); +int dm_pci_write_config16(struct udevice *dev, int offset, u16 value); +int dm_pci_write_config32(struct udevice *dev, int offset, u32 value); + /* * The following functions provide access to the above without needing the * size parameter. We are trying to encourage the use of the 8/16/32-style

On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
At present there are no PCI functions which allow access to PCI configuration using a struct udevice. This is a sad situation for driver model as it makes use of PCI harder. Add these functions.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Correct 'Driver mode' typo
- Add blank line after dm_pci_read_config() declaration
drivers/pci/pci-uclass.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 18 ++++++++++++ 2 files changed, 94 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 6262f35..b79927e 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -210,6 +210,17 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value, return pci_bus_write_config(bus, bdf, offset, value, size); }
+int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
enum pci_size_t size)
+{
struct udevice *bus;
for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;)
bus = bus->parent;
return pci_bus_write_config(bus, pci_get_bdf(dev), offset, value, size);
+}
int pci_write_config32(pci_dev_t bdf, int offset, u32 value) { return pci_write_config(bdf, offset, value, PCI_SIZE_32); @@ -225,6 +236,21 @@ int pci_write_config8(pci_dev_t bdf, int offset, u8 value) return pci_write_config(bdf, offset, value, PCI_SIZE_8); }
+int dm_pci_write_config8(struct udevice *dev, int offset, u8 value) +{
return dm_pci_write_config(dev, offset, value, PCI_SIZE_8);
+}
+int dm_pci_write_config16(struct udevice *dev, int offset, u16 value) +{
return dm_pci_write_config(dev, offset, value, PCI_SIZE_16);
+}
+int dm_pci_write_config32(struct udevice *dev, int offset, u32 value) +{
return dm_pci_write_config(dev, offset, value, PCI_SIZE_32);
+}
int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long *valuep, enum pci_size_t size) { @@ -249,6 +275,17 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep, return pci_bus_read_config(bus, bdf, offset, valuep, size); }
+int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
enum pci_size_t size)
+{
struct udevice *bus;
for (bus = dev; device_get_uclass_id(bus->parent) == UCLASS_PCI;)
bus = bus->parent;
return pci_bus_read_config(bus, pci_get_bdf(dev), offset, valuep,
size);
+}
int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep) { unsigned long value; @@ -288,6 +325,45 @@ int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep) return 0; }
+int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep) +{
unsigned long value;
int ret;
ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_8);
if (ret)
return ret;
*valuep = value;
return 0;
+}
+int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep) +{
unsigned long value;
int ret;
ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_16);
if (ret)
return ret;
*valuep = value;
return 0;
+}
+int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep) +{
unsigned long value;
int ret;
ret = dm_pci_read_config(dev, offset, &value, PCI_SIZE_32);
if (ret)
return ret;
*valuep = value;
return 0;
+}
int pci_auto_config_devices(struct udevice *bus) { struct pci_controller *hose = bus->uclass_priv; diff --git a/include/pci.h b/include/pci.h index 628ede0..d1e2765 100644 --- a/include/pci.h +++ b/include/pci.h @@ -988,6 +988,24 @@ int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset, int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset, unsigned long value, enum pci_size_t size);
+/**
- Driver model PCI config access functions. Use these in preference to others
- when you have a valid device
- */
+int dm_pci_read_config(struct udevice *dev, int offset, unsigned long *valuep,
enum pci_size_t size);
+int dm_pci_read_config8(struct udevice *dev, int offset, u8 *valuep); +int dm_pci_read_config16(struct udevice *dev, int offset, u16 *valuep); +int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep);
+int dm_pci_write_config(struct udevice *dev, int offset, unsigned long value,
enum pci_size_t size);
+int dm_pci_write_config8(struct udevice *dev, int offset, u8 value); +int dm_pci_write_config16(struct udevice *dev, int offset, u16 value); +int dm_pci_write_config32(struct udevice *dev, int offset, u32 value);
/*
- The following functions provide access to the above without needing the
- size parameter. We are trying to encourage the use of the 8/16/32-style
--
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 10 August 2015 at 22:11, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
At present there are no PCI functions which allow access to PCI configuration using a struct udevice. This is a sad situation for driver model as it makes use of PCI harder. Add these functions.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Correct 'Driver mode' typo
- Add blank line after dm_pci_read_config() declaration
drivers/pci/pci-uclass.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 18 ++++++++++++ 2 files changed, 94 insertions(+)
[snip]
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86

These functions allow iteration through all PCI devices including bridges. The children of each PCI bus are returned in turn. This can be useful for configuring, checking or enumerating all the devices.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Drop the inner while() loop in skip_to_next_device() - it isn't needed
Changes in v2: - Add a comment as to why we need to scan multiple PCI controllers
drivers/pci/pci-uclass.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 25 ++++++++++++++++++++ 2 files changed, 85 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index b79927e..ad65427 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -775,6 +775,66 @@ static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); }
+static int skip_to_next_device(struct udevice *bus, struct udevice **devp) +{ + struct udevice *dev; + int ret = 0; + + /* + * Scan through all the PCI controllers. On x86 there will only be one + * but that is not necessarily true on other hardware. + */ + do { + device_find_first_child(bus, &dev); + if (dev) { + *devp = dev; + return 0; + } + ret = uclass_next_device(&bus); + if (ret) + return ret; + } while (bus); + + return 0; +} + +int pci_find_next_device(struct udevice **devp) +{ + struct udevice *child = *devp; + struct udevice *bus = child->parent; + int ret; + + /* First try all the siblings */ + *devp = NULL; + while (child) { + device_find_next_child(&child); + if (child) { + *devp = child; + return 0; + } + } + + /* We ran out of siblings. Try the next bus */ + ret = uclass_next_device(&bus); + if (ret) + return ret; + + return bus ? skip_to_next_device(bus, devp) : 0; +} + +int pci_find_first_device(struct udevice **devp) +{ + struct udevice *bus; + int ret; + + *devp = NULL; + ret = uclass_first_device(UCLASS_PCI, &bus); + if (ret) + return ret; + + return skip_to_next_device(bus, devp); +} + UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index d1e2765..488ff44 100644 --- a/include/pci.h +++ b/include/pci.h @@ -910,6 +910,31 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, struct udevice **devp);
/** + * pci_find_first_device() - return the first available PCI device + * + * This function and pci_find_first_device() allow iteration through all + * available PCI devices on all buses. Assuming there are any, this will + * return the first one. + * + * @devp: Set to the first available device, or NULL if no more are left + * or we got an error + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) + */ +int pci_find_first_device(struct udevice **devp); + +/** + * pci_find_next_device() - return the next available PCI device + * + * Finds the next available PCI device after the one supplied, or sets @devp + * to NULL if there are no more. + * + * @devp: On entry, the last device returned. Set to the next available + * device, or NULL if no more are left or we got an error + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) + */ +int pci_find_next_device(struct udevice **devp); + +/** * pci_get_ff() - Returns a mask for the given access size * * @size: Access size

On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
These functions allow iteration through all PCI devices including bridges. The children of each PCI bus are returned in turn. This can be useful for configuring, checking or enumerating all the devices.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Drop the inner while() loop in skip_to_next_device() - it isn't needed
Changes in v2:
- Add a comment as to why we need to scan multiple PCI controllers
drivers/pci/pci-uclass.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 25 ++++++++++++++++++++ 2 files changed, 85 insertions(+)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index b79927e..ad65427 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -775,6 +775,66 @@ static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf, return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); }
+static int skip_to_next_device(struct udevice *bus, struct udevice **devp) +{
struct udevice *dev;
int ret = 0;
/*
* Scan through all the PCI controllers. On x86 there will only be one
* but that is not necessarily true on other hardware.
*/
do {
device_find_first_child(bus, &dev);
if (dev) {
*devp = dev;
return 0;
}
ret = uclass_next_device(&bus);
if (ret)
return ret;
} while (bus);
return 0;
+}
+int pci_find_next_device(struct udevice **devp) +{
struct udevice *child = *devp;
struct udevice *bus = child->parent;
int ret;
/* First try all the siblings */
*devp = NULL;
while (child) {
device_find_next_child(&child);
if (child) {
*devp = child;
return 0;
}
}
/* We ran out of siblings. Try the next bus */
ret = uclass_next_device(&bus);
if (ret)
return ret;
return bus ? skip_to_next_device(bus, devp) : 0;
+}
+int pci_find_first_device(struct udevice **devp) +{
struct udevice *bus;
int ret;
*devp = NULL;
ret = uclass_first_device(UCLASS_PCI, &bus);
if (ret)
return ret;
return skip_to_next_device(bus, devp);
+}
UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index d1e2765..488ff44 100644 --- a/include/pci.h +++ b/include/pci.h @@ -910,6 +910,31 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn, struct udevice **devp);
/**
- pci_find_first_device() - return the first available PCI device
- This function and pci_find_first_device() allow iteration through all
- available PCI devices on all buses. Assuming there are any, this will
- return the first one.
- @devp: Set to the first available device, or NULL if no more are left
or we got an error
- @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe)
- */
+int pci_find_first_device(struct udevice **devp);
+/**
- pci_find_next_device() - return the next available PCI device
- Finds the next available PCI device after the one supplied, or sets @devp
- to NULL if there are no more.
- @devp: On entry, the last device returned. Set to the next available
device, or NULL if no more are left or we got an error
- @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe)
- */
+int pci_find_next_device(struct udevice **devp);
+/**
- pci_get_ff() - Returns a mask for the given access size
- @size: Access size
--
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 10 August 2015 at 22:14, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
These functions allow iteration through all PCI devices including bridges. The children of each PCI bus are returned in turn. This can be useful for configuring, checking or enumerating all the devices.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Drop the inner while() loop in skip_to_next_device() - it isn't needed
Changes in v2:
- Add a comment as to why we need to scan multiple PCI controllers
drivers/pci/pci-uclass.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 25 ++++++++++++++++++++ 2 files changed, 85 insertions(+)
[snip]
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86

Use savedefconfig to get this file into the correct order.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: - Rebase to mainline
configs/efi-x86_defconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig index 1aa0655..43fb0c4 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_defconfig @@ -1,16 +1,16 @@ CONFIG_X86=y CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi" CONFIG_TARGET_EFI=y CONFIG_TSC_CALIBRATION_BYPASS=y +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_NET is not set CONFIG_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DM_PCI=y -CONFIG_DEFAULT_DEVICE_TREE="efi" -CONFIG_EFI=y -CONFIG_EFI_APP=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_EFI_CONSOLE=y CONFIG_DEBUG_UART_BASE=0 CONFIG_DEBUG_UART_CLOCK=0 -# CONFIG_CMD_NET is not set -# CONFIG_CMD_BOOTM is not set +# CONFIG_X86_SERIAL is not set +CONFIG_EFI=y

On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
Use savedefconfig to get this file into the correct order.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Rebase to mainline
configs/efi-x86_defconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig index 1aa0655..43fb0c4 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_defconfig @@ -1,16 +1,16 @@ CONFIG_X86=y CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi" CONFIG_TARGET_EFI=y CONFIG_TSC_CALIBRATION_BYPASS=y +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_NET is not set CONFIG_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DM_PCI=y -CONFIG_DEFAULT_DEVICE_TREE="efi" -CONFIG_EFI=y -CONFIG_EFI_APP=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_EFI_CONSOLE=y CONFIG_DEBUG_UART_BASE=0 CONFIG_DEBUG_UART_CLOCK=0 -# CONFIG_CMD_NET is not set -# CONFIG_CMD_BOOTM is not set +# CONFIG_X86_SERIAL is not set
+CONFIG_EFI=y
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 10 August 2015 at 22:54, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
Use savedefconfig to get this file into the correct order.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Rebase to mainline
configs/efi-x86_defconfig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/configs/efi-x86_defconfig b/configs/efi-x86_defconfig index 1aa0655..43fb0c4 100644 --- a/configs/efi-x86_defconfig +++ b/configs/efi-x86_defconfig @@ -1,16 +1,16 @@ CONFIG_X86=y CONFIG_VENDOR_EFI=y +CONFIG_DEFAULT_DEVICE_TREE="efi" CONFIG_TARGET_EFI=y CONFIG_TSC_CALIBRATION_BYPASS=y +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_NET is not set CONFIG_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DM_PCI=y -CONFIG_DEFAULT_DEVICE_TREE="efi" -CONFIG_EFI=y -CONFIG_EFI_APP=y CONFIG_DEBUG_UART=y CONFIG_DEBUG_EFI_CONSOLE=y CONFIG_DEBUG_UART_BASE=0 CONFIG_DEBUG_UART_CLOCK=0 -# CONFIG_CMD_NET is not set -# CONFIG_CMD_BOOTM is not set +# CONFIG_X86_SERIAL is not set
+CONFIG_EFI=y
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86

This code could use a little tightening up. There is some repetition and an odd use of fdtdec_get_int_array().
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: - Fix handling of duplicate entries
arch/x86/cpu/irq.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-)
diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 97dd000..6be2f81 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -125,10 +125,10 @@ static int create_pirq_routing_table(void) return -EINVAL; }
- ret = fdtdec_get_int_array(blob, node, "intel,pirq-link", - &irq_router.link_base, 1); - if (ret) + ret = fdtdec_get_int(blob, node, "intel,pirq-link", -1); + if (ret == -1) return ret; + irq_router.link_base = ret;
irq_router.irq_mask = fdtdec_get_int(blob, node, "intel,pirq-mask", PIRQ_BITMAP); @@ -156,18 +156,13 @@ static int create_pirq_routing_table(void) }
cell = fdt_getprop(blob, node, "intel,pirq-routing", &len); - if (!cell) - return -EINVAL; - - if ((len % sizeof(struct pirq_routing)) == 0) - count = len / sizeof(struct pirq_routing); - else + if (!cell || len % sizeof(struct pirq_routing)) return -EINVAL; + count = len / sizeof(struct pirq_routing);
- rt = malloc(sizeof(struct irq_routing_table)); + rt = calloc(1, sizeof(struct irq_routing_table)); if (!rt) return -ENOMEM; - memset((char *)rt, 0, sizeof(struct irq_routing_table));
/* Populate the PIRQ table fields */ rt->signature = PIRQ_SIGNATURE; @@ -181,7 +176,8 @@ static int create_pirq_routing_table(void) slot_base = rt->slots;
/* Now fill in the irq_info entries in the PIRQ table */ - for (i = 0; i < count; i++) { + for (i = 0; i < count; + i++, cell += sizeof(struct pirq_routing) / sizeof(u32)) { struct pirq_routing pr;
pr.bdf = fdt_addr_to_cpu(cell[0]); @@ -212,25 +208,14 @@ static int create_pirq_routing_table(void) if (slot->irq[pr.pin - 1].link != LINK_N2V(pr.pirq, irq_router.link_base)) debug("WARNING: Inconsistent PIRQ routing information\n"); - - cell += sizeof(struct pirq_routing) / - sizeof(u32); - continue; - } else { - debug("writing INT%c\n", 'A' + pr.pin - 1); - fill_irq_info(slot, PCI_BUS(pr.bdf), - PCI_DEV(pr.bdf), pr.pin, pr.pirq); - cell += sizeof(struct pirq_routing) / - sizeof(u32); continue; } + } else { + slot = slot_base + irq_entries++; } - - slot = slot_base + irq_entries; - fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), - pr.pin, pr.pirq); - irq_entries++; - cell += sizeof(struct pirq_routing) / sizeof(u32); + debug("writing INT%c\n", 'A' + pr.pin - 1); + fill_irq_info(slot, PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin, + pr.pirq); }
rt->size = irq_entries * sizeof(struct irq_info) + 32;

On 10 August 2015 at 07:05, Simon Glass sjg@chromium.org wrote:
This code could use a little tightening up. There is some repetition and an odd use of fdtdec_get_int_array().
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com Tested-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2:
- Fix handling of duplicate entries
arch/x86/cpu/irq.c | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-)
Applied to u-boot-x86

This code may be useful for boards that use driver model for PCI.
Note: It would be better to have driver model automatically call this function somehow. However for now it is probably safer to have it under board control.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: None
arch/x86/include/asm/fsp/fsp_support.h | 7 +++++++ arch/x86/lib/fsp/fsp_common.c | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/fsp/fsp_support.h b/arch/x86/include/asm/fsp/fsp_support.h index c6c7dc0..7317dda 100644 --- a/arch/x86/include/asm/fsp/fsp_support.h +++ b/arch/x86/include/asm/fsp/fsp_support.h @@ -207,4 +207,11 @@ void *fsp_get_bootloader_tmp_mem(const void *hob_list, u32 *len); */ void update_fsp_upd(struct upd_region *fsp_upd);
+/** + * fsp_init_phase_pci() - Tell the FSP that we have completed PCI init + * + * @return 0 if OK, -EPERM if the FSP gave an error. + */ +int fsp_init_phase_pci(void); + #endif diff --git a/arch/x86/lib/fsp/fsp_common.c b/arch/x86/lib/fsp/fsp_common.c index c585710..6f72c6d 100644 --- a/arch/x86/lib/fsp/fsp_common.c +++ b/arch/x86/lib/fsp/fsp_common.c @@ -19,19 +19,24 @@ int print_cpuinfo(void) return default_print_cpuinfo(); }
-int board_pci_post_scan(struct pci_controller *hose) +int fsp_init_phase_pci(void) { u32 status;
/* call into FspNotify */ debug("Calling into FSP (notify phase INIT_PHASE_PCI): "); status = fsp_notify(NULL, INIT_PHASE_PCI); - if (status != FSP_SUCCESS) + if (status) debug("fail, error code %x\n", status); else debug("OK\n");
- return 0; + return status ? -EPERM : 0; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + return fsp_init_phase_pci(); }
void board_final_cleanup(void)

On 10 August 2015 at 07:05, Simon Glass sjg@chromium.org wrote:
This code may be useful for boards that use driver model for PCI.
Note: It would be better to have driver model automatically call this function somehow. However for now it is probably safer to have it under board control.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2: None
arch/x86/include/asm/fsp/fsp_support.h | 7 +++++++ arch/x86/lib/fsp/fsp_common.c | 11 ++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-)
Applied to u-boot-x86

This function can fail. In this case we should return the error rather than swallowing it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: - Add new patch to allow pirq_init() to return an error
arch/x86/cpu/baytrail/valleyview.c | 4 +--- arch/x86/cpu/irq.c | 17 +++++++++++------ arch/x86/cpu/qemu/qemu.c | 4 +--- arch/x86/cpu/quark/quark.c | 4 +--- arch/x86/cpu/queensbay/tnc.c | 4 +--- arch/x86/include/asm/irq.h | 4 +++- 6 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 610e9d9..225ea38 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -40,8 +40,6 @@ int arch_cpu_init(void)
int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } #endif diff --git a/arch/x86/cpu/irq.c b/arch/x86/cpu/irq.c index 6be2f81..35b29f6 100644 --- a/arch/x86/cpu/irq.c +++ b/arch/x86/cpu/irq.c @@ -225,17 +225,22 @@ static int create_pirq_routing_table(void) return 0; }
-void pirq_init(void) +int pirq_init(void) { + int ret; + cpu_irq_init();
- if (create_pirq_routing_table()) { + ret = create_pirq_routing_table(); + if (ret) { debug("Failed to create pirq routing table\n"); - } else { - /* Route PIRQ */ - pirq_route_irqs(pirq_routing_table->slots, - get_irq_slot_count(pirq_routing_table)); + return ret; } + /* Route PIRQ */ + pirq_route_irqs(pirq_routing_table->slots, + get_irq_slot_count(pirq_routing_table)); + + return 0; }
u32 write_pirq_routing_table(u32 addr) diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c index 64634a9..7c03e02 100644 --- a/arch/x86/cpu/qemu/qemu.c +++ b/arch/x86/cpu/qemu/qemu.c @@ -41,7 +41,5 @@ void reset_cpu(ulong addr)
int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c index 20cc09e..12ac376 100644 --- a/arch/x86/cpu/quark/quark.c +++ b/arch/x86/cpu/quark/quark.c @@ -174,7 +174,5 @@ void cpu_irq_init(void)
int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c index de50893..c465642 100644 --- a/arch/x86/cpu/queensbay/tnc.c +++ b/arch/x86/cpu/queensbay/tnc.c @@ -80,7 +80,5 @@ void cpu_irq_init(void)
int arch_misc_init(void) { - pirq_init(); - - return 0; + return pirq_init(); } diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 4de5512..6697da3 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -70,7 +70,9 @@ void cpu_irq_init(void); * * This initializes the PIRQ routing on the platform and configures all PCI * devices' interrupt line register to a working IRQ number on the 8259 PIC. + * + * @return 0 if OK, -ve on error */ -void pirq_init(void); +int pirq_init(void);
#endif /* _ARCH_IRQ_H_ */

On 10 August 2015 at 07:05, Simon Glass sjg@chromium.org wrote:
This function can fail. In this case we should return the error rather than swallowing it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2:
- Add new patch to allow pirq_init() to return an error
arch/x86/cpu/baytrail/valleyview.c | 4 +--- arch/x86/cpu/irq.c | 17 +++++++++++------ arch/x86/cpu/qemu/qemu.c | 4 +--- arch/x86/cpu/quark/quark.c | 4 +--- arch/x86/cpu/queensbay/tnc.c | 4 +--- arch/x86/include/asm/irq.h | 4 +++- 6 files changed, 18 insertions(+), 19 deletions(-)
Applied to u-boot-x86

Set up interrupts correctly so that Linux can use all devices. Use savedefconfig to regenerate the defconfig file.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Drop unnecessary blank lines - Add PCIe root ports from bayleybay
Changes in v2: - Use pirq_init() instead of custom code
arch/x86/dts/minnowmax.dts | 59 ++++++++++++++++++++++++++++++++++++++++++--- configs/minnowmax_defconfig | 10 ++++---- include/configs/minnowmax.h | 1 + 3 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 9527233..25611bb9 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -7,6 +7,7 @@ /dts-v1/;
#include <dt-bindings/gpio/x86-gpio.h> +#include <dt-bindings/interrupt-router/intel-irq.h>
/include/ "skeleton.dtsi" /include/ "serial.dtsi" @@ -117,9 +118,61 @@ #address-cells = <3>; #size-cells = <2>; u-boot,dm-pre-reloc; - ranges = <0x02000000 0x0 0xd0000000 0xd0000000 0 0x10000000 - 0x42000000 0x0 0xc0000000 0xc0000000 0 0x10000000 - 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000 + 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + + irq-router@1f,0 { + reg = <0x0000f800 0 0 0 0>; + compatible = "intel,irq-router"; + intel,pirq-config = "ibase"; + intel,ibase-offset = <0x50>; + intel,pirq-link = <8 8>; + intel,pirq-mask = <0xdcb0>; + intel,pirq-routing = < + /* BayTrail PCI devices */ + PCI_BDF(0x00, 0x02, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x11, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x12, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x13, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x15, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x18, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x18, 0x02) INTD PIRQD + PCI_BDF(0x00, 0x18, 0x06) INTD PIRQD + PCI_BDF(0x00, 0x18, 0x07) INTB PIRQB + PCI_BDF(0x00, 0x1a, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x1b, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x1c, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x1c, 0x02) INTC PIRQC + PCI_BDF(0x00, 0x1c, 0x03) INTD PIRQD + PCI_BDF(0x00, 0x1d, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x1e, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x1e, 0x01) INTD PIRQD + PCI_BDF(0x00, 0x1e, 0x02) INTB PIRQB + PCI_BDF(0x00, 0x1e, 0x03) INTC PIRQC + PCI_BDF(0x00, 0x1e, 0x04) INTD PIRQD + PCI_BDF(0x00, 0x1e, 0x05) INTB PIRQB + PCI_BDF(0x00, 0x1f, 0x03) INTB PIRQB + + /* PCIe root ports downstream interrupts */ + PCI_BDF(1, 0, 0) INTA PIRQA + PCI_BDF(1, 0, 0) INTB PIRQB + PCI_BDF(1, 0, 0) INTC PIRQC + PCI_BDF(1, 0, 0) INTD PIRQD + PCI_BDF(2, 0, 0) INTA PIRQB + PCI_BDF(2, 0, 0) INTB PIRQC + PCI_BDF(2, 0, 0) INTC PIRQD + PCI_BDF(2, 0, 0) INTD PIRQA + PCI_BDF(3, 0, 0) INTA PIRQC + PCI_BDF(3, 0, 0) INTB PIRQD + PCI_BDF(3, 0, 0) INTC PIRQA + PCI_BDF(3, 0, 0) INTD PIRQB + PCI_BDF(4, 0, 0) INTA PIRQD + PCI_BDF(4, 0, 0) INTB PIRQA + PCI_BDF(4, 0, 0) INTC PIRQB + PCI_BDF(4, 0, 0) INTD PIRQC + >; + }; };
spi { diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index a67597d..9af4aa3 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -5,7 +5,8 @@ CONFIG_TARGET_MINNOWMAX=y CONFIG_HAVE_INTEL_ME=y CONFIG_SMP=y CONFIG_HAVE_VGA_BIOS=y -CONFIG_GENERATE_SFI_TABLE=y +CONFIG_GENERATE_PIRQ_TABLE=y +CONFIG_GENERATE_MP_TABLE=y CONFIG_CMD_CPU=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -18,13 +19,12 @@ CONFIG_OF_CONTROL=y CONFIG_CPU=y CONFIG_DM_PCI=y CONFIG_SPI_FLASH=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x3f8 +CONFIG_DEBUG_UART_CLOCK=1843200 CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y CONFIG_DM_RTC=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_SYS_VSNPRINTF=y -CONFIG_DEBUG_UART=y -CONFIG_DEBUG_UART_NS16550=y -CONFIG_DEBUG_UART_BASE=0x3f8 -CONFIG_DEBUG_UART_CLOCK=1843200 diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 64fa676..aeb04b9 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -15,6 +15,7 @@
#define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_ARCH_EARLY_INIT_R +#define CONFIG_ARCH_MISC_INIT
#define CONFIG_SMSC_LPC47M

Hi Simon,
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
Set up interrupts correctly so that Linux can use all devices. Use savedefconfig to regenerate the defconfig file.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Drop unnecessary blank lines
- Add PCIe root ports from bayleybay
Changes in v2:
- Use pirq_init() instead of custom code
arch/x86/dts/minnowmax.dts | 59 ++++++++++++++++++++++++++++++++++++++++++--- configs/minnowmax_defconfig | 10 ++++---- include/configs/minnowmax.h | 1 + 3 files changed, 62 insertions(+), 8 deletions(-)
diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 9527233..25611bb9 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -7,6 +7,7 @@ /dts-v1/;
#include <dt-bindings/gpio/x86-gpio.h> +#include <dt-bindings/interrupt-router/intel-irq.h>
/include/ "skeleton.dtsi" /include/ "serial.dtsi" @@ -117,9 +118,61 @@ #address-cells = <3>; #size-cells = <2>; u-boot,dm-pre-reloc;
ranges = <0x02000000 0x0 0xd0000000 0xd0000000 0 0x10000000
0x42000000 0x0 0xc0000000 0xc0000000 0 0x10000000
0x01000000 0x0 0x2000 0x2000 0 0xe000>;
ranges = <0x02000000 0x0 0x80000000 0x80000000 0 0x40000000
0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
0x01000000 0x0 0x2000 0x2000 0 0xe000>;
irq-router@1f,0 {
reg = <0x0000f800 0 0 0 0>;
compatible = "intel,irq-router";
intel,pirq-config = "ibase";
intel,ibase-offset = <0x50>;
intel,pirq-link = <8 8>;
intel,pirq-mask = <0xdcb0>;
intel,pirq-routing = <
/* BayTrail PCI devices */
PCI_BDF(0x00, 0x02, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x11, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x12, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x13, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x15, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x18, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x18, 0x02) INTD PIRQD
PCI_BDF(0x00, 0x18, 0x06) INTD PIRQD
PCI_BDF(0x00, 0x18, 0x07) INTB PIRQB
PCI_BDF(0x00, 0x1a, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x1b, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x1c, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x1c, 0x02) INTC PIRQC
PCI_BDF(0x00, 0x1c, 0x03) INTD PIRQD
PCI_BDF(0x00, 0x1d, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x1e, 0x00) INTA PIRQA
PCI_BDF(0x00, 0x1e, 0x01) INTD PIRQD
PCI_BDF(0x00, 0x1e, 0x02) INTB PIRQB
PCI_BDF(0x00, 0x1e, 0x03) INTC PIRQC
PCI_BDF(0x00, 0x1e, 0x04) INTD PIRQD
PCI_BDF(0x00, 0x1e, 0x05) INTB PIRQB
PCI_BDF(0x00, 0x1f, 0x03) INTB PIRQB
Sorry, but I still want these baytrail boards' device trees be in sync. There is no harm that we put disabled device here as U-Boot won't able to program the IRQ anyway.
1). Nits: can we avoid using 0x prefix? This is to keep consistent naming convention as the datasheet. Converting hex numbers needs some brain work :) 2). I see device 28 you only listed function 0/2/3. Why is root port 2 (function 1) missing?
/* PCIe root ports downstream interrupts */
PCI_BDF(1, 0, 0) INTA PIRQA
PCI_BDF(1, 0, 0) INTB PIRQB
PCI_BDF(1, 0, 0) INTC PIRQC
PCI_BDF(1, 0, 0) INTD PIRQD
PCI_BDF(2, 0, 0) INTA PIRQB
PCI_BDF(2, 0, 0) INTB PIRQC
PCI_BDF(2, 0, 0) INTC PIRQD
PCI_BDF(2, 0, 0) INTD PIRQA
PCI_BDF(3, 0, 0) INTA PIRQC
PCI_BDF(3, 0, 0) INTB PIRQD
PCI_BDF(3, 0, 0) INTC PIRQA
PCI_BDF(3, 0, 0) INTD PIRQB
PCI_BDF(4, 0, 0) INTA PIRQD
PCI_BDF(4, 0, 0) INTB PIRQA
PCI_BDF(4, 0, 0) INTC PIRQB
PCI_BDF(4, 0, 0) INTD PIRQC
>;
};
If U-Boot cannot see root port 2 on MinnowMax, then this routing table from BayleyBay does not work for MinnowMax as there will be no bus 4.
}; spi {
diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index a67597d..9af4aa3 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -5,7 +5,8 @@ CONFIG_TARGET_MINNOWMAX=y CONFIG_HAVE_INTEL_ME=y CONFIG_SMP=y CONFIG_HAVE_VGA_BIOS=y -CONFIG_GENERATE_SFI_TABLE=y +CONFIG_GENERATE_PIRQ_TABLE=y +CONFIG_GENERATE_MP_TABLE=y CONFIG_CMD_CPU=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set @@ -18,13 +19,12 @@ CONFIG_OF_CONTROL=y CONFIG_CPU=y CONFIG_DM_PCI=y CONFIG_SPI_FLASH=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x3f8 +CONFIG_DEBUG_UART_CLOCK=1843200 CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y CONFIG_DM_RTC=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_SYS_VSNPRINTF=y -CONFIG_DEBUG_UART=y -CONFIG_DEBUG_UART_NS16550=y -CONFIG_DEBUG_UART_BASE=0x3f8 -CONFIG_DEBUG_UART_CLOCK=1843200 diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 64fa676..aeb04b9 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -15,6 +15,7 @@
#define CONFIG_SYS_MONITOR_LEN (1 << 20) #define CONFIG_ARCH_EARLY_INIT_R +#define CONFIG_ARCH_MISC_INIT
#define CONFIG_SMSC_LPC47M
--
Regards, Bin

We should signal to the FSP that PCI enumeration is complete. Perform this task in a suitable place.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Drop interrupt.h header include
Changes in v2: - Add new patch to tidy up interrupt and FSP init
arch/x86/cpu/baytrail/valleyview.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 225ea38..2d5a0eb 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -9,6 +9,7 @@ #include <pci_ids.h> #include <asm/irq.h> #include <asm/post.h> +#include <asm/fsp/fsp_support.h>
static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, @@ -40,6 +41,12 @@ int arch_cpu_init(void)
int arch_misc_init(void) { - return pirq_init(); + int ret; + + ret = pirq_init(); + if (ret) + return ret; + + return fsp_init_phase_pci(); } #endif

On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
We should signal to the FSP that PCI enumeration is complete. Perform this task in a suitable place.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Drop interrupt.h header include
Changes in v2:
- Add new patch to tidy up interrupt and FSP init
arch/x86/cpu/baytrail/valleyview.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 225ea38..2d5a0eb 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -9,6 +9,7 @@ #include <pci_ids.h> #include <asm/irq.h> #include <asm/post.h> +#include <asm/fsp/fsp_support.h>
static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, @@ -40,6 +41,12 @@ int arch_cpu_init(void)
int arch_misc_init(void) {
return pirq_init();
int ret;
ret = pirq_init();
if (ret)
return ret;
return fsp_init_phase_pci();
}
#endif
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On 10 August 2015 at 23:16, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
We should signal to the FSP that PCI enumeration is complete. Perform this task in a suitable place.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Drop interrupt.h header include
Changes in v2:
- Add new patch to tidy up interrupt and FSP init
arch/x86/cpu/baytrail/valleyview.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 225ea38..2d5a0eb 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -9,6 +9,7 @@ #include <pci_ids.h> #include <asm/irq.h> #include <asm/post.h> +#include <asm/fsp/fsp_support.h>
static struct pci_device_id mmc_supported[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, @@ -40,6 +41,12 @@ int arch_cpu_init(void)
int arch_misc_init(void) {
return pirq_init();
int ret;
ret = pirq_init();
if (ret)
return ret;
return fsp_init_phase_pci();
}
#endif
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Applied to u-boot-x86

It is a bit tedious to figure out the interrupt configuration for a new x86 platform. Add a script which can do this, based on the output of 'pci long'. This may be helpful in some cases.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add new patch to add a simple interrupt script to the README
Changes in v2: None
doc/README.x86 | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/doc/README.x86 b/doc/README.x86 index af2459c..1e8be8f 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -708,6 +708,20 @@ allocation and assignment will be done by U-Boot automatically. Now you can enable CONFIG_GENERATE_PIRQ_TABLE for testing Linux kernel using i8259 PIC and CONFIG_GENERATE_MP_TABLE for testing Linux kernel using local APIC and I/O APIC.
+This script might be useful. If you feed it the output of 'pci long' from +U-Boot then it will generate a device tree fragment with the interrupt +configuration for each device: + + $ cat console_output |awk '/PCI/ {device=$4} /interrupt line/ {line=$4} \ + /interrupt pin/ {pin = $4; if (pin != "0x00") \ + {printf "PCI_BDF(%s) INT%c PIRQ%c\n", device, strtonum(pin) + 64, 64 + \ + strtonum(pin)}}' | sed 's/(..).(..).(..):/0x\1, 0x\2, 0x\3/' + +Example output: + PCI_BDF(0x00, 0x02, 0x00) INTA PIRQA + PCI_BDF(0x00, 0x11, 0x00) INTA PIRQA +... + TODO List --------- - Audio

Hi Simon,
On Mon, Aug 10, 2015 at 9:05 PM, Simon Glass sjg@chromium.org wrote:
It is a bit tedious to figure out the interrupt configuration for a new x86 platform. Add a script which can do this, based on the output of 'pci long'. This may be helpful in some cases.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add new patch to add a simple interrupt script to the README
Changes in v2: None
doc/README.x86 | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/doc/README.x86 b/doc/README.x86 index af2459c..1e8be8f 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -708,6 +708,20 @@ allocation and assignment will be done by U-Boot automatically. Now you can enable CONFIG_GENERATE_PIRQ_TABLE for testing Linux kernel using i8259 PIC and CONFIG_GENERATE_MP_TABLE for testing Linux kernel using local APIC and I/O APIC.
+This script might be useful. If you feed it the output of 'pci long' from +U-Boot then it will generate a device tree fragment with the interrupt +configuration for each device:
- $ cat console_output |awk '/PCI/ {device=$4} /interrupt line/ {line=$4} \
/interrupt pin/ {pin = $4; if (pin != "0x00") \
&& pin != "0xff"
{printf "PCI_BDF(%s) INT%c PIRQ%c\n", device, strtonum(pin) + 64, 64 + \
strtonum(pin)}}' | sed 's/\(..\)\.\(..\)\.\(..\):/0x\1, 0x\2, 0x\3/'
+Example output:
- PCI_BDF(0x00, 0x02, 0x00) INTA PIRQA
- PCI_BDF(0x00, 0x11, 0x00) INTA PIRQA
Nits: can we avoid using hex numbers here?
+...
TODO List
- Audio
--
Regards, Bin

We should not fiddle with interrupts or the FSP when running as an EFI payload. Detect this and skip this code.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v3: None Changes in v2: - Add new patch to support running as an EFI payload
arch/x86/cpu/baytrail/valleyview.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index 2d5a0eb..6c3dfe8 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -43,6 +43,8 @@ int arch_misc_init(void) { int ret;
+ if (!ll_boot_init()) + return 0; ret = pirq_init(); if (ret) return ret;

On 10 August 2015 at 07:05, Simon Glass sjg@chromium.org wrote:
We should not fiddle with interrupts or the FSP when running as an EFI payload. Detect this and skip this code.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v3: None Changes in v2:
- Add new patch to support running as an EFI payload
arch/x86/cpu/baytrail/valleyview.c | 2 ++ 1 file changed, 2 insertions(+)
Applied to u-boot-x86
participants (2)
-
Bin Meng
-
Simon Glass