soc/amd: commonize generation of the PIC/APIC mapping tables

Now that we have a common init_tables in all mainboards using AMD SoCs,
both the population of the fch_pic_routing and fch_apic_routing arrays
and the definition of those arrays can be moved to the common AMD SoC
code to not have the code duplicated in all mainboards.

BUG=b:182782749

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Suggested-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Change-Id: I8c65eca258272f0ef7dec3ece6236f5d00954c66
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68853
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Felix Held 2022-10-26 00:59:13 +02:00
parent c5b32ee8d8
commit cf92ecf6f1
13 changed files with 76 additions and 530 deletions

View File

@ -9,7 +9,6 @@
#include <soc/southbridge.h> #include <soc/southbridge.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/platform_descriptors.h> #include <soc/platform_descriptors.h>
#include <string.h>
#include <types.h> #include <types.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <soc/amd/picasso/chip.h> #include <soc/amd/picasso/chip.h>
@ -20,17 +19,8 @@
/* TODO: recheck IRQ tables */ /* TODO: recheck IRQ tables */
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
static const struct fch_irq_routing fch_irq_map[] = { static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_A, 8, 16 }, { PIRQ_A, 8, 16 },
{ PIRQ_B, 10, 17 }, { PIRQ_B, 10, 17 },
@ -56,41 +46,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void program_display_sel_gpios(void) static void program_display_sel_gpios(void)
{ {
int idx, port_type; int idx, port_type;
@ -125,14 +86,6 @@ static void mainboard_init(void *chip_info)
mainboard_program_emmc_gpios(); mainboard_program_emmc_gpios();
} }
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -2,25 +2,15 @@
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <string.h>
#include <types.h> #include <types.h>
#include "gpio.h" #include "gpio.h"
/* TODO: Update for birman */ /* TODO: Update for birman */
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -61,54 +51,17 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_HPET_H, 0x00, 0x00 }, { PIRQ_HPET_H, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
{ {
mainboard_program_gpios(); mainboard_program_gpios();
} }
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -2,23 +2,13 @@
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <string.h>
#include <types.h> #include <types.h>
#include "gpio.h" #include "gpio.h"
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -59,54 +49,17 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_HPET_H, 0x00, 0x00 }, { PIRQ_HPET_H, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
{ {
mainboard_program_gpios(); mainboard_program_gpios();
} }
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -3,24 +3,13 @@
#include <device/device.h> #include <device/device.h>
#include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper.h>
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <console/console.h>
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/southbridge.h> #include <soc/southbridge.h>
#include <string.h>
#include "gpio.h" #include "gpio.h"
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
static const struct fch_irq_routing fch_irq_map[] = { static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_A, 3, 16 }, { PIRQ_A, 3, 16 },
{ PIRQ_B, 4, 17 }, { PIRQ_B, 4, 17 },
@ -53,42 +42,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
/* PIRQ Setup */
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
{ {
size_t num_gpios; size_t num_gpios;
@ -97,17 +56,6 @@ static void mainboard_init(void *chip_info)
gpio_configure_pads(gpios, num_gpios); gpio_configure_pads(gpios, num_gpios);
} }
/*************************************************
* enable the dedicated function in gardenia board.
*************************************************/
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -2,22 +2,12 @@
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <string.h>
#include <types.h> #include <types.h>
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -59,53 +49,16 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_HPET_H, 0x00, 0x00 }, { PIRQ_HPET_H, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
{ {
} }
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -7,7 +7,6 @@
#include <soc/cpu.h> #include <soc/cpu.h>
#include <soc/southbridge.h> #include <soc/southbridge.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <string.h>
#include <types.h> #include <types.h>
#include <commonlib/helpers.h> #include <commonlib/helpers.h>
#include <soc/amd/picasso/chip.h> #include <soc/amd/picasso/chip.h>
@ -15,17 +14,8 @@
/* TODO: recheck IRQ tables */ /* TODO: recheck IRQ tables */
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
static const struct fch_irq_routing fch_irq_map[] = { static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_A, 8, 16 }, { PIRQ_A, 8, 16 },
{ PIRQ_B, 10, 17 }, { PIRQ_B, 10, 17 },
@ -51,41 +41,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
{ {
struct soc_amd_picasso_config *cfg = config_of_soc(); struct soc_amd_picasso_config *cfg = config_of_soc();
@ -102,14 +63,6 @@ static void mainboard_init(void *chip_info)
mainboard_program_emmc_gpios(); mainboard_program_emmc_gpios();
} }
static void mainboard_enable(struct device *dev)
{
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
}
struct chip_operations mainboard_ops = { struct chip_operations mainboard_ops = {
.init = mainboard_init, .init = mainboard_init,
.enable_dev = mainboard_enable,
}; };

View File

@ -3,25 +3,14 @@
#include <device/device.h> #include <device/device.h>
#include <amdblocks/agesawrapper.h> #include <amdblocks/agesawrapper.h>
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <console/console.h>
#include <soc/gpio.h> #include <soc/gpio.h>
#include <soc/pci_devs.h> #include <soc/pci_devs.h>
#include <soc/southbridge.h> #include <soc/southbridge.h>
#include <string.h>
#include "gpio.h" #include "gpio.h"
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
static const struct fch_irq_routing fch_irq_map[] = { static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_A, 3, 16 }, { PIRQ_A, 3, 16 },
{ PIRQ_B, 4, 17 }, { PIRQ_B, 4, 17 },
@ -54,35 +43,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
/* /*
* This table defines the index into the picr/intr_data tables for each * This table defines the index into the picr/intr_data tables for each
* device. Any enabled device and slot that uses hardware interrupts should * device. Any enabled device and slot that uses hardware interrupts should
@ -113,8 +79,6 @@ static void pirq_setup(void)
{ {
pirq_data_ptr = mainboard_pirq_data; pirq_data_ptr = mainboard_pirq_data;
pirq_data_size = ARRAY_SIZE(mainboard_pirq_data); pirq_data_size = ARRAY_SIZE(mainboard_pirq_data);
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
} }
static void mainboard_init(void *chip_info) static void mainboard_init(void *chip_info)
@ -130,7 +94,6 @@ static void mainboard_init(void *chip_info)
*************************************************/ *************************************************/
static void mainboard_enable(struct device *dev) static void mainboard_enable(struct device *dev)
{ {
init_tables();
/* Initialize the PIRQ data structures for consumption */ /* Initialize the PIRQ data structures for consumption */
pirq_setup(); pirq_setup();
} }

View File

@ -12,7 +12,6 @@
#include <gpio.h> #include <gpio.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <variant/ec.h> #include <variant/ec.h>
#include <string.h>
#define BACKLIGHT_GPIO GPIO_129 #define BACKLIGHT_GPIO GPIO_129
#define WWAN_AUX_RST_GPIO GPIO_18 #define WWAN_AUX_RST_GPIO GPIO_18
@ -23,16 +22,8 @@
#define METHOD_MAINBOARD_PTS "\\_SB.MPTS" #define METHOD_MAINBOARD_PTS "\\_SB.MPTS"
#define METHOD_MAINBOARD_S0X "\\_SB.MS0X" #define METHOD_MAINBOARD_S0X "\\_SB.MS0X"
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -74,41 +65,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_HPET_H, 0x00, 0x00 }, { PIRQ_HPET_H, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_configure_gpios(void) static void mainboard_configure_gpios(void)
{ {
size_t base_num_gpios, override_num_gpios; size_t base_num_gpios, override_num_gpios;
@ -219,10 +181,6 @@ static void mainboard_enable(struct device *dev)
dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
/* TODO: b/184678786 - Move into espi_config */ /* TODO: b/184678786 - Move into espi_config */
/* Unmask eSPI IRQ 1 (Keyboard) */ /* Unmask eSPI IRQ 1 (Keyboard) */
pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1))); pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1)));

