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

« back to all changes in this revision

Viewing changes to roms/u-boot/board/keymile/common/common.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
 
3
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 
4
 *
 
5
 * (C) Copyright 2011
 
6
 * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
 
7
 *
 
8
 * SPDX-License-Identifier:     GPL-2.0+
 
9
 */
 
10
 
 
11
#include <common.h>
 
12
#include <ioports.h>
 
13
#include <command.h>
 
14
#include <malloc.h>
 
15
#include <hush.h>
 
16
#include <net.h>
 
17
#include <netdev.h>
 
18
#include <asm/io.h>
 
19
#include <linux/ctype.h>
 
20
 
 
21
#if defined(CONFIG_POST)
 
22
#include "post.h"
 
23
#endif
 
24
#include "common.h"
 
25
#include <i2c.h>
 
26
 
 
27
DECLARE_GLOBAL_DATA_PTR;
 
28
 
 
29
/*
 
30
 * Set Keymile specific environment variables
 
31
 * Currently only some memory layout variables are calculated here
 
32
 * ... ------------------------------------------------
 
33
 * ... |@rootfsaddr |@pnvramaddr |@varaddr |@reserved |@END_OF_RAM
 
34
 * ... |<------------------- pram ------------------->|
 
35
 * ... ------------------------------------------------
 
36
 * @END_OF_RAM: denotes the RAM size
 
37
 * @pnvramaddr: Startadress of pseudo non volatile RAM in hex
 
38
 * @pram      : preserved ram size in k
 
39
 * @varaddr   : startadress for /var mounted into RAM
 
40
 */
 
41
int set_km_env(void)
 
42
{
 
43
        uchar buf[32];
 
44
        unsigned int pnvramaddr;
 
45
        unsigned int pram;
 
46
        unsigned int varaddr;
 
47
        unsigned int kernelmem;
 
48
        char *p;
 
49
        unsigned long rootfssize = 0;
 
50
 
 
51
        pnvramaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM
 
52
                        - CONFIG_KM_PNVRAM;
 
53
        sprintf((char *)buf, "0x%x", pnvramaddr);
 
54
        setenv("pnvramaddr", (char *)buf);
 
55
 
 
56
        /* try to read rootfssize (ram image) from envrionment */
 
57
        p = getenv("rootfssize");
 
58
        if (p != NULL)
 
59
                strict_strtoul(p, 16, &rootfssize);
 
60
        pram = (rootfssize + CONFIG_KM_RESERVED_PRAM + CONFIG_KM_PHRAM +
 
61
                CONFIG_KM_PNVRAM) / 0x400;
 
62
        sprintf((char *)buf, "0x%x", pram);
 
63
        setenv("pram", (char *)buf);
 
64
 
 
65
        varaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM;
 
66
        sprintf((char *)buf, "0x%x", varaddr);
 
67
        setenv("varaddr", (char *)buf);
 
68
 
 
69
        kernelmem = gd->ram_size - 0x400 * pram;
 
70
        sprintf((char *)buf, "0x%x", kernelmem);
 
71
        setenv("kernelmem", (char *)buf);
 
72
 
 
73
        return 0;
 
74
}
 
75
 
 
76
#if defined(CONFIG_SYS_I2C_INIT_BOARD)
 
77
static void i2c_write_start_seq(void)
 
78
{
 
79
        set_sda(1);
 
80
        udelay(DELAY_HALF_PERIOD);
 
81
        set_scl(1);
 
82
        udelay(DELAY_HALF_PERIOD);
 
83
        set_sda(0);
 
84
        udelay(DELAY_HALF_PERIOD);
 
85
        set_scl(0);
 
86
        udelay(DELAY_HALF_PERIOD);
 
87
}
 
