~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/post/board/lwmon5/gdc.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2008 Dmitry Rakhchev, EmCraft Systems, rda@emcraft.com
 
3
 *
 
4
 * Developed for DENX Software Engineering GmbH
 
5
 *
 
6
 * SPDX-License-Identifier:     GPL-2.0+
 
7
 */
 
8
#include <common.h>
 
9
 
 
10
/* This test attempts to verify board GDC. A scratch register tested, then
 
11
 * simple memory test (get_ram_size()) run over GDC memory.
 
12
 */
 
13
 
 
14
#include <post.h>
 
15
#include <watchdog.h>
 
16
#include <asm/io.h>
 
17
#include <video.h>
 
18
 
 
19
DECLARE_GLOBAL_DATA_PTR;
 
20
 
 
21
#define GDC_SCRATCH_REG 0xC1FF8044
 
22
#define GDC_VERSION_REG 0xC1FF8084
 
23
#define GDC_HOST_BASE   0xC1FC0000
 
24
#define GDC_RAM_START   0xC0000000
 
25
#define GDC_RAM_END     (GDC_HOST_BASE - 1)
 
26
#define GDC_RAM_SIZE    (GDC_RAM_END - GDC_RAM_START)
 
27
 
 
28
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC4
 
29
 
 
30
const static unsigned long pattern[] = {
 
31
        0xffffffff,
 
32
        0xaaaaaaaa,
 
33
        0xcccccccc,
 
34
        0xf0f0f0f0,
 
35
        0xff00ff00,
 
36
        0xffff0000,
 
37
        0x0000ffff,
 
38
        0x00ff00ff,
 
39
        0x0f0f0f0f,
 
40
        0x33333333,
 
41
        0x55555555,
 
42
        0x00000000
 
43
};
 
44
 
 
45
const static unsigned long otherpattern = 0x01234567;
 
46
 
 
47
/* test write/read og a given LIME Register */
 
48
static int gdc_test_reg_one(uint value)
 
49
{
 
50
        uint read_value;
 
51
 
 
52
        /* write test pattern */
 
53
        out_be32((void *)GDC_SCRATCH_REG, value);
 
54
        /* read other location (protect against data lines capacity) */
 
55
        in_be32((void *)GDC_RAM_START);
 
56
        /* verify test pattern */
 
57
        read_value = in_be32((void *)GDC_SCRATCH_REG);
 
58
        if (read_value != value) {
 
59
                post_log("GDC SCRATCH test failed write %08X, read %08X\n",
 
60
                         value, read_value);
 
61
        }
 
62
 
 
63
        return (read_value != value);
 
64
}
 
65
 
 
66
/* test with a given static 32 bit pattern in a given memory addressrange */
 
67
static int gdc_post_test1(ulong *start, ulong size, ulong val)
 
68
{
 
69
        int ret = 0;
 
70
        ulong i = 0;
 
71
        ulong *mem = start;
 
72
        ulong readback;
 
73
 
 
74
        for (i = 0; i < size / sizeof(ulong); i++) {
 
75
                mem[i] = val;
 
76
                if (i % 1024 == 0)
 
77
                        WATCHDOG_RESET();
 
78
        }
 
79
 
 
80
        for (i = 0; i < size / sizeof(ulong); i++) {
 
81
                readback = mem[i];
 
82
                if (readback != val) {
 
83
                        post_log("GDC Memory error at %08x, "
 
84
                                 "wrote %08x, read %08x !\n",
 
85
                                 mem + i, val, readback);
 
86
                        ret = -1;
 
87
                        break;
 
88
                }
 
89
                if (i % 1024 == 0)
 
90
                        WATCHDOG_RESET();
 
91
        }
 
92
 
 
93
        return ret;
 
94
}
 
95
 
 
96
/* test with dynamic 32 bit pattern in a given memory addressrange */
 
97
static int gdc_post_test2(ulong *start, ulong size)
 
98
{
 
99
        int ret = 0;
 
100
        ulong i = 0;
 
101
        ulong *mem = start;
 
102
        ulong readback;
 
103
 
 
104
        for (i = 0; i < size / sizeof(ulong); i++) {
 
105
                mem[i] = 1 << (i % 32);
 
106
                if (i % 1024 == 0)
 
107
                        WATCHDOG_RESET();
 
108
        }
 
109
 
 
110
        for (i = 0; i < size / sizeof(ulong); i++) {
 
111
                readback = mem[i];
 
112
                if (readback != 1 << (i % 32)) {
 
113
                        post_log("GDC Memory error at %08x, "
 
114
                                 "wrote %08x, read %08x !\n",
 
115
                                 mem + i, 1 << (i % 32), readback);
 
116
                        ret = -1;
 
117
                        break;
 
118
                }
 
119
                if (i % 1024 == 0)
 
120
                        WATCHDOG_RESET();
 
121
        }
 
122
 
 
123
        return ret;
 
124
}
 
