1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <amdblocks/amd_pci_util.h>
8 #include <soc/southbridge.h>
9 #include <soc/pci_devs.h>
11 #include <commonlib/helpers.h>
12 #include <soc/amd/picasso/chip.h>
15 /* TODO: recheck IRQ tables */
18 * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
19 * This table is responsible for physically routing the PIC and
20 * IOAPIC IRQs to the different PCI devices on the system. It
21 * is read and written via registers 0xC00/0xC01 as an
22 * Index/Data pair. These values are chipset and mainboard
23 * dependent and should be updated accordingly.
25 static uint8_t fch_pic_routing
[0x80];
26 static uint8_t fch_apic_routing
[0x80];
28 _Static_assert(sizeof(fch_pic_routing
) == sizeof(fch_apic_routing
),
29 "PIC and APIC FCH interrupt tables must be the same size");
31 static const struct fch_irq_routing
{
41 { PIRQ_SD
, PIRQ_NC
, 16 },
42 { PIRQ_SDIO
, PIRQ_NC
, 16 },
43 { PIRQ_SATA
, PIRQ_NC
, 19 },
44 { PIRQ_EMMC
, PIRQ_NC
, 17 },
47 { PIRQ_I2C3
, 14, 14 },
53 /* The MISC registers are not interrupt numbers */
54 { PIRQ_MISC
, 0xfa, 0x00 },
55 { PIRQ_MISC0
, 0x91, 0x00 },
56 { PIRQ_MISC1
, 0x00, 0x00 },
57 { PIRQ_MISC2
, 0x00, 0x00 },
60 static void init_tables(void)
62 const struct fch_irq_routing
*entry
;
65 memset(fch_pic_routing
, PIRQ_NC
, sizeof(fch_pic_routing
));
66 memset(fch_apic_routing
, PIRQ_NC
, sizeof(fch_apic_routing
));
68 for (i
= 0; i
< ARRAY_SIZE(mandolin_fch
); i
++) {
69 entry
= mandolin_fch
+ i
;
70 fch_pic_routing
[entry
->intr_index
] = entry
->pic_irq_num
;
71 fch_apic_routing
[entry
->intr_index
] = entry
->apic_irq_num
;
75 static void pirq_setup(void)
77 intr_data_ptr
= fch_apic_routing
;
78 picr_data_ptr
= fch_pic_routing
;
81 static void mainboard_init(void *chip_info
)
83 struct soc_amd_picasso_config
*cfg
= config_of_soc();
85 if (!CONFIG(MANDOLIN_LPC
))
86 cfg
->emmc_config
.timing
= SD_EMMC_EMMC_HS400
;
88 mainboard_program_gpios();
90 /* Re-muxing LPCCLK0 can hang the system if LPC is in use. */
91 if (CONFIG(MANDOLIN_LPC
))
92 printk(BIOS_INFO
, "eMMC not available due to LPC requirement\n");
94 mainboard_program_emmc_gpios();
97 static void mainboard_enable(struct device
*dev
)
100 /* Initialize the PIRQ data structures for consumption */
104 struct chip_operations mainboard_ops
= {
105 .init
= mainboard_init
,
106 .enable_dev
= mainboard_enable
,