88
 
 
89
/*
 
90
 * I2C is a synchronous protocol and resets of the processor in the middle
 
91
 * of an access can block the I2C Bus until a powerdown of the full unit is
 
92
 * done. This function toggles the SCL until the SCL and SCA line are
 
93
 * released, but max. 16 times, after this a I2C start-sequence is sent.
 
94
 * This I2C Deblocking mechanism was developed by Keymile in association
 
95
 * with Anatech and Atmel in 1998.
 
96
 */
 
97
int i2c_make_abort(void)
 
98
{
 
99
        int     scl_state = 0;
 
100
        int     sda_state = 0;
 
101
        int     i = 0;
 
102
        int     ret = 0;
 
103
 
 
104
        if (!get_sda()) {
 
105
                ret = -1;
 
106
                while (i < 16) {
 
107
                        i++;
 
108
                        set_scl(0);
 
109
                        udelay(DELAY_ABORT_SEQ);
 
110
                        set_scl(1);
 
111
                        udelay(DELAY_ABORT_SEQ);
 
112
                        scl_state = get_scl();
 
113
                        sda_state = get_sda();
 
114
                        if (scl_state && sda_state) {
 
115
                                ret = 0;
 
116
                                break;
 
117
                        }
 
118
                }
 
119
        }
 
120
        if (ret == 0)
 
121
                for (i = 0; i < 5; i++)
 
122
                        i2c_write_start_seq();
 
123
 
 
124
        /* respect stop setup time */
 
125
        udelay(DELAY_ABORT_SEQ);
 
126
        set_scl(1);
 
127
        udelay(DELAY_ABORT_SEQ);
 
128
        set_sda(1);
 
129
        get_sda();
 
130
 
 
131
        return ret;
 
132
}
 
133
 
 
134
/**
 
135
 * i2c_init_board - reset i2c bus. When the board is powercycled during a
 
136
 * bus transfer it might hang; for details see doc/I2C_Edge_Conditions.
 
137
 */
 
138
void i2c_init_board(void)
 
139
{
 
140
        /* Now run the AbortSequence() */
 
141
        i2c_make_abort();
 
142
}
 
143
#endif
 
144
 
 
145
#if defined(CONFIG_KM_COMMON_ETH_INIT)
 
146
int board_eth_init(bd_t *bis)
 
147
{
 
148
        if (ethernet_present())
 
149
                return cpu_eth_init(bis);
 
150
 
 
151
        return -1;
 
152
}
 
153
#endif
 
154
 
 
155
/*
 
156
 * do_setboardid command
 
157
 * read out the board id and the hw key from the intventory EEPROM and set
 
158
 * this values as environment variables.
 
159
 */
 
160
static int do_setboardid(cmd_tbl_t *cmdtp, int flag, int argc,
 
161
                                char *const argv[])
 
162
{
 
163
        unsigned char buf[32];
 
164
        char *p;
 
165
 
 
166
        p = get_local_var("IVM_BoardId");
 
167
        if (p == NULL) {
 
168
                printf("can't get the IVM_Boardid\n");
 
169
                return 1;
 
170
        }
 
171
        sprintf((char *)buf, "%s", p);
 
172
        setenv("boardid", (char *)buf);
 
173
        printf("set boardid=%s\n", buf);
 
174
 
 
175
        p = get_local_var("IVM_HWKey");
 
176
        if (p == NULL) {
 
177
                printf("can't get the IVM_HWKey\n");
 
178
                return 1;
 
179
        }
 
180
        sprintf((char *)buf, "%s", p);
 
181
        setenv("hwkey", (char *)buf);
 
182
        printf("set hwkey=%s\n", buf);
 
183
        printf("Execute manually saveenv for persistent storage.\n");
 
184
 
 
185
        return 0;
 
186
}
 
187
 
 
188
U_BOOT_CMD(km_setboardid, 1, 0, do_setboardid, "setboardid", "read out bid and "
 
189
                                 "hwkey from IVM and set in environment");
 