View File

@ -18,17 +18,8 @@
#include <variant/ec.h> #include <variant/ec.h>
#include <variant/thermal.h> #include <variant/thermal.h>
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
static const struct fch_irq_routing fch_irq_map[] = { static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_A, 3, 16 }, { PIRQ_A, 3, 16 },
{ PIRQ_B, 4, 17 }, { PIRQ_B, 4, 17 },
@ -61,35 +52,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
/* /*
* This table defines the index into the picr/intr_data tables for each * This table defines the index into the picr/intr_data tables for each
* device. Any enabled device and slot that uses hardware interrupts should * device. Any enabled device and slot that uses hardware interrupts should
@ -117,8 +85,6 @@ static void pirq_setup(void)
{ {
pirq_data_ptr = mainboard_pirq_data; pirq_data_ptr = mainboard_pirq_data;
pirq_data_size = ARRAY_SIZE(mainboard_pirq_data); pirq_data_size = ARRAY_SIZE(mainboard_pirq_data);
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
} }
void __weak variant_devtree_update(void) void __weak variant_devtree_update(void)
@ -165,7 +131,6 @@ static void mainboard_init(void *chip_info)
*************************************************/ *************************************************/
static void mainboard_enable(struct device *dev) static void mainboard_enable(struct device *dev)
{ {
init_tables();
/* Initialize the PIRQ data structures for consumption */ /* Initialize the PIRQ data structures for consumption */
pirq_setup(); pirq_setup();

View File

@ -6,19 +6,10 @@
#include <console/console.h> #include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <soc/acpi.h> #include <soc/acpi.h>
#include <string.h>
#include <variant/ec.h> #include <variant/ec.h>
/* /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -60,41 +51,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_HPET_H, 0x00, 0x00 }, { PIRQ_HPET_H, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_configure_gpios(void) static void mainboard_configure_gpios(void)
{ {
size_t base_num_gpios, override_num_gpios; size_t base_num_gpios, override_num_gpios;
@ -117,10 +79,6 @@ static void mainboard_enable(struct device *dev)
{ {
printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n"); printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n");
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
/* TODO: b/184678786 - Move into espi_config */ /* TODO: b/184678786 - Move into espi_config */
/* Unmask eSPI IRQ 1 (Keyboard) */ /* Unmask eSPI IRQ 1 (Keyboard) */
pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1))); pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1)));

