coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
fch.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <bootstate.h>
5 #include <cpu/amd/msr.h>
6 #include <cpu/x86/smm.h>
7 #include <cpu/x86/msr.h>
8 #include <device/device.h>
9 #include <device/pci.h>
10 #include <device/pci_ops.h>
11 #include <amdblocks/amd_pci_util.h>
12 #include <amdblocks/reset.h>
13 #include <amdblocks/acpimmio.h>
14 #include <amdblocks/acpi.h>
15 #include <amdblocks/gpio.h>
16 #include <amdblocks/i2c.h>
17 #include <amdblocks/smi.h>
18 #include <soc/acpi.h>
19 #include <soc/cpu.h>
20 #include <soc/i2c.h>
21 #include <soc/iomap.h>
22 #include <soc/southbridge.h>
23 #include <soc/smi.h>
24 #include <soc/amd_pci_int_defs.h>
25 #include <soc/pci_devs.h>
26 #include <types.h>
27 #include "chip.h"
28 
29 /*
30  * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
31  * provides a visible association with the index, therefore helping
32  * maintainability of table. If a new index/name is defined in
33  * amd_pci_int_defs.h, just add the pair at the end of this table.
34  * Order is not important.
35  */
36 const static struct irq_idx_name irq_association[] = {
37  { PIRQ_A, "INTA#" },
38  { PIRQ_B, "INTB#" },
39  { PIRQ_C, "INTC#" },
40  { PIRQ_D, "INTD#" },
41  { PIRQ_E, "INTE#" },
42  { PIRQ_F, "INTF#/GENINT2" },
43  { PIRQ_G, "INTG#" },
44  { PIRQ_H, "INTH#" },
45  { PIRQ_MISC, "Misc" },
46  { PIRQ_MISC0, "Misc0" },
47  { PIRQ_MISC1, "Misc1" },
48  { PIRQ_MISC2, "Misc2" },
49  { PIRQ_SIRQA, "Ser IRQ INTA" },
50  { PIRQ_SIRQB, "Ser IRQ INTB" },
51  { PIRQ_SIRQC, "Ser IRQ INTC" },
52  { PIRQ_SIRQD, "Ser IRQ INTD" },
53  { PIRQ_SCI, "SCI" },
54  { PIRQ_SMBUS, "SMBUS" },
55  { PIRQ_ASF, "ASF" },
56  { PIRQ_PMON, "PerMon" },
57  { PIRQ_SD, "SD" },
58  { PIRQ_SDIO, "SDIO" },
59  { PIRQ_CIR, "CIR" },
60  { PIRQ_GPIOA, "GPIOa" },
61  { PIRQ_GPIOB, "GPIOb" },
62  { PIRQ_GPIOC, "GPIOc" },
63  { PIRQ_SATA, "SATA" },
64  { PIRQ_EMMC, "eMMC" },
65  { PIRQ_GPP0, "GPP0" },
66  { PIRQ_GPP1, "GPP1" },
67  { PIRQ_GPP2, "GPP2" },
68  { PIRQ_GPP3, "GPP3" },
69  { PIRQ_GPIO, "GPIO" },
70  { PIRQ_I2C0, "I2C0" },
71  { PIRQ_I2C1, "I2C1" },
72  { PIRQ_I2C2, "I2C2" },
73  { PIRQ_I2C3, "I2C3" },
74  { PIRQ_UART0, "UART0" },
75  { PIRQ_UART1, "UART1" },
76  { PIRQ_I2C4, "I2C4" },
77  { PIRQ_I2C5, "I2C5" },
78  { PIRQ_UART2, "UART2" },
79  { PIRQ_UART3, "UART3" },
80 };
81 
82 const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
83 {
84  *size = ARRAY_SIZE(irq_association);
85  return irq_association;
86 }
87 
88 static void fch_clk_output_48Mhz(void)
89 {
90  u32 ctrl;
91  const struct soc_amd_picasso_config *cfg = config_of_soc();
92 
94  /* If used external clock source for I2S, disable the internal clock output */
96  cfg->common_config.acp_config.acp_pin_cfg == I2S_PINS_I2S_TDM)
97  ctrl &= ~BP_X48M0_OUTPUT_EN;
98  else
99  ctrl |= BP_X48M0_OUTPUT_EN;
101 }
102 
103 static void sb_rfmux_config_override(void)
104 {
105  u8 port;
106  const struct soc_amd_picasso_config *cfg;
107 
108  cfg = config_of_soc();
109 
110  for (port = 0; port < USB_PD_PORT_COUNT; port++) {
115  }
116  }
117 }
118 
119 static void fch_init_acpi_ports(void)
120 {
121  u32 reg;
122 
123  /* We use some of these ports in SMM regardless of whether or not
124  * ACPI tables are generated. Enable these ports indiscriminately.
125  */
126 
131 
132  if (CONFIG(HAVE_SMI_HANDLER)) {
133  /* APMC - SMI Command Port */
136 
137  /* SMI on SlpTyp requires sending SMI before completion
138  response of the I/O write. */
139  reg = pm_read32(PM_PCI_CTRL);
140  reg |= FORCE_SLPSTATE_RETRY;
141  pm_write32(PM_PCI_CTRL, reg);
142 
143  /* Disable SlpTyp feature */
144  reg = pm_read8(PM_RST_CTRL1);
145  reg &= ~SLPTYPE_CONTROL_EN;
146  pm_write8(PM_RST_CTRL1, reg);
147 
149  } else {
151  }
152 
153  /* Decode ACPI registers and enable standard features */
158 }
159 
160 /*
161  * A-Link to AHB bridge, part of the AMBA fabric. These are internal clocks
162  * and unneeded for Raven/Picasso so gate them to save power.
163  */
164 static void al2ahb_clock_gate(void)
165 {
166  uint8_t al2ahb_val;
167  uintptr_t al2ahb_base = ALINK_AHB_ADDRESS;
168 
169  al2ahb_val = read8((void *)(al2ahb_base + AL2AHB_CONTROL_CLK_OFFSET));
170  al2ahb_val |= AL2AHB_CLK_GATE_EN;
171  write8((void *)(al2ahb_base + AL2AHB_CONTROL_CLK_OFFSET), al2ahb_val);
172  al2ahb_val = read8((void *)(al2ahb_base + AL2AHB_CONTROL_HCLK_OFFSET));
173  al2ahb_val |= AL2AHB_HCLK_GATE_EN;
174  write8((void *)(al2ahb_base + AL2AHB_CONTROL_HCLK_OFFSET), al2ahb_val);
175 }
176 
177 /* configure the general purpose PCIe clock outputs according to the devicetree settings */
178 static void gpp_clk_setup(void)
179 {
180  const struct soc_amd_picasso_config *cfg = config_of_soc();
181 
182  /* look-up table to be able to iterate over the PCIe clock output settings */
183  const uint8_t gpp_clk_shift_lut[GPP_CLK_OUTPUT_COUNT] = {
191  };
192 
193  uint32_t gpp_clk_ctl = misc_read32(GPP_CLK_CNTRL);
194 
195  for (int i = 0; i < GPP_CLK_OUTPUT_COUNT; i++) {
196  gpp_clk_ctl &= ~GPP_CLK_REQ_MASK(gpp_clk_shift_lut[i]);
197  /*
198  * The remapping of values is done so that the default of the enum used for the
199  * devicetree settings is the clock being enabled, so that a missing devicetree
200  * configuration for this will result in an always active clock and not an
201  * inactive PCIe clock output.
202  */
203  switch (cfg->gpp_clk_config[i]) {
204  case GPP_CLK_REQ:
205  gpp_clk_ctl |= GPP_CLK_REQ_EXT(gpp_clk_shift_lut[i]);
206  break;
207  case GPP_CLK_OFF:
208  gpp_clk_ctl |= GPP_CLK_REQ_OFF(gpp_clk_shift_lut[i]);
209  break;
210  case GPP_CLK_ON:
211  default:
212  gpp_clk_ctl |= GPP_CLK_REQ_ON(gpp_clk_shift_lut[i]);
213  }
214  }
215 
216  misc_write32(GPP_CLK_CNTRL, gpp_clk_ctl);
217 }
218 
219 void fch_init(void *chip_info)
220 {
221  i2c_soc_init();
223 
225  gpio_add_events();
226 
228 
229  gpp_clk_setup();
230 
232 
234 }
235 
236 void fch_final(void *chip_info)
237 {
238 }
239 
240 /*
241  * Update the PCI devices with a valid IRQ number
242  * that is set in the mainboard PCI_IRQ structures.
243  */
244 static void set_pci_irqs(void *unused)
245 {
246  /* Write PCI_INTR regs 0xC00/0xC01 */
248 
249  /* pirq_data is consumed by `write_pci_cfg_irqs` */
251 
252  /* Write IRQs for all devicetree enabled devices */
254 }
255 
256 /*
257  * Hook this function into the PCI state machine
258  * on entry into BS_DEV_ENABLE.
259  */
@ PIRQ_A
Definition: acpi_pirq_gen.h:22
@ PIRQ_C
Definition: acpi_pirq_gen.h:24
@ PIRQ_G
Definition: acpi_pirq_gen.h:28
@ PIRQ_H
Definition: acpi_pirq_gen.h:29
@ PIRQ_E
Definition: acpi_pirq_gen.h:26
@ PIRQ_D
Definition: acpi_pirq_gen.h:25
@ PIRQ_F
Definition: acpi_pirq_gen.h:27
@ PIRQ_B
Definition: acpi_pirq_gen.h:23
#define SLPTYPE_CONTROL_EN
Definition: acpimmio.h:32
static void pm_write32(uint8_t reg, uint32_t value)
Definition: acpimmio.h:191
static uint8_t pm_read8(uint8_t reg)
Definition: acpimmio.h:166
static void pm_write16(uint8_t reg, uint16_t value)
Definition: acpimmio.h:186
static uint32_t misc_read32(uint8_t reg)
Definition: acpimmio.h:266
static uint32_t pm_read32(uint8_t reg)
Definition: acpimmio.h:176
static void misc_write32(uint8_t reg, uint32_t value)
Definition: acpimmio.h:281
static void pm_write8(uint8_t reg, uint8_t value)
Definition: acpimmio.h:181
#define PM_RST_CTRL1
Definition: acpimmio.h:31
#define ACPI_PM1_CNT_BLK
Definition: iomap.h:43
#define ACPI_PM_TMR_BLK
Definition: iomap.h:44
#define ACPI_GPE0_BLK
Definition: iomap.h:46
#define ACPI_PM_EVT_BLK
Definition: iomap.h:40
#define ALINK_AHB_ADDRESS
Definition: iomap.h:11
static void write8(void *addr, uint8_t val)
Definition: mmio.h:30
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint8_t read8(const void *addr)
Definition: mmio.h:12
@ BS_DEV_ENABLE
Definition: bootstate.h:82
@ BS_ON_ENTRY
Definition: bootstate.h:95
#define ARRAY_SIZE(a)
Definition: helpers.h:12
const struct irq_idx_name * sb_get_apic_reg_association(size_t *size)
Definition: fch.c:75
BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL)
void fch_init(void *chip_info)
Definition: fch.c:290
void fch_final(void *chip_info)
Definition: fch.c:304
#define GPP_CLK_REQ_MASK(clk_shift)
Definition: southbridge.h:98
#define GPP_CLK_REQ_ON(clk_shift)
Definition: southbridge.h:99
#define GPP_CLK5_REQ_SHIFT
Definition: southbridge.h:95
#define GPP_CLK2_REQ_SHIFT
Definition: southbridge.h:93
#define PM_TMR_BLK
Definition: southbridge.h:40
#define PM_ACPI_CONF
Definition: southbridge.h:43
#define GPP_CLK_CNTRL
Definition: southbridge.h:89
#define PM_ACPI_TIMER_EN_EN
Definition: southbridge.h:48
#define FORCE_SLPSTATE_RETRY
Definition: southbridge.h:12
#define PM_ACPI_GLOBAL_EN
Definition: southbridge.h:45
#define GPP_CLK_OUTPUT_COUNT
Definition: southbridge.h:97
#define PM_ACPI_DECODE_STD
Definition: southbridge.h:44
#define GPP_CLK6_REQ_SHIFT
Definition: southbridge.h:96
#define BP_X48M0_OUTPUT_EN
Definition: southbridge.h:114
#define GPP_CLK1_REQ_SHIFT
Definition: southbridge.h:91
#define PM_ACPI_RTC_EN_EN
Definition: southbridge.h:46
#define PM_EVT_BLK
Definition: southbridge.h:26
#define GPP_CLK4_REQ_SHIFT
Definition: southbridge.h:92
#define GPP_CLK0_REQ_SHIFT
Definition: southbridge.h:90
#define PM_GPE0_BLK
Definition: southbridge.h:41
#define PM_ACPI_SMI_CMD
Definition: southbridge.h:42
#define PM_PCI_CTRL
Definition: southbridge.h:11
#define GPP_CLK_REQ_EXT(clk_shift)
Definition: southbridge.h:100
#define GPP_CLK_REQ_OFF(clk_shift)
Definition: southbridge.h:101
#define PM1_CNT_BLK
Definition: southbridge.h:39
#define GPP_CLK3_REQ_SHIFT
Definition: southbridge.h:94
@ CONFIG
Definition: dsi_common.h:201
port
Definition: i915.h:29
#define APM_CNT
Definition: smm.h:19
#define config_of_soc()
Definition: device.h:394
static void gpp_clk_setup(void)
Definition: fch.c:178
static void sb_rfmux_config_override(void)
Definition: fch.c:103
static void fch_init_acpi_ports(void)
Definition: fch.c:119
static const struct irq_idx_name irq_association[]
Definition: fch.c:36
static void fch_clk_output_48Mhz(void)
Definition: fch.c:88
static void al2ahb_clock_gate(void)
Definition: fch.c:164
static void set_pci_irqs(void *unused)
Definition: fch.c:244
#define MISC_CLK_CNTL1
Definition: southbridge.h:93
@ GPP_CLK_REQ
Definition: chip.h:17
@ GPP_CLK_ON
Definition: chip.h:16
@ GPP_CLK_OFF
Definition: chip.h:18
#define PIRQ_EMMC
#define PIRQ_SATA
#define PIRQ_GPIOB
#define PIRQ_SDIO
#define PIRQ_GPP2
#define PIRQ_GPP1
#define PIRQ_PMON
#define PIRQ_I2C0
#define PIRQ_SIRQA
#define PIRQ_SMBUS
#define PIRQ_MISC0
#define PIRQ_ASF
#define PIRQ_GPP0
#define PIRQ_CIR
#define PIRQ_SIRQC
#define PIRQ_SCI
#define PIRQ_GPIOA
#define PIRQ_SIRQD
#define PIRQ_I2C5
#define PIRQ_MISC
#define PIRQ_SD
#define PIRQ_UART0
#define PIRQ_GPP3
#define PIRQ_I2C3
#define PIRQ_I2C4
#define PIRQ_I2C2
#define PIRQ_UART1
#define PIRQ_I2C1
#define PIRQ_GPIO
#define PIRQ_SIRQB
#define PIRQ_GPIOC
#define SMITYPE_SLP_TYP
Definition: smi.h:107
#define SMITYPE_SMI_CMD_PORT
Definition: smi.h:113
void acpi_pm_gpe_add_events_print_events(void)
Definition: acpi.c:77
void gpio_add_events(void)
Definition: gpio.c:382
void i2c_soc_init(void)
Definition: i2c.c:113
void write_pci_cfg_irqs(void)
Definition: amd_pci_util.c:84
void write_pci_int_table(void)
Definition: amd_pci_util.c:41
void populate_pirq_data(void)
void configure_smi(uint8_t smi_num, uint8_t mode)
Definition: smi_util.c:12
@ SMI_MODE_SMI
Definition: smi.h:10
#define USB_PD_PORT_COUNT
Definition: chip.h:76
#define PIRQ_MISC2
#define PIRQ_UART3
#define PIRQ_MISC1
#define PIRQ_UART2
#define PD_PORT_MUX_OFFSET(x)
Definition: i2c.h:21
#define USB_PD_PORT_CONTROL
Definition: i2c.h:20
#define USB_PD_RFMUX_OVERRIDE
Definition: i2c.h:23
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
enum acp_config::@398 acp_pin_cfg
struct acp_config acp_config
Definition: chip.h:42
struct usb_pd_control usb_pd_config_override[USB_PD_PORT_COUNT]
Definition: chip.h:305
struct soc_amd_common_config common_config
Definition: chip.h:98
bool acp_i2s_use_external_48mhz_osc
Definition: chip.h:276
enum soc_amd_picasso_config::@419 gpp_clk_config[GPP_CLK_OUTPUT_COUNT]
uint8_t rfmux_override_en
Definition: chip.h:64
uint32_t rfmux_config
Definition: chip.h:65