190
 
 
191
/*
 
192
 * command km_checkbidhwk
 
193
 *      if "boardid" and "hwkey" are not already set in the environment, do:
 
194
 *              if a "boardIdListHex" exists in the environment:
 
195
 *                      - read ivm data for boardid and hwkey
 
196
 *                      - compare each entry of the boardIdListHex with the
 
197
 *                              IVM data:
 
198
 *                      if match:
 
199
 *                              set environment variables boardid, boardId,
 
200
 *                              hwkey, hwKey to the found values
 
201
 *                              both (boardid and boardId) are set because
 
202
 *                              they might be used differently in the
 
203
 *                              application and in the init scripts (?)
 
204
 *      return 0 in case of match, 1 if not match or error
 
205
 */
 
206
static int do_checkboardidhwk(cmd_tbl_t *cmdtp, int flag, int argc,
 
207
                        char *const argv[])
 
208
{
 
209
        unsigned long ivmbid = 0, ivmhwkey = 0;
 
210
        unsigned long envbid = 0, envhwkey = 0;
 
211
        char *p;
 
212
        int verbose = argc > 1 && *argv[1] == 'v';
 
213
        int rc = 0;
 
214
 
 
215
        /*
 
216
         * first read out the real inventory values, these values are
 
217
         * already stored in the local hush variables
 
218
         */
 
219
        p = get_local_var("IVM_BoardId");
 
220
        if (p == NULL) {
 
221
                printf("can't get the IVM_Boardid\n");
 
222
                return 1;
 
223
        }
 
224
        rc = strict_strtoul(p, 16, &ivmbid);
 
225
 
 
226
        p = get_local_var("IVM_HWKey");
 
227
        if (p == NULL) {
 
228
                printf("can't get the IVM_HWKey\n");
 
229
                return 1;
 
230
        }
 
231
        rc = strict_strtoul(p, 16, &ivmhwkey);
 
232
 
 
233
        if (!ivmbid || !ivmhwkey) {
 
234
                printf("Error: IVM_BoardId and/or IVM_HWKey not set!\n");
 
235
                return rc;
 
236
        }
 
237
 
 
238
        /* now try to read values from environment if available */
 
239
        p = getenv("boardid");
 
240
        if (p != NULL)
 
241
                rc = strict_strtoul(p, 16, &envbid);
 
242
        p = getenv("hwkey");
 
243
        if (p != NULL)
 
244
                rc = strict_strtoul(p, 16, &envhwkey);
 
245
 
 
246
        if (rc != 0) {
 
247
                printf("strict_strtoul returns error: %d", rc);
 
248
                return rc;
 
249
        }
 
250
 
 
251
        if (!envbid || !envhwkey) {
 
252
                /*
 
253
                 * BoardId/HWkey not available in the environment, so try the
 
254
                 * environment variable for BoardId/HWkey list
 
255
                 */
 
256
                char *bidhwklist = getenv("boardIdListHex");
 
257
 
 
258
                if (bidhwklist) {
 
259
                        int found = 0;
 
260
                        char *rest = bidhwklist;
 
261
                        char *endp;
 
262
 
 
263
                        if (verbose) {
 
264
                                printf("IVM_BoardId: %ld, IVM_HWKey=%ld\n",
 
265
                                        ivmbid, ivmhwkey);
 
266
                                printf("boardIdHwKeyList: %s\n",
 
267
                                        bidhwklist);
 
268
                        }
 
269
                        while (!found) {
 
270
                                /* loop over each bid/hwkey pair in the list */
 
271
                                unsigned long bid   = 0;
 
272
                                unsigned long hwkey = 0;
 
273
 
 
274
                                while (*rest && !isxdigit(*rest))
 
275
                                        rest++;
 
276
                                /*
 
277
                                 * use simple_strtoul because we need &end and
 
278
                                 * we know we got non numeric char at the end
 
279
                                 */
 
280
                                bid = simple_strtoul(rest, &endp, 16);
 
281
                                /* BoardId and HWkey are separated with a "_" */
 
282
                                if (*endp == '_') {
 
283
                                        rest  = endp + 1;
 
284
                                        /*
 
285
                                         * use simple_strtoul because we need
 
286
                                         * &end
 
287
                                         */
 
288
                                        hwkey = simple_strtoul(rest, &endp, 16);
 
289
                                        rest  = endp;
 
290
                                        while (*rest && !isxdigit(*rest))
 
291
                                                rest++;
 
292
                                }
 
293
                                if ((!bid) || (!hwkey)) {
 
294
                                        /* end of list */
 
295
                                        break;
 
296
                                }
 
297
                                if (verbose) {
 
298
                                        printf("trying bid=0x%lX, hwkey=%ld\n",
 
299
                                                bid, hwkey);
 
300
                                }
 
301
                                /*
 
302
                                 * Compare the values of the found entry in the
 
303
                                 * list with the valid values which are stored
 
304
                                 * in the inventory eeprom. If they are equal
 
305
                                 * set the values in environment variables.
 
306
                                 */
 
307
                                if ((bid == ivmbid) && (hwkey == ivmhwkey)) {
 
308
                                        char buf[10];
 
309
 
 
310
                                        found = 1;
 
311
                                        envbid   = bid;
 
312
                                        envhwkey = hwkey;
 
313
                                        sprintf(buf, "%lx", bid);
 
314
                                        setenv("boardid", buf);
 
315
                                        sprintf(buf, "%lx", hwkey);
 
316
                                        setenv("hwkey", buf);
 
317
                                }
 
318
                        } /* end while( ! found ) */
 
319
                }
 
320
        }
 
321
 
 
322
        /* compare now the values */
 
323
        if ((ivmbid == envbid) && (ivmhwkey == envhwkey)) {
 
324
                printf("boardid=0x%3lX, hwkey=%ld\n", envbid, envhwkey);
 
325
                rc = 0; /* match */
 
326
        } else {
 
327
                printf("Error: env boardid=0x%3lX, hwkey=%ld\n", envbid,
 
328
                        envhwkey);
 
329
                printf("       IVM bId=0x%3lX, hwKey=%ld\n", ivmbid, ivmhwkey);
 
330
                rc = 1; /* don't match */
 
331
        }
 
332
        return rc;
 
333
}
 
