1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) ASPEED Technology Inc.
4 */
5 #include <common.h>
6 #include <asm/io.h>
7
8 /* SCU registers */
9 #define SCU_BASE 0x1e6e2000
10 #define SCU_PINMUX4 (SCU_BASE + 0x410)
11 #define SCU_PINMUX4_RGMII3TXD1 BIT(19)
12 #define SCU_PINMUX5 (SCU_BASE + 0x414)
13 #define SCU_PINMUX5_SGPMI BIT(27)
14 #define SCU_PINMUX5_SGPMO BIT(26)
15 #define SCU_PINMUX5_SGPMLD BIT(25)
16 #define SCU_PINMUX5_SGPMCK BIT(24)
17 #define SCU_GPIO_PD0 (SCU_BASE + 0x610)
18 #define SCU_GPIO_PD0_B6 BIT(14)
19 #define SCU_PINMUX27 (SCU_BASE + 0x69c)
20 #define SCU_PINMUX27_HBLED_EN BIT(31)
21
22 /* eSPI registers */
23 #define ESPI_BASE 0x1e6ee000
24 #define ESPI_CTRL (ESPI_BASE + 0x0)
25 #define ESPI_INT_EN (ESPI_BASE + 0xc)
26 #define ESPI_CTRL2 (ESPI_BASE + 0x80)
27 #define ESPI_SYSEVT_INT_EN (ESPI_BASE + 0x94)
28 #define ESPI_SYSEVT1_INT_EN (ESPI_BASE + 0x100)
29 #define ESPI_SYSEVT_INT_T0 (ESPI_BASE + 0x110)
30 #define ESPI_SYSEVT_INT_T1 (ESPI_BASE + 0x114)
31 #define ESPI_SYSEVT1_INT_T0 (ESPI_BASE + 0x120)
32
33 /* LPC registers */
34 #define LPC_BASE 0x1e789000
35 #define LPC_HICR5 (LPC_BASE + 0x80)
36 #define LPC_HICR5_SIO80HGPIO_EN BIT(31)
37 #define LPC_HICR5_80HGPIO_EN BIT(30)
38 #define LPC_HICR5_80HGPIO_SEL_MASK GENMASK(28, 24)
39 #define LPC_HICR5_80HGPIO_SEL_SHIFT 24
40 #define LPC_HICR5_SNP0_INT_EN BIT(1)
41 #define LPC_HICR5_SNP0_EN BIT(0)
42 #define LPC_HICR6 (LPC_BASE + 0x84)
43 #define LPC_HICR6_STS_SNP1 BIT(1)
44 #define LPC_HICR6_STS_SNP0 BIT(0)
45 #define LPC_SNPWADR (LPC_BASE + 0x90)
46 #define LPC_SNPWADR_SNP0_MASK GENMASK(15, 0)
47 #define LPC_SNPWADR_SNP0_SHIFT 0
48 #define LPC_HICRB (LPC_BASE + 0x100)
49 #define LPC_HICRB_80HSGPIO_EN BIT(13)
50
51 /* GPIO/SGPIO registers */
52 #define GPIO_BASE 0x1e780000
53 #define GPIO_ABCD_VAL (GPIO_BASE + 0x0)
54 #define GPIO_ABCD_VAL_D4 BIT(28)
55 #define GPIO_ABCD_VAL_C5 BIT(21)
56 #define GPIO_ABCD_VAL_C3 BIT(19)
57 #define GPIO_ABCD_DIR (GPIO_BASE + 0x4)
58 #define GPIO_ABCD_DIR_D4 BIT(28)
59 #define GPIO_ABCD_DIR_C5 BIT(21)
60 #define GPIO_ABCD_DIR_C3 BIT(19)
61 #define GPIO_EFGH_DIR (GPIO_BASE + 0x24)
62 #define GPIO_EFGH_DIR_G6 BIT(22)
63 #define SGPIO_M1_CONF (GPIO_BASE + 0x554)
64 #define SGPIO_M1_CONF_CLKDIV_MASK GENMASK(31, 16)
65 #define SGPIO_M1_CONF_CLKDIV_SHIFT 16
66 #define SGPIO_M1_PINS_MASK GENMASK(10, 6)
67 #define SGPIO_M1_PINS_SHIFT 6
68 #define SPGIO_M1_EN BIT(0)
69
70 #define LPC_HICR5_UNKVAL_MASK 0x1FFF0000 /* bits with unknown values on reset */
71
snoop_init(void)72 static void snoop_init(void)
73 {
74 u32 val;
75
76 /* set lpc snoop #0 to port 0x80 */
77 val = readl(LPC_SNPWADR) & 0xffff0000;
78 val |= ((0x80 << LPC_SNPWADR_SNP0_SHIFT) &
79 LPC_SNPWADR_SNP0_MASK);
80 writel(val, LPC_SNPWADR);
81
82 /* clear interrupt status */
83 val = readl(LPC_HICR6);
84 val |= (LPC_HICR6_STS_SNP0 |
85 LPC_HICR6_STS_SNP1);
86 writel(val, LPC_HICR6);
87
88 /* enable lpc snoop #0 and SIOGIO */
89 val = readl(LPC_HICR5);
90 val |= (LPC_HICR5_SIO80HGPIO_EN |
91 LPC_HICR5_SNP0_EN);
92 writel(val, LPC_HICR5);
93
94 /* enable port80h snoop on SGPIO */
95 val = readl(LPC_HICRB);
96 val |= LPC_HICRB_80HSGPIO_EN;
97 writel(val, LPC_HICRB);
98 }
99
sgpio_init(void)100 static void sgpio_init(void)
101 {
102 #define SGPIO_CLK_DIV(N) ((N) << 16)
103 #define SGPIO_BYTES(N) ((N) << 6)
104 #define SGPIO_ENABLE 1
105 #define SCU_414_SGPM_MASK GENMASK(27, 24)
106
107 /* set the sgpio clock to pclk/(2*(5+1)) or ~2 MHz */
108 u32 val;
109
110 val = ((256 << SGPIO_M1_CONF_CLKDIV_SHIFT) & SGPIO_M1_CONF_CLKDIV_MASK) |
111 ((10 << SGPIO_M1_PINS_SHIFT) & SGPIO_M1_PINS_MASK) |
112 SPGIO_M1_EN;
113 writel(val, SGPIO_M1_CONF);
114
115 val = readl(SCU_PINMUX5);
116 val |= (SCU_PINMUX5_SGPMI |
117 SCU_PINMUX5_SGPMO |
118 SCU_PINMUX5_SGPMLD |
119 SCU_PINMUX5_SGPMCK);
120 writel(val, SCU_PINMUX5);
121 }
122
gpio_init(void)123 static void gpio_init(void)
124 {
125 /* Default setting of Y23 pad in AST2600 A1 is HBLED so disable it. */
126 writel(readl(SCU_PINMUX27) & ~SCU_PINMUX27_HBLED_EN,
127 SCU_PINMUX27);
128
129 /*
130 * Set GPIOC3 as an output with value high explicitly since it doesn't
131 * have an external pull up. It uses direct register access because
132 * it's called from board_early_init_f().
133 */
134 writel(readl(SCU_PINMUX4) & ~SCU_PINMUX4_RGMII3TXD1,
135 SCU_PINMUX4);
136 writel(readl(GPIO_ABCD_DIR) | GPIO_ABCD_DIR_C3,
137 GPIO_ABCD_DIR);
138 writel(readl(GPIO_ABCD_VAL) | GPIO_ABCD_VAL_C3,
139 GPIO_ABCD_VAL);
140
141 writel(readl(SCU_GPIO_PD0) | SCU_GPIO_PD0_B6, SCU_GPIO_PD0);
142
143 /*
144 * GPIO C5 has a connection between BMC(3.3v) and CPU(1.0v) so if we
145 * set it as an logic high output, it will be clipped by a protection
146 * circuit in the CPU and eventually the signal will be detected as
147 * logic low. So we leave this GPIO as an input so that the signal
148 * can be pulled up by a CPU internal resister. The signal will be
149 * 1.0v logic high resultingy.
150 */
151 writel(readl(GPIO_ABCD_DIR) & ~GPIO_ABCD_DIR_C5,
152 GPIO_ABCD_DIR);
153
154 /*
155 * Set GPIOD4 as an output with value low explicitly to set the
156 * default SPD mux path to CPU and DIMMs.
157 */
158 writel(readl(GPIO_ABCD_DIR) | GPIO_ABCD_DIR_D4,
159 GPIO_ABCD_DIR);
160 writel(readl(GPIO_ABCD_VAL) & ~GPIO_ABCD_VAL_D4,
161 GPIO_ABCD_VAL);
162
163 /* GPIO G6 is also an open-drain output so set it as an input. */
164 writel(readl(GPIO_EFGH_DIR) & ~GPIO_EFGH_DIR_G6,
165 GPIO_EFGH_DIR);
166 }
167
espi_init(void)168 static void espi_init(void)
169 {
170 u32 reg;
171
172 /*
173 * Aspeed STRONGLY NOT recommend to use eSPI early init.
174 *
175 * This eSPI early init sequence merely set OOB_FREE. It
176 * is NOT able to actually handle OOB requests from PCH.
177 *
178 * During the power on stage, PCH keep waiting OOB_FREE
179 * to continue its booting. In general, OOB_FREE is set
180 * when BMC firmware is ready. That is, the eSPI kernel
181 * driver is mounted and ready to serve eSPI. However,
182 * it means that PCH must wait until BMC kernel ready.
183 *
184 * For customers that request PCH booting as soon as
185 * possible. You may use this early init to set OOB_FREE
186 * to prevent PCH from blocking by OOB_FREE before BMC
187 * kernel ready.
188 *
189 * If you are not sure what you are doing, DO NOT use it.
190 */
191 reg = readl(ESPI_CTRL);
192 reg |= 0xef;
193 writel(reg, ESPI_CTRL);
194
195 writel(0x0, ESPI_SYSEVT_INT_T0);
196 writel(0x0, ESPI_SYSEVT_INT_T1);
197
198 reg = readl(ESPI_INT_EN);
199 reg |= 0x80000000;
200 writel(reg, ESPI_INT_EN);
201
202 writel(0xffffffff, ESPI_SYSEVT_INT_EN);
203 writel(0x1, ESPI_SYSEVT1_INT_EN);
204 writel(0x1, ESPI_SYSEVT1_INT_T0);
205
206 reg = readl(ESPI_CTRL2);
207 reg |= 0x50;
208 writel(reg, ESPI_CTRL2);
209
210 reg = readl(ESPI_CTRL);
211 reg |= 0x10;
212 writel(reg, ESPI_CTRL);
213 }
214
board_early_init_f(void)215 int board_early_init_f(void)
216 {
217 snoop_init();
218 gpio_init();
219 sgpio_init();
220 espi_init();
221 return 0;
222 }
223