]>
Commit | Line | Data |
---|---|---|
5894ca00 | 1 | /* |
4d13b1b7 MY |
2 | * Copyright (C) 2012-2015 Panasonic Corporation |
3 | * Copyright (C) 2015 Socionext Inc. | |
4 | * Author: Masahiro Yamada <yamada.masahiro@socionext.com> | |
5894ca00 MY |
5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
a86ac954 | 11 | #include <mach/board.h> |
5894ca00 MY |
12 | |
13 | #if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) | |
14 | ||
15 | #define PFC_MICRO_SUPPORT_CARD_RESET \ | |
16 | ((CONFIG_SUPPORT_CARD_BASE) + 0x000D0034) | |
17 | #define PFC_MICRO_SUPPORT_CARD_REVISION \ | |
18 | ((CONFIG_SUPPORT_CARD_BASE) + 0x000D00E0) | |
19 | /* | |
20 | * 0: reset deassert, 1: reset | |
21 | * | |
22 | * bit[0]: LAN, I2C, LED | |
23 | * bit[1]: UART | |
24 | */ | |
25 | void support_card_reset_deassert(void) | |
26 | { | |
27 | writel(0, PFC_MICRO_SUPPORT_CARD_RESET); | |
28 | } | |
29 | ||
30 | void support_card_reset(void) | |
31 | { | |
32 | writel(3, PFC_MICRO_SUPPORT_CARD_RESET); | |
33 | } | |
34 | ||
35 | static int support_card_show_revision(void) | |
36 | { | |
37 | u32 revision; | |
38 | ||
39 | revision = readl(PFC_MICRO_SUPPORT_CARD_REVISION); | |
40 | printf("(PFC CPLD version %d.%d)\n", revision >> 4, revision & 0xf); | |
41 | return 0; | |
42 | } | |
43 | #endif | |
44 | ||
45 | #if defined(CONFIG_DCC_MICRO_SUPPORT_CARD) | |
46 | ||
47 | #define DCC_MICRO_SUPPORT_CARD_RESET_LAN \ | |
48 | ((CONFIG_SUPPORT_CARD_BASE) + 0x00401300) | |
49 | #define DCC_MICRO_SUPPORT_CARD_RESET_UART \ | |
50 | ((CONFIG_SUPPORT_CARD_BASE) + 0x00401304) | |
51 | #define DCC_MICRO_SUPPORT_CARD_RESET_I2C \ | |
52 | ((CONFIG_SUPPORT_CARD_BASE) + 0x00401308) | |
53 | #define DCC_MICRO_SUPPORT_CARD_REVISION \ | |
54 | ((CONFIG_SUPPORT_CARD_BASE) + 0x005000E0) | |
55 | ||
56 | void support_card_reset_deassert(void) | |
57 | { | |
58 | writel(1, DCC_MICRO_SUPPORT_CARD_RESET_LAN); /* LAN and LED */ | |
59 | writel(1, DCC_MICRO_SUPPORT_CARD_RESET_UART); /* UART */ | |
60 | writel(1, DCC_MICRO_SUPPORT_CARD_RESET_I2C); /* I2C */ | |
61 | } | |
62 | ||
63 | void support_card_reset(void) | |
64 | { | |
65 | writel(0, DCC_MICRO_SUPPORT_CARD_RESET_LAN); /* LAN and LED */ | |
66 | writel(0, DCC_MICRO_SUPPORT_CARD_RESET_UART); /* UART */ | |
67 | writel(0, DCC_MICRO_SUPPORT_CARD_RESET_I2C); /* I2C */ | |
68 | } | |
69 | ||
70 | static int support_card_show_revision(void) | |
71 | { | |
72 | u32 revision; | |
73 | ||
74 | revision = readl(DCC_MICRO_SUPPORT_CARD_REVISION); | |
75 | ||
76 | if (revision >= 0x67) { | |
77 | printf("(DCC CPLD version 3.%d.%d)\n", | |
78 | revision >> 4, revision & 0xf); | |
79 | return 0; | |
80 | } else { | |
81 | printf("(DCC CPLD unknown version)\n"); | |
82 | return -1; | |
83 | } | |
84 | } | |
85 | #endif | |
86 | ||
7a3620b2 MY |
87 | int check_support_card(void) |
88 | { | |
89 | printf("SC: Micro Support Card "); | |
90 | return support_card_show_revision(); | |
91 | } | |
92 | ||
5894ca00 MY |
93 | void support_card_init(void) |
94 | { | |
95 | /* | |
96 | * After power on, we need to keep the LAN controller in reset state | |
97 | * for a while. (200 usec) | |
4d13b1b7 | 98 | * Fortunately, enough wait time is already inserted in pll_init() |
5894ca00 MY |
99 | * function. So we do not have to wait here. |
100 | */ | |
101 | support_card_reset_deassert(); | |
102 | } | |
103 | ||
5894ca00 MY |
104 | #if defined(CONFIG_SMC911X) |
105 | #include <netdev.h> | |
106 | ||
107 | int board_eth_init(bd_t *bis) | |
108 | { | |
109 | return smc911x_initialize(0, CONFIG_SMC911X_BASE); | |
110 | } | |
111 | #endif | |
112 | ||
113 | #if !defined(CONFIG_SYS_NO_FLASH) | |
114 | ||
115 | #include <mtd/cfi_flash.h> | |
a86ac954 | 116 | #include <mach/sbc-regs.h> |
5894ca00 | 117 | |
7a3620b2 MY |
118 | struct memory_bank { |
119 | phys_addr_t base; | |
120 | unsigned long size; | |
121 | }; | |
5894ca00 | 122 | |
7a3620b2 | 123 | static int mem_is_flash(const struct memory_bank *mem) |
5894ca00 MY |
124 | { |
125 | const int loop = 128; | |
126 | u32 *scratch_addr; | |
127 | u32 saved_value; | |
128 | int ret = 1; | |
129 | int i; | |
130 | ||
7a3620b2 MY |
131 | /* just in case, use the tail of the memory bank */ |
132 | scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop, | |
133 | sizeof(u32) * loop, MAP_NOCACHE); | |
5894ca00 MY |
134 | |
135 | for (i = 0; i < loop; i++, scratch_addr++) { | |
136 | saved_value = readl(scratch_addr); | |
137 | writel(~saved_value, scratch_addr); | |
138 | if (readl(scratch_addr) != saved_value) { | |
139 | /* We assume no memory or SRAM here. */ | |
140 | writel(saved_value, scratch_addr); | |
141 | ret = 0; | |
142 | break; | |
143 | } | |
144 | } | |
145 | ||
146 | unmap_physmem(scratch_addr, MAP_NOCACHE); | |
147 | ||
148 | return ret; | |
149 | } | |
150 | ||
7a3620b2 MY |
151 | #if defined(CONFIG_PFC_MICRO_SUPPORT_CARD) |
152 | /* {address, size} */ | |
153 | static const struct memory_bank memory_banks_boot_swap_off[] = { | |
154 | {0x02000000, 0x01f00000}, | |
155 | }; | |
156 | ||
157 | static const struct memory_bank memory_banks_boot_swap_on[] = { | |
158 | {0x00000000, 0x01f00000}, | |
159 | }; | |
160 | #endif | |
161 | ||
162 | #if defined(CONFIG_DCC_MICRO_SUPPORT_CARD) | |
163 | static const struct memory_bank memory_banks_boot_swap_off[] = { | |
5e165b25 | 164 | {0x04000000, 0x02000000}, |
7a3620b2 MY |
165 | }; |
166 | ||
167 | static const struct memory_bank memory_banks_boot_swap_on[] = { | |
5e165b25 MY |
168 | {0x00000000, 0x02000000}, |
169 | {0x04000000, 0x02000000}, | |
7a3620b2 MY |
170 | }; |
171 | #endif | |
172 | ||
173 | static const struct memory_bank | |
174 | *flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT]; | |
175 | ||
176 | phys_addr_t cfi_flash_bank_addr(int i) | |
5894ca00 | 177 | { |
7a3620b2 MY |
178 | return flash_banks_list[i]->base; |
179 | } | |
5894ca00 | 180 | |
7a3620b2 MY |
181 | unsigned long cfi_flash_bank_size(int i) |
182 | { | |
183 | return flash_banks_list[i]->size; | |
184 | } | |
185 | ||
186 | static void detect_num_flash_banks(void) | |
187 | { | |
188 | const struct memory_bank *memory_bank, *end; | |
189 | ||
190 | cfi_flash_num_flash_banks = 0; | |
191 | ||
192 | if (boot_is_swapped()) { | |
193 | memory_bank = memory_banks_boot_swap_on; | |
194 | end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_on); | |
195 | } else { | |
196 | memory_bank = memory_banks_boot_swap_off; | |
197 | end = memory_bank + ARRAY_SIZE(memory_banks_boot_swap_off); | |
198 | } | |
199 | ||
200 | for (; memory_bank < end; memory_bank++) { | |
201 | if (cfi_flash_num_flash_banks >= | |
202 | CONFIG_SYS_MAX_FLASH_BANKS_DETECT) | |
203 | break; | |
204 | ||
205 | if (mem_is_flash(memory_bank)) { | |
206 | flash_banks_list[cfi_flash_num_flash_banks] = | |
207 | memory_bank; | |
208 | ||
209 | debug("flash bank found: base = 0x%lx, size = 0x%lx\n", | |
210 | memory_bank->base, memory_bank->size); | |
211 | cfi_flash_num_flash_banks++; | |
5894ca00 | 212 | } |
5894ca00 MY |
213 | } |
214 | ||
7a3620b2 MY |
215 | debug("number of flash banks: %d\n", cfi_flash_num_flash_banks); |
216 | } | |
4d13b1b7 | 217 | #else /* CONFIG_SYS_NO_FLASH */ |
7a3620b2 MY |
218 | void detect_num_flash_banks(void) |
219 | { | |
220 | }; | |
4d13b1b7 | 221 | #endif /* CONFIG_SYS_NO_FLASH */ |
7a3620b2 MY |
222 | |
223 | void support_card_late_init(void) | |
224 | { | |
225 | detect_num_flash_banks(); | |
5894ca00 | 226 | } |