334
 
 
335
U_BOOT_CMD(km_checkbidhwk, 2, 0, do_checkboardidhwk,
 
336
                "check boardid and hwkey",
 
337
                "[v]\n  - check environment parameter "\
 
338
                "\"boardIdListHex\" against stored boardid and hwkey "\
 
339
                "from the IVM\n    v: verbose output"
 
340
);
 
341
 
 
342
/*
 
343
 * command km_checktestboot
 
344
 *  if the testpin of the board is asserted, return 1
 
345
 *  *   else return 0
 
346
 */
 
347
static int do_checktestboot(cmd_tbl_t *cmdtp, int flag, int argc,
 
348
                        char *const argv[])
 
349
{
 
350
        int testpin = 0;
 
351
        char *s = NULL;
 
352
        int testboot = 0;
 
353
        int verbose = argc > 1 && *argv[1] == 'v';
 
354
 
 
355
#if defined(CONFIG_POST)
 
356
        testpin = post_hotkeys_pressed();
 
357
        s = getenv("test_bank");
 
358
#endif
 
359
        /* when test_bank is not set, act as if testpin is not asserted */
 
360
        testboot = (testpin != 0) && (s);
 
361
        if (verbose) {
 
362
                printf("testpin   = %d\n", testpin);
 
363
                printf("test_bank = %s\n", s ? s : "not set");
 
364
                printf("boot test app : %s\n", (testboot) ? "yes" : "no");
 
365
        }
 
366
        /* return 0 means: testboot, therefore we need the inversion */
 
367
        return !testboot;
 
368
}
 
369
 
 
370
U_BOOT_CMD(km_checktestboot, 2, 0, do_checktestboot,
 
371
                "check if testpin is asserted",
 
372
                "[v]\n  v - verbose output"
 
373
);