xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/psp_verstage/fch.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include "psp_verstage.h"
4 
5 #include <amdblocks/acpimmio.h>
6 #include <amdblocks/aoac.h>
7 #include <amdblocks/espi.h>
8 #include <amdblocks/i2c.h>
9 #include <amdblocks/spi.h>
10 #include <arch/exception.h>
11 #include <arch/hlt.h>
12 #include <arch/io.h>
13 #include <bl_uapp/bl_errorcodes_public.h>
14 #include <bl_uapp/bl_syscall_public.h>
15 #include <console/console.h>
16 #include <device/mmio.h>
17 #include <soc/i2c.h>
18 #include <soc/southbridge.h>
19 #include <stdint.h>
20 
i2c3_set_bar(void * bar)21 static void i2c3_set_bar(void *bar)
22 {
23 	i2c_set_bar(3, (uintptr_t)bar);
24 }
25 
i2c2_set_bar(void * bar)26 static void i2c2_set_bar(void *bar)
27 {
28 	i2c_set_bar(2, (uintptr_t)bar);
29 }
30 
espi_set_bar(void * bar)31 static void espi_set_bar(void *bar)
32 {
33 	espi_update_static_bar((uintptr_t)bar);
34 }
35 
iomux_set_bar(void * bar)36 static void iomux_set_bar(void *bar)
37 {
38 	acpimmio_iomux = bar;
39 }
40 
misc_set_bar(void * bar)41 static void misc_set_bar(void *bar)
42 {
43 	acpimmio_misc = bar;
44 }
45 
gpio_set_bar(void * bar)46 static void gpio_set_bar(void *bar)
47 {
48 	acpimmio_gpio0 = bar;
49 }
50 
51 static uintptr_t io_bar;
52 
io_set_bar(void * bar)53 static void io_set_bar(void *bar)
54 {
55 	io_bar = (uintptr_t)bar;
56 }
57 
io_read8(u16 reg)58 u8 io_read8(u16 reg)
59 {
60 	return read8p(io_bar + reg);
61 }
62 
io_write8(u16 reg,u8 value)63 void io_write8(u16 reg, u8 value)
64 {
65 	write8p(io_bar + reg, value);
66 }
67 
aoac_set_bar(void * bar)68 static void aoac_set_bar(void *bar)
69 {
70 	acpimmio_aoac = bar;
71 }
72 
73 static struct {
74 	const char *name;
75 	struct {
76 		enum fch_io_device device;
77 		uint32_t arg0;
78 	} args;
79 	void (*set_bar)(void *bar);
80 	void *_bar;
81 } bar_map[] = {
82 	{"IOMUX", {FCH_IO_DEVICE_IOMUX}, iomux_set_bar},
83 	{"MISC", {FCH_IO_DEVICE_MISC}, misc_set_bar},
84 	{"GPIO", {FCH_IO_DEVICE_GPIO}, gpio_set_bar},
85 	{"IO", {FCH_IO_DEVICE_IOPORT}, io_set_bar},
86 	{"eSPI", {FCH_IO_DEVICE_ESPI}, espi_set_bar},
87 	{"I2C2", {FCH_IO_DEVICE_I2C, 2}, i2c2_set_bar},
88 	{"I2C3", {FCH_IO_DEVICE_I2C, 3}, i2c3_set_bar},
89 	{"SPI", {FCH_IO_DEVICE_SPI}, spi_set_base},
90 	{"AOAC", {FCH_IO_DEVICE_AOAC}, aoac_set_bar},
91 };
92 
map_spi_rom(void)93 void *map_spi_rom(void)
94 {
95 	struct spirom_info spi = {0};
96 
97 	if (svc_get_spi_rom_info(&spi))
98 		printk(BIOS_DEBUG, "Error getting SPI ROM info.\n");
99 
100 	if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM) && spi.SpiBiosSmnBase != 0) {
101 		uintptr_t *addr = NULL;
102 
103 		if (svc_map_spi_rom(spi.SpiBiosSmnBase, CONFIG_ROM_SIZE, (void **)&addr))
104 			printk(BIOS_DEBUG, "Error mapping SPI ROM to address.\n");
105 		return addr;
106 	}
107 	return spi.SpiBiosSmnBase;
108 }
109 
map_fch_devices(void)110 static uint32_t map_fch_devices(void)
111 {
112 	void *bar;
113 	uint32_t err;
114 	unsigned int i;
115 
116 	for (i = 0; i < ARRAY_SIZE(bar_map); ++i) {
117 		err = svc_map_fch_dev(bar_map[i].args.device, bar_map[i].args.arg0, 0, &bar);
118 		if (err) {
119 			printk(BIOS_ERR, "Failed to map %s: %u\n", bar_map[i].name, err);
120 			return err;
121 		}
122 
123 		bar_map[i]._bar = bar;
124 		bar_map[i].set_bar(bar);
125 	}
126 
127 	return BL_OK;
128 }
129 
unmap_fch_devices(void)130 uint32_t unmap_fch_devices(void)
131 {
132 	void *bar;
133 	uint32_t err, rtn = BL_OK;
134 	unsigned int i;
135 
136 	for (i = 0; i < ARRAY_SIZE(bar_map); ++i) {
137 		bar = bar_map[i]._bar;
138 		if (!bar)
139 			continue;
140 
141 		err = svc_unmap_fch_dev(bar_map[i].args.device, bar);
142 		if (err) {
143 			printk(BIOS_ERR, "Failed to unmap %s: %u\n", bar_map[i].name, err);
144 			rtn = err;
145 		} else {
146 			bar_map[i]._bar = NULL;
147 			bar_map[i].set_bar(NULL);
148 		}
149 	}
150 
151 	return rtn;
152 }
153 
verstage_soc_early_init(void)154 uint32_t verstage_soc_early_init(void)
155 {
156 	return map_fch_devices();
157 }
158 
verstage_soc_espi_init(void)159 void verstage_soc_espi_init(void)
160 {
161 	if (!CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
162 		return;
163 	printk(BIOS_DEBUG, "Setting up espi\n");
164 	espi_setup();
165 }
166 
verstage_soc_i2c_init(void)167 void verstage_soc_i2c_init(void)
168 {
169 	printk(BIOS_DEBUG, "Setting up i2c\n");
170 	i2c_soc_early_init();
171 }
172 
verstage_soc_aoac_init(void)173 void verstage_soc_aoac_init(void)
174 {
175 	printk(BIOS_DEBUG, "Setting up aoac\n");
176 	enable_aoac_devices();
177 }
178 
verstage_soc_spi_init(void)179 void verstage_soc_spi_init(void)
180 {
181 	printk(BIOS_DEBUG, "Setting up spi\n");
182 	fch_spi_config_modes();
183 	show_spi_speeds_and_modes();
184 }
185