1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2016 Google, Inc
4  */
5 #include <common.h>
6 #include <dm.h>
7 #include <ram.h>
8 #include <timer.h>
9 #include <asm/io.h>
10 #include <asm/arch/platform.h>
11 #include <asm/arch/scu_ast2500.h>
12 #include <asm/arch/sdram_ast2500.h>
13 #include <asm/arch/timer.h>
14 #include <linux/err.h>
15 #include <dm/uclass.h>
16 
17 DECLARE_GLOBAL_DATA_PTR;
18 
19 #define AST_LPC_HICR5 0x080
20 # define LPC_HICR5_ENFWH BIT(10)
21 #define AST_LPC_HICRB 0x100
22 # define LPC_HICRB_SIO_ILPC2AHB_DIS BIT(6)
23 
24 # define AST_SDMC_PROTECT 0x00
25 # define AST_SDMC_GFX_PROT 0x08
26 #  define SDMC_GFX_PROT_VGA_CURSOR BIT(0)
27 #  define SDMC_GFX_PROT_VGA_CG_READ BIT(1)
28 #  define SDMC_GFX_PROT_VGA_ASCII_READ BIT(2)
29 #  define SDMC_GFX_PROT_VGA_CRT BIT(3)
30 #  define SDMC_GFX_PROT_PCIE BIT(16)
31 #  define SDMC_GFX_PROT_XDMA BIT(17)
32 
isolate_bmc(void)33 static void isolate_bmc(void)
34 {
35 	bool sdmc_unlocked;
36 	u32 val;
37 
38 	/* iLPC2AHB */
39 #if !defined(CONFIG_ASPEED_ENABLE_SUPERIO)
40 	val = readl(ASPEED_HW_STRAP1);
41 	val |= SCU_HWSTRAP_LPC_SIO_DEC_DIS;
42 	writel(val, ASPEED_HW_STRAP1);
43 #endif
44 
45 	val = readl(ASPEED_LPC_CTRL + AST_LPC_HICRB);
46 	val |= LPC_HICRB_SIO_ILPC2AHB_DIS;
47 	writel(val, ASPEED_LPC_CTRL + AST_LPC_HICRB);
48 
49 	/* P2A, PCIe BMC */
50 	val = readl(ASPEED_PCIE_CONFIG_SET);
51 	val &= ~(SCU_PCIE_CONFIG_SET_BMC_DMA
52 	         | SCU_PCIE_CONFIG_SET_BMC_MMIO
53 	         | SCU_PCIE_CONFIG_SET_BMC_EN
54 	         | SCU_PCIE_CONFIG_SET_VGA_MMIO);
55 	writel(val, ASPEED_PCIE_CONFIG_SET);
56 
57 	/* Debug UART */
58 #if !defined(CONFIG_ASPEED_ENABLE_DEBUG_UART)
59 	val = readl(ASPEED_MISC1_CTRL);
60 	val |= SCU_MISC_DEBUG_UART_DISABLE;
61 	writel(val, ASPEED_MISC1_CTRL);
62 #endif
63 
64 	/* X-DMA */
65 	sdmc_unlocked = readl(ASPEED_SDRAM_CTRL + AST_SDMC_PROTECT);
66 	if (!sdmc_unlocked)
67 		writel(SDRAM_UNLOCK_KEY, ASPEED_SDRAM_CTRL + AST_SDMC_PROTECT);
68 
69 	val = readl(ASPEED_SDRAM_CTRL + AST_SDMC_GFX_PROT);
70 	val |= (SDMC_GFX_PROT_VGA_CURSOR
71 	        | SDMC_GFX_PROT_VGA_CG_READ
72 	        | SDMC_GFX_PROT_VGA_ASCII_READ
73 	        | SDMC_GFX_PROT_VGA_CRT
74 	        | SDMC_GFX_PROT_PCIE
75 	        | SDMC_GFX_PROT_XDMA);
76 	writel(val, ASPEED_SDRAM_CTRL + AST_SDMC_GFX_PROT);
77 
78 	if (!sdmc_unlocked)
79 		writel(~SDRAM_UNLOCK_KEY, ASPEED_SDRAM_CTRL + AST_SDMC_PROTECT);
80 
81 	/* LPC2AHB */
82 	val = readl(ASPEED_LPC_CTRL + AST_LPC_HICR5);
83 	val &= ~LPC_HICR5_ENFWH;
84 	writel(val, ASPEED_LPC_CTRL + AST_LPC_HICR5);
85 }
86 
board_init(void)87 __weak int board_init(void)
88 {
89 	struct udevice *dev;
90 	int i;
91 	int ret;
92 
93 	isolate_bmc();
94 
95 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
96 
97 	/*
98 	 * Loop over all MISC uclass drivers to call the comphy code
99 	 * and init all CP110 devices enabled in the DT
100 	 */
101 	i = 0;
102 	while (1) {
103 		/* Call the comphy code via the MISC uclass driver */
104 		ret = uclass_get_device(UCLASS_MISC, i++, &dev);
105 
106 		/* We're done, once no further CP110 device is found */
107 		if (ret)
108 			break;
109 	}
110 
111 	return 0;
112 }
113 
114 #define SDMC_CONFIG_VRAM_GET(x)		((x >> 2) & 0x3)
115 #define SDMC_CONFIG_MEM_GET(x)		(x & 0x3)
116 #define SDMC_CONFIG_ECC_STATUS_GET(x)	((x) & BIT(7))
117 
118 static const u32 ast2500_dram_table[] = {
119 	0x08000000,	//128MB
120 	0x10000000,	//256MB
121 	0x20000000,	//512MB
122 	0x40000000,	//1024MB
123 };
124 
125 u32
ast_sdmc_get_mem_size(void)126 ast_sdmc_get_mem_size(void)
127 {
128 	u32 size = 0;
129 	u32 size_conf = SDMC_CONFIG_MEM_GET(readl(0x1e6e0004));
130 
131 	size = ast2500_dram_table[size_conf];
132 
133 	return size;
134 
135 }
136 
137 static const u32 aspeed_vram_table[] = {
138 	0x00800000,	//8MB
139 	0x01000000,	//16MB
140 	0x02000000,	//32MB
141 	0x04000000,	//64MB
142 };
143 
144 static u32
ast_sdmc_get_vram_size(void)145 ast_sdmc_get_vram_size(void)
146 {
147 	u32 size_conf = SDMC_CONFIG_VRAM_GET(readl(0x1e6e0004));
148 	return aspeed_vram_table[size_conf];
149 }
150 
ast_sdmc_is_ecc_on(void)151 static bool ast_sdmc_is_ecc_on(void)
152 {
153 	u32 ecc_status = SDMC_CONFIG_ECC_STATUS_GET(readl(0x1e6e0004));
154 
155 	return !!ecc_status;
156 }
157 
ast_sdmc_get_ecc_size(void)158 static u32 ast_sdmc_get_ecc_size(void)
159 {
160 	if (ast_sdmc_is_ecc_on())
161 		return readl(0x1e6e0054) + (1 << 20);
162 	else
163 		return 0;
164 }
165 
dram_init(void)166 __weak int dram_init(void)
167 {
168 #ifdef CONFIG_RAM
169 	struct udevice *dev;
170 	struct ram_info ram;
171 	int ret;
172 
173 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
174 	if (ret) {
175 		debug("DRAM FAIL1\r\n");
176 		return ret;
177 	}
178 
179 	ret = ram_get_info(dev, &ram);
180 	if (ret) {
181 		debug("DRAM FAIL2\r\n");
182 		return ret;
183 	}
184 
185 	gd->ram_size = ram.size;
186 #else
187 	u32 vga = ast_sdmc_get_vram_size();
188 	u32 dram = ast_sdmc_get_mem_size();
189 
190 #ifdef CONFIG_ARCH_FIXUP_FDT_MEMORY
191 	/*
192 	 * U-boot will fixup the memory node in kernel's DT.  The ECC redundancy
193 	 * is unable to handle now, just report the ECC size as the ram size.
194 	 */
195 	if (ast_sdmc_is_ecc_on())
196 		gd->ram_size = ast_sdmc_get_ecc_size();
197 	else
198 		gd->ram_size = dram - vga;
199 #else
200 	/*
201 	 * Report the memory size regardless the ECC redundancy, let kernel
202 	 * handle the ram paritions
203 	 */
204 	gd->ram_size = dram - vga;
205 #endif /* end of "#ifdef CONFIG_ARCH_FIXUP_FDT_MEMORY" */
206 #endif /* end of "#ifdef CONFIG_RAM" */
207 	return 0;
208 }
209 
board_add_ram_info(int use_default)210 void board_add_ram_info(int use_default)
211 {
212 	u32 act_size = ast_sdmc_get_mem_size() >> 20;
213 	u32 vga_rsvd = ast_sdmc_get_vram_size() >> 20;
214 	u32 ecc_size = ast_sdmc_get_ecc_size() >> 20;
215 	bool ecc_on = ast_sdmc_is_ecc_on();
216 
217 	printf(" (capacity:%d MiB, VGA:%d MiB, ECC:%s", act_size, vga_rsvd,
218 	       ecc_on ? "on" : "off");
219 
220 	if (ecc_on)
221 		printf(", ECC size:%d MiB", ecc_size);
222 
223 	printf(")");
224 }
225 
arch_early_init_r(void)226 int arch_early_init_r(void)
227 {
228 #ifdef CONFIG_DM_PCI
229 	/* Trigger PCIe devices detection */
230 	pci_init();
231 #endif
232 
233 	return 0;
234 }
235 
236