125
 
 
126
/* test with dynamic 32 bit pattern in a given memory addressrange */
 
127
static int gdc_post_test3(ulong *start, ulong size)
 
128
{
 
129
        int ret = 0;
 
130
        ulong i = 0;
 
131
        ulong *mem = start;
 
132
        ulong readback;
 
133
 
 
134
        for (i = 0; i < size / sizeof(ulong); i++) {
 
135
                mem[i] = i;
 
136
                if (i % 1024 == 0)
 
137
                        WATCHDOG_RESET();
 
138
        }
 
139
 
 
140
        for (i = 0; i < size / sizeof(ulong); i++) {
 
141
                readback = mem[i];
 
142
                if (readback != i) {
 
143
                        post_log("GDC Memory error at %08x, "
 
144
                                 "wrote %08x, read %08x !\n",
 
145
                                 mem + i, i, readback);
 
146
                        ret = -1;
 
147
                        break;
 
148
                }
 
149
                if (i % 1024 == 0)
 
150
                        WATCHDOG_RESET();
 
151
        }
 
152
 
 
153
        return ret;
 
154
}
 
155
 
 
156
/* test with dynamic 32 bit pattern in a given memory addressrange */
 
157
static int gdc_post_test4(ulong *start, ulong size)
 
158
{
 
159
        int ret = 0;
 
160
        ulong i = 0;
 
161
        ulong *mem = start;
 
162
        ulong readback;
 
163
 
 
164
        for (i = 0; i < size / sizeof(ulong); i++) {
 
165
                mem[i] = ~i;
 
166
                if (i % 1024 == 0)
 
167
                        WATCHDOG_RESET();
 
168
        }
 
169
 
 
170
        for (i = 0; i < size / sizeof(ulong); i++) {
 
171
                readback = mem[i];
 
172
                if (readback != ~i) {
 
173
                        post_log("GDC Memory error at %08x, "
 
174
                                 "wrote %08x, read %08x !\n",
 
175
                                 mem + i, ~i, readback);
 
176
                        ret = -1;
 
177
                        break;
 
178
                }
 
179
                if (i % 1024 == 0)
 
180
                        WATCHDOG_RESET();
 
181
        }
 
182
 
 
183
        return ret;
 
184
}
 
185
 
 
186
/* do some patterntests in a given addressrange */
 
187
int gdc_mem_test(ulong *start, ulong size)
 
188
{
 
189
        int ret = 0;
 
190
 
 
191
        /*
 
192
         * check addressrange and do different static and dynamic
 
193
         * pattern tests with it.
 
194
         */
 
195
        if (((void *)start) + size <= (void *)GDC_RAM_END) {
 
196
                if (ret == 0)
 
197
                        ret = gdc_post_test1(start, size, 0x00000000);
 
198
 
 
199
                if (ret == 0)
 
200
                        ret = gdc_post_test1(start, size, 0xffffffff);
 
201
 
 
202
                if (ret == 0)
 
203
                        ret = gdc_post_test1(start, size, 0x55555555);
 
204
 
 
205
                if (ret == 0)
 
206
                        ret = gdc_post_test1(start, size, 0xaaaaaaaa);
 
207
 
 
208
                if (ret == 0)
 
209
                        ret = gdc_post_test2(start, size);
 
210
 
 
211
                if (ret == 0)
 
212
                        ret = gdc_post_test3(start, size);
 
213
 
 
214
                if (ret == 0)
 
215
                        ret = gdc_post_test4(start, size);
 
216
        }
 
217
 
 
218
        return ret;
 
219
}
 
220
 
 
221
/* test function of gdc memory addresslines*/
 
222
static int gdc_post_addrline(ulong *address, ulong *base, ulong size)
 
223
{
 
224
        ulong *target;
 
225
        ulong *end;
 
226
        ulong readback = 0;
 
227
        ulong xor = 0;
 
228
        int ret = 0;
 
229
 
 
230
        end = (ulong *)((ulong)base + size);
 
231
 
 
232
        for (xor = sizeof(long); xor > 0; xor <<= 1) {
 
233
                target = (ulong *)((ulong)address ^ xor);
 
234
                if ((target >= base) && (target < end)) {
 
235
                        *address = ~*target;
 
236
                        readback = *target;
 
237
                }
 
238
 
 
239
                if (readback == *address) {
 
240
                        post_log("GDC Memory (address line) error at %08x"
 
241
                                 "XOR value %08x !\n",
 
242
                                 address, target , xor);
 
243
                        ret = -1;
 
244
                        break;
 
245
                }
 
246
        }
 
247
 
 
248
        return ret;
 
249
}
 
250
 
 
251
static int gdc_post_dataline(ulong *address)
 
252
{
 
253
        unsigned long temp32 = 0;
 
254
        int i = 0;
 
255
        int ret = 0;
 
256
 
 
257
        for (i = 0; i < ARRAY_SIZE(pattern); i++) {
 
258
                *address = pattern[i];
 
259
                /*
 
260
                 * Put a different pattern on the data lines: otherwise they
 
261
                 * may float long enough to read back what we wrote.
 
262
                 */
 
263
                *(address + 1) = otherpattern;
 
264
                temp32 = *address;
 
265
 
 
266
                if (temp32 != pattern[i]){
 
267
                        post_log("GDC Memory (date line) error at %08x, "
 
268
                                 "wrote %08x, read %08x !\n",
 
269
                                 address, pattern[i], temp32);
 
270
                        ret = 1;
 
271
                }
 
272
        }
 
273
 
 
274
        return ret;
 
275
}
 
276
 
 
277
/* Verify GDC, get memory size, verify GDC memory */
 
278
int gdc_post_test(int flags)
 
279
{
 
280
        uint    old_value;
 
281
        int     i = 0;
 
282
        int     ret = 0;
 
283
 
 
284
        post_log("\n");
 
285
        old_value = in_be32((void *)GDC_SCRATCH_REG);
 
286
 
 
287
        /*
 
288
         * GPIOC2 register behaviour: the LIME graphics processor has a
 
289
         * maximum of 5 GPIO ports that can be used in this hardware
 
290
         * configuration. Thus only the  bits  for these 5 GPIOs can be
 
291
         * activated in the GPIOC2 register. All other bits will always be
 
292
         * read as zero.
 
293
         */
 
294
        if (gdc_test_reg_one(0x00150015))
 
295
                ret = 1;
 
296
        if (gdc_test_reg_one(0x000A000A))
 
297
                ret = 1;
 
298
 
 
299
        out_be32((void *)GDC_SCRATCH_REG, old_value);
 
300
 
 
301
        old_value = in_be32((void *)GDC_VERSION_REG);
 
302
        post_log("GDC chip version %u.%u, year %04X\n",
 
303
                 (old_value >> 8) & 0xFF, old_value & 0xFF,
 
304
                 (old_value >> 16) & 0xFFFF);
 
305
 
 
306
        old_value = get_ram_size((void *)GDC_RAM_START,
 
307
                                 0x02000000);
 
308
 
 
309
        debug("GDC RAM size (ist):  %d bytes\n", old_value);
 
310
        debug("GDC RAM size (soll): %d bytes\n", GDC_RAM_SIZE);
 
311
        post_log("GDC RAM size: %d bytes\n", old_value);
 
312
 
 
313
        /* Test SDRAM datalines */
 
314
        if (gdc_post_dataline((ulong *)GDC_RAM_START)) {
 
315
                ret = 1;
 
316
                goto out;
 
317
        }
 
318
        WATCHDOG_RESET();
 
319
 
 
320
        /* Test SDRAM adresslines */
 
321
        if (gdc_post_addrline((ulong *)GDC_RAM_START,
 
322
                              (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
 
323
                ret = 1;
 
324
                goto out;
 
325
        }
 
326
        WATCHDOG_RESET();
 
327
        if (gdc_post_addrline((ulong *)GDC_RAM_END - sizeof(long),
 
328
                              (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
 
329
                ret = 1;
 
330
                goto out;
 
331
        }
 
332
        WATCHDOG_RESET();
 
333
 
 
334
        /* memory pattern test */
 
335
        debug("GDC Memory test (flags %8x:%8x)\n", flags,
 
336
              POST_SLOWTEST | POST_MANUAL);
 
337
 
 
338
        if (flags & POST_MANUAL) {
 
339
                debug("Full memory test\n");
 
340
                if (gdc_mem_test((ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
 
341
                        ret = 1;
 
342
                        goto out;
 
343
                }
 
344
                /* load splashscreen again */
 
345
        } else {
 
346
                debug("smart memory test\n");
 
347
                for (i = 0; i < (GDC_RAM_SIZE >> 20) && ret == 0; i++) {
 
348
                        if (ret == 0)
 
349
                                ret = gdc_mem_test((ulong *)(GDC_RAM_START +
 
350
                                                             (i << 20)),
 
351
                                                   0x800);
 
352
                        if (ret == 0)
 
353
                                ret = gdc_mem_test((ulong *)(GDC_RAM_START +
 
354
                                                             (i << 20) + 0xff800),
 
355
                                                   0x800);
 
356
                }
 
357
        }
 
358
        WATCHDOG_RESET();
 
359
 
 
360
out:
 
361
        return ret;
 
362
}
 
363
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC4 */