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 
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 
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 
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 
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 
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