View File

@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
#include <string.h>
#include <console/console.h> #include <console/console.h>
#include <device/device.h> #include <device/device.h>
#include <device/mmio.h> #include <device/mmio.h>
@ -31,16 +30,8 @@
#define METHOD_MAINBOARD_WAK "\\_SB.MWAK" #define METHOD_MAINBOARD_WAK "\\_SB.MWAK"
#define METHOD_MAINBOARD_PTS "\\_SB.MPTS" #define METHOD_MAINBOARD_PTS "\\_SB.MPTS"
/*********************************************************** /* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01. accessed via I/O ports 0xc00/0xc01. */
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
/* /*
* This controls the device -> IRQ routing. * This controls the device -> IRQ routing.
@ -78,42 +69,12 @@ static const struct fch_irq_routing fch_irq_map[] = {
{ PIRQ_MISC2, 0x00, 0x00 }, { PIRQ_MISC2, 0x00, 0x00 },
}; };
static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length) const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
{ {
*length = ARRAY_SIZE(fch_irq_map); *length = ARRAY_SIZE(fch_irq_map);
return fch_irq_map; return fch_irq_map;
} }
static void init_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
/* PIRQ Setup */
static void pirq_setup(void)
{
intr_data_ptr = fch_apic_routing;
picr_data_ptr = fch_pic_routing;
}
static void mainboard_configure_gpios(void) static void mainboard_configure_gpios(void)
{ {
size_t base_num_gpios, override_num_gpios; size_t base_num_gpios, override_num_gpios;
@ -205,12 +166,7 @@ static void mainboard_fill_ssdt(const struct device *dev)
*************************************************/ *************************************************/
static void mainboard_enable(struct device *dev) static void mainboard_enable(struct device *dev)
{ {
init_tables();
/* Initialize the PIRQ data structures for consumption */
pirq_setup();
dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
} }
static void mainboard_final(void *chip_info) static void mainboard_final(void *chip_info)

View File

@ -19,6 +19,8 @@ struct fch_irq_routing {
uint8_t apic_irq_num; uint8_t apic_irq_num;
}; };
const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length);
struct pirq_struct { struct pirq_struct {
u8 devfn; u8 devfn;
u8 PIN[4]; /* PINA/B/C/D are index 0/1/2/3 */ u8 PIN[4]; /* PINA/B/C/D are index 0/1/2/3 */
@ -31,8 +33,6 @@ struct irq_idx_name {
extern const struct pirq_struct *pirq_data_ptr; extern const struct pirq_struct *pirq_data_ptr;
extern u32 pirq_data_size; extern u32 pirq_data_size;
extern const u8 *intr_data_ptr;
extern const u8 *picr_data_ptr;
u8 read_pci_int_idx(u8 index, int mode); u8 read_pci_int_idx(u8 index, int mode);
void write_pci_int_idx(u8 index, int mode, u8 data); void write_pci_int_idx(u8 index, int mode, u8 data);

View File

@ -7,11 +7,21 @@
#include <amdblocks/amd_pci_util.h> #include <amdblocks/amd_pci_util.h>
#include <pc80/i8259.h> #include <pc80/i8259.h>
#include <soc/amd_pci_int_defs.h> #include <soc/amd_pci_int_defs.h>
#include <string.h>
/*
* These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
* This table is responsible for physically routing the PIC and
* IOAPIC IRQs to the different PCI devices on the system. It
* is read and written via registers 0xC00/0xC01 as an
* Index/Data pair. These values are chipset and mainboard
* dependent and should be updated accordingly.
*/
static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
const struct pirq_struct *pirq_data_ptr; const struct pirq_struct *pirq_data_ptr;
u32 pirq_data_size; u32 pirq_data_size;
const u8 *intr_data_ptr;
const u8 *picr_data_ptr;
/* /*
* Read the FCH PCI_INTR registers 0xC00/0xC01 at a * Read the FCH PCI_INTR registers 0xC00/0xC01 at a
@ -33,6 +43,29 @@ void write_pci_int_idx(u8 index, int mode, u8 data)
outb(data, PCI_INTR_DATA); outb(data, PCI_INTR_DATA);
} }
static void init_fch_irq_map_tables(void)
{
const struct fch_irq_routing *mb_irq_map;
size_t mb_fch_irq_mapping_table_size;
size_t i;
mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
printk(BIOS_WARNING,
"Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
mb_irq_map[i].intr_index, i);
continue;
}
fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
}
}
/* /*
* Write the FCH PCI_INTR registers 0xC00/0xC01 with values * Write the FCH PCI_INTR registers 0xC00/0xC01 with values
* given in global variables intr_data and picr_data. * given in global variables intr_data and picr_data.
@ -44,13 +77,13 @@ void write_pci_int_table(void)
size_t i, limit; size_t i, limit;
const struct irq_idx_name *idx_name; const struct irq_idx_name *idx_name;
init_fch_irq_map_tables();
idx_name = sb_get_apic_reg_association(&limit); idx_name = sb_get_apic_reg_association(&limit);
if (picr_data_ptr == NULL || intr_data_ptr == NULL || if (idx_name == NULL) {
idx_name == NULL) {
printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01" printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01"
" registers because\n" " registers because\n"
"'mainboard_picr_data' or 'mainboard_intr_data'" " 'irq_association'\ntables is NULL\n");
" or 'irq_association'\ntables are NULL\n");
return; return;
} }
@ -67,11 +100,11 @@ void write_pci_int_table(void)
*/ */
for (i = 0 ; i < limit; i++) { for (i = 0 ; i < limit; i++) {
byte = idx_name[i].index; byte = idx_name[i].index;
write_pci_int_idx(byte, 0, (u8)picr_data_ptr[byte]); write_pci_int_idx(byte, 0, fch_pic_routing[byte]);
printk(BIOS_DEBUG, "0x%02X\t\t%-20s 0x%02X\t", printk(BIOS_DEBUG, "0x%02X\t\t%-20s 0x%02X\t",
byte, idx_name[i].name, byte, idx_name[i].name,
read_pci_int_idx(byte, 0)); read_pci_int_idx(byte, 0));
write_pci_int_idx(byte, 1, (u8)intr_data_ptr[byte]); write_pci_int_idx(byte, 1, fch_apic_routing[byte]);
printk(BIOS_DEBUG, "0x%02X\n", read_pci_int_idx(byte, 1)); printk(BIOS_DEBUG, "0x%02X\n", read_pci_int_idx(byte, 1));
} }
} }