1
2
3
4
5
6
7
8#include <common.h>
9#include <linux/ctype.h>
10#include <linux/io.h>
11
12#include "micro-support-card.h"
13
14#define MICRO_SUPPORT_CARD_BASE 0x43f00000
15#define SMC911X_BASE ((MICRO_SUPPORT_CARD_BASE) + 0x00000)
16#define LED_BASE ((MICRO_SUPPORT_CARD_BASE) + 0x90000)
17#define NS16550A_BASE ((MICRO_SUPPORT_CARD_BASE) + 0xb0000)
18#define MICRO_SUPPORT_CARD_RESET ((MICRO_SUPPORT_CARD_BASE) + 0xd0034)
19#define MICRO_SUPPORT_CARD_REVISION ((MICRO_SUPPORT_CARD_BASE) + 0xd00E0)
20
21static bool support_card_found;
22
23static void support_card_detect(void)
24{
25 DECLARE_GLOBAL_DATA_PTR;
26 const void *fdt = gd->fdt_blob;
27 int offset;
28
29 offset = fdt_node_offset_by_compatible(fdt, 0, "smsc,lan9118");
30 if (offset < 0)
31 return;
32
33 offset = fdt_node_offset_by_compatible(fdt, 0, "ns16550a");
34 if (offset < 0)
35 return;
36
37 support_card_found = true;
38}
39
40
41
42
43
44
45
46static void support_card_reset_deassert(void)
47{
48 writel(0x00010000, MICRO_SUPPORT_CARD_RESET);
49}
50
51static void support_card_reset(void)
52{
53 writel(0x00020003, MICRO_SUPPORT_CARD_RESET);
54}
55
56static int support_card_show_revision(void)
57{
58 u32 revision;
59
60 revision = readl(MICRO_SUPPORT_CARD_REVISION);
61 revision &= 0xff;
62
63
64 printf("SC: Micro Support Card (CPLD version %s%d.%d)\n",
65 revision >> 4 == 6 ? "3." : "",
66 revision >> 4, revision & 0xf);
67
68 return 0;
69}
70
71void support_card_init(void)
72{
73 support_card_detect();
74
75 if (!support_card_found)
76 return;
77
78 support_card_reset();
79
80
81
82
83 udelay(200);
84 support_card_reset_deassert();
85
86 support_card_show_revision();
87}
88
89#if defined(CONFIG_SMC911X)
90#include <netdev.h>
91
92int board_eth_init(bd_t *bis)
93{
94 if (!support_card_found)
95 return 0;
96
97 return smc911x_initialize(0, SMC911X_BASE);
98}
99#endif
100
101#if defined(CONFIG_MTD_NOR_FLASH)
102
103#include <mtd/cfi_flash.h>
104
105struct memory_bank {
106 phys_addr_t base;
107 unsigned long size;
108};
109
110static int mem_is_flash(const struct memory_bank *mem)
111{
112 const int loop = 128;
113 u32 *scratch_addr;
114 u32 saved_value;
115 int ret = 1;
116 int i;
117
118
119 scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop,
120 sizeof(u32) * loop, MAP_NOCACHE);
121
122 for (i = 0; i < loop; i++, scratch_addr++) {
123 saved_value = readl(scratch_addr);
124 writel(~saved_value, scratch_addr);
125 if (readl(scratch_addr) != saved_value) {
126
127 writel(saved_value, scratch_addr);
128 ret = 0;
129 break;
130 }
131 }
132
133 unmap_physmem(scratch_addr, MAP_NOCACHE);
134
135 return ret;
136}
137
138
139static const struct memory_bank memory_banks[] = {
140 {0x42000000, 0x01f00000},
141};
142
143static const struct memory_bank
144*flash_banks_list[CONFIG_SYS_MAX_FLASH_BANKS_DETECT];
145
146phys_addr_t cfi_flash_bank_addr(int i)
147{
148 return flash_banks_list[i]->base;
149}
150
151unsigned long cfi_flash_bank_size(int i)
152{
153 return flash_banks_list[i]->size;
154}
155
156static void detect_num_flash_banks(void)
157{
158 const struct memory_bank *memory_bank, *end;
159
160 cfi_flash_num_flash_banks = 0;
161
162 memory_bank = memory_banks;
163 end = memory_bank + ARRAY_SIZE(memory_banks);
164
165 for (; memory_bank < end; memory_bank++) {
166 if (cfi_flash_num_flash_banks >=
167 CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
168 break;
169
170 if (mem_is_flash(memory_bank)) {
171 flash_banks_list[cfi_flash_num_flash_banks] =
172 memory_bank;
173
174 debug("flash bank found: base = 0x%lx, size = 0x%lx\n",
175 (unsigned long)memory_bank->base,
176 (unsigned long)memory_bank->size);
177 cfi_flash_num_flash_banks++;
178 }
179 }
180
181 debug("number of flash banks: %d\n", cfi_flash_num_flash_banks);
182}
183#else
184static void detect_num_flash_banks(void)
185{
186};
187#endif
188
189void support_card_late_init(void)
190{
191 if (!support_card_found)
192 return;
193
194 detect_num_flash_banks();
195}
196
197static const u8 ledval_num[] = {
198 0x7e,
199 0x0c,
200 0xb6,
201 0x9e,
202 0xcc,
203 0xda,
204 0xfa,
205 0x4e,
206 0xfe,
207 0xde,
208};
209
210static const u8 ledval_alpha[] = {
211 0xee,
212 0xf8,
213 0x72,
214 0xbc,
215 0xf2,
216 0xe2,
217 0x7a,
218 0xe8,
219 0x08,
220 0x3c,
221 0xea,
222 0x70,
223 0x6e,
224 0xa8,
225 0xb8,
226 0xe6,
227 0xce,
228 0xa0,
229 0xc8,
230 0x8c,
231 0x7c,
232 0x54,
233 0xfc,
234 0xec,
235 0xdc,
236 0xa4,
237};
238
239static u8 char2ledval(char c)
240{
241 if (isdigit(c))
242 return ledval_num[c - '0'];
243 else if (isalpha(c))
244 return ledval_alpha[toupper(c) - 'A'];
245
246 return 0;
247}
248
249void led_puts(const char *s)
250{
251 int i;
252 u32 val = 0;
253
254 if (!support_card_found)
255 return;
256
257 if (!s)
258 return;
259
260 for (i = 0; i < 4; i++) {
261 val <<= 8;
262 val |= char2ledval(*s);
263 if (*s != '\0')
264 s++;
265 }
266
267 writel(~val, LED_BASE);
268}
269