• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <amdblocks/acpi.h>
4 #include <amdblocks/acpimmio.h>
5 #include <amdblocks/amd_pci_util.h>
6 #include <amdblocks/gpio.h>
7 #include <amdblocks/pci_clk_req.h>
8 #include <amdblocks/reset.h>
9 #include <amdblocks/smi.h>
10 #include <assert.h>
11 #include <bootstate.h>
12 #include <cpu/x86/smm.h>
13 #include <amdblocks/i2c.h>
14 #include <soc/amd_pci_int_defs.h>
15 #include <soc/iomap.h>
16 #include <soc/i2c.h>
17 #include <soc/smi.h>
18 #include <soc/southbridge.h>
19 #include "chip.h"
20 
21 /*
22  * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
23  * provides a visible association with the index, therefore helping
24  * maintainability of table. If a new index/name is defined in
25  * amd_pci_int_defs.h, just add the pair at the end of this table.
26  * Order is not important.
27  */
28 static const struct irq_idx_name irq_association[] = {
29 	{ PIRQ_A,	"INTA#" },
30 	{ PIRQ_B,	"INTB#" },
31 	{ PIRQ_C,	"INTC#" },
32 	{ PIRQ_D,	"INTD#" },
33 	{ PIRQ_E,	"INTE#" },
34 	{ PIRQ_F,	"INTF#/GENINT2" },
35 	{ PIRQ_G,	"INTG#" },
36 	{ PIRQ_H,	"INTH#" },
37 	{ PIRQ_MISC,	"Misc" },
38 	{ PIRQ_MISC0,	"Misc0" },
39 	{ PIRQ_HPET_L,	"HPET_L" },
40 	{ PIRQ_HPET_H,	"HPET_H" },
41 	{ PIRQ_SIRQA,	"Ser IRQ INTA" },
42 	{ PIRQ_SIRQB,	"Ser IRQ INTB" },
43 	{ PIRQ_SIRQC,	"Ser IRQ INTC" },
44 	{ PIRQ_SIRQD,	"Ser IRQ INTD" },
45 	{ PIRQ_SCI,	"SCI" },
46 	{ PIRQ_SMBUS,	"SMBUS" },
47 	{ PIRQ_ASF,	"ASF" },
48 	{ PIRQ_PMON,	"PerMon" },
49 	{ PIRQ_SD,	"SD" },
50 	{ PIRQ_SDIO,	"SDIO" },
51 	{ PIRQ_CIR,	"CIR" },
52 	{ PIRQ_GPIOA,	"GPIOa" },
53 	{ PIRQ_GPIOB,	"GPIOb" },
54 	{ PIRQ_GPIOC,	"GPIOc" },
55 	{ PIRQ_GPP0,	"GPP0" },
56 	{ PIRQ_GPP1,	"GPP1" },
57 	{ PIRQ_GPP2,	"GPP2" },
58 	{ PIRQ_GPP3,	"GPP3" },
59 	{ PIRQ_GPIO,	"GPIO" },
60 	{ PIRQ_I2C0,	"I2C0" },
61 	{ PIRQ_I2C1,	"I2C1" },
62 	{ PIRQ_I2C2,	"I2C2" },
63 	{ PIRQ_I2C3,	"I2C3" },
64 	{ PIRQ_UART0,	"UART0" },
65 	{ PIRQ_UART1,	"UART1" },
66 	{ PIRQ_I2C4,	"I2C4" },
67 	{ PIRQ_UART4,	"UART4" },
68 	{ PIRQ_UART2,	"UART2" },
69 	{ PIRQ_UART3,	"UART3" },
70 };
71 
sb_get_apic_reg_association(size_t * size)72 const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
73 {
74 	*size = ARRAY_SIZE(irq_association);
75 	return irq_association;
76 }
77 
fch_clk_output_48Mhz(void)78 static void fch_clk_output_48Mhz(void)
79 {
80 	uint32_t ctrl = misc_read32(MISC_CLK_CNTL0);
81 	/* Enable BP_X48M0 Clock Output */
82 	ctrl |= BP_X48M0_OUTPUT_EN;
83 	/* Disable clock output in S0i3 */
84 	ctrl |= BP_X48M0_S0I3_DIS;
85 	misc_write32(MISC_CLK_CNTL0, ctrl);
86 }
87 
fch_init_acpi_ports(void)88 static void fch_init_acpi_ports(void)
89 {
90 	u32 reg;
91 
92 	/* We use some of these ports in SMM regardless of whether or not
93 	 * ACPI tables are generated. Enable these ports indiscriminately.
94 	 */
95 
96 	pm_write16(PM_EVT_BLK, ACPI_PM_EVT_BLK);
97 	pm_write16(PM1_CNT_BLK, ACPI_PM1_CNT_BLK);
98 	pm_write16(PM_TMR_BLK, ACPI_PM_TMR_BLK);
99 	pm_write16(PM_GPE0_BLK, ACPI_GPE0_BLK);
100 
101 	if (CONFIG(HAVE_SMI_HANDLER)) {
102 		/* APMC - SMI Command Port */
103 		pm_write16(PM_ACPI_SMI_CMD, APM_CNT);
104 		configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI);
105 
106 		/* SMI on SlpTyp requires sending SMI before completion
107 		   response of the I/O write. */
108 		reg = pm_read32(PM_PCI_CTRL);
109 		reg |= FORCE_SLPSTATE_RETRY;
110 		pm_write32(PM_PCI_CTRL, reg);
111 
112 		/* Disable SlpTyp feature */
113 		reg = pm_read8(PM_RST_CTRL1);
114 		reg &= ~SLPTYPE_CONTROL_EN;
115 		pm_write8(PM_RST_CTRL1, reg);
116 
117 		configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI);
118 	} else {
119 		pm_write16(PM_ACPI_SMI_CMD, 0);
120 	}
121 
122 	/* Decode ACPI registers and enable standard features */
123 	pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD |
124 				PM_ACPI_GLOBAL_EN |
125 				PM_ACPI_RTC_EN_EN |
126 				PM_ACPI_TIMER_EN_EN);
127 }
128 
129 /* configure the general purpose PCIe clock outputs according to the devicetree settings */
gpp_clk_setup(void)130 static void gpp_clk_setup(void)
131 {
132 	struct soc_amd_mendocino_config *cfg = config_of_soc();
133 	gpp_clk_setup_common(&cfg->gpp_clk_config[0], ARRAY_SIZE(cfg->gpp_clk_config));
134 }
135 
cgpll_clock_gate_init(void)136 static void cgpll_clock_gate_init(void)
137 {
138 	uint32_t t;
139 
140 	t = misc_read32(MISC_CLKGATEDCNTL);
141 	t |= ALINKCLK_GATEOFFEN;
142 	t |= BLINKCLK_GATEOFFEN;
143 	t |= XTAL_PAD_S0I3_TURNOFF_EN;
144 	t |= XTAL_PAD_S3_TURNOFF_EN;
145 	t |= XTAL_PAD_S5_TURNOFF_EN;
146 	misc_write32(MISC_CLKGATEDCNTL, t);
147 
148 	t = misc_read32(MISC_CGPLL_CONFIGURATION0);
149 	t |= USB_PHY_CMCLK_S3_DIS;
150 	t |= USB_PHY_CMCLK_S0I3_DIS;
151 	t |= USB_PHY_CMCLK_S5_DIS;
152 	misc_write32(MISC_CGPLL_CONFIGURATION0, t);
153 
154 	t = pm_read32(PM_ISACONTROL);
155 	t |= ABCLKGATEEN;
156 	pm_write32(PM_ISACONTROL, t);
157 }
158 
fch_init(void * chip_info)159 void fch_init(void *chip_info)
160 {
161 	set_resets_to_cold();
162 	i2c_soc_init();
163 	fch_init_acpi_ports();
164 
165 	acpi_pm_gpe_add_events_print_events();
166 	gpio_add_events();
167 
168 	gpp_clk_setup();
169 	fch_clk_output_48Mhz();
170 	cgpll_clock_gate_init();
171 }
172 
fch_final(void * chip_info)173 void fch_final(void *chip_info)
174 {
175 }
176 
set_pci_irqs(void * unused)177 static void set_pci_irqs(void *unused)
178 {
179 	/* Write PCI_INTR regs 0xC00/0xC01 */
180 	write_pci_int_table();
181 
182 	/* pirq_data is consumed by `write_pci_cfg_irqs` */
183 	populate_pirq_data();
184 
185 	/* Write IRQs for all devicetree enabled devices */
186 	write_pci_cfg_irqs();
187 }
188 
189 /*
190  * Hook this function into the PCI state machine
191  * on entry into BS_DEV_ENABLE.
192  */
193 BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL);
194