source: SVN/rincon/u-boot/common/cmd_onenand.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 4.0 KB
Line 
1/*
2 *  U-Boot command for OneNAND support
3 *
4 *  Copyright (C) 2005-2007 Samsung Electronics
5 *  Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <common.h>
13#include <command.h>
14
15#include <linux/mtd/compat.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/onenand.h>
18
19#include <asm/io.h>
20
21extern struct mtd_info onenand_mtd;
22extern struct onenand_chip onenand_chip;
23
24int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
25{
26        int ret = 0;
27
28        switch (argc) {
29        case 0:
30        case 1:
31                printf("Usage:\n%s\n", cmdtp->usage);
32                return 1;
33
34        case 2:
35                if (strncmp(argv[1], "open", 4) == 0) {
36                        onenand_init();
37                        return 0;
38                }
39                printf("%s\n", onenand_mtd.name);
40                return 0;
41
42        default:
43                /* At least 4 args */
44                if (strncmp(argv[1], "erase", 5) == 0) {
45                        struct erase_info instr = {
46                                .callback       = NULL,
47                        };
48                        ulong start, end;
49                        ulong block;
50                        char *endtail;
51
52                        if (strncmp(argv[2], "block", 5) == 0) {
53                                start = simple_strtoul(argv[3], NULL, 10);
54                                endtail = strchr(argv[3], '-');
55                                end = simple_strtoul(endtail + 1, NULL, 10);
56                        } else {
57                                start = simple_strtoul(argv[2], NULL, 10);
58                                end = simple_strtoul(argv[3], NULL, 10);
59
60                                start >>= onenand_chip.erase_shift;
61                                end >>= onenand_chip.erase_shift;
62                                /* Don't include the end block */
63                                end--;
64                        }
65
66                        if (!end || end < 0)
67                                end = start;
68
69                        printf("Erase block from %lu to %lu\n", start, end);
70
71                        for (block = start; block <= end; block++) {
72                                instr.addr = block << onenand_chip.erase_shift;
73                                instr.len = 1 << onenand_chip.erase_shift;
74                                ret = onenand_erase(&onenand_mtd, &instr);
75                                if (ret) {
76                                        printf("erase failed %lu\n", block);
77                                        break;
78                                }
79                        }
80
81                        return 0;
82                }
83
84                if (strncmp(argv[1], "read", 4) == 0) {
85                        ulong addr = simple_strtoul(argv[2], NULL, 16);
86                        ulong ofs = simple_strtoul(argv[3], NULL, 16);
87                        size_t len = simple_strtoul(argv[4], NULL, 16);
88                        int oob = strncmp(argv[1], "read.oob", 8) ? 0 : 1;
89                        struct mtd_oob_ops ops;
90
91                        ops.mode = MTD_OOB_PLACE;
92
93                        if (oob) {
94                                ops.len = 0;
95                                ops.datbuf = NULL;
96                                ops.ooblen = len;
97                                ops.oobbuf = (u_char *) addr;
98                        } else {
99                                ops.len = len;
100                                ops.datbuf = (u_char *) addr;
101                                ops.ooblen = 0;
102                                ops.oobbuf = NULL;
103                        }
104                        ops.retlen = ops.oobretlen = 0;
105
106                        onenand_mtd.read_oob(&onenand_mtd, ofs, &ops);
107                        printf("Done\n");
108
109                        return 0;
110                }
111
112                if (strncmp(argv[1], "write", 5) == 0) {
113                        ulong addr = simple_strtoul(argv[2], NULL, 16);
114                        ulong ofs = simple_strtoul(argv[3], NULL, 16);
115                        size_t len = simple_strtoul(argv[4], NULL, 16);
116                        size_t retlen = 0;
117
118                        onenand_write(&onenand_mtd, ofs, len, &retlen,
119                                      (u_char *) addr);
120                        printf("Done\n");
121
122                        return 0;
123                }
124
125                if (strncmp(argv[1], "block", 5) == 0) {
126                        ulong addr = simple_strtoul(argv[2], NULL, 16);
127                        ulong block = simple_strtoul(argv[3], NULL, 10);
128                        ulong page = simple_strtoul(argv[4], NULL, 10);
129                        size_t len = simple_strtol(argv[5], NULL, 10);
130                        ulong ofs;
131                        int oob = strncmp(argv[1], "block.oob", 9) ? 0 : 1;
132                        struct mtd_oob_ops ops;
133
134                        ops.mode = MTD_OOB_PLACE;
135
136
137                        ofs = block << onenand_chip.erase_shift;
138                        if (page)
139                                ofs += page << onenand_chip.page_shift;
140
141                        if (!len) {
142                                if (oob)
143                                        ops.ooblen = 64;
144                                else
145                                        ops.len = 512;
146                        }
147
148                        if (oob) {
149                                ops.datbuf = NULL;
150                                ops.oobbuf = (u_char *) addr;
151                        } else {
152                                ops.datbuf = (u_char *) addr;
153                                ops.oobbuf = NULL;
154                        }
155                        ops.retlen = ops.oobretlen = 0;
156
157                        onenand_read_oob(&onenand_mtd, ofs, &ops);
158                        return 0;
159                }
160
161                break;
162        }
163
164        return 0;
165}
166
167U_BOOT_CMD(
168        onenand,        6,      1,      do_onenand,
169        "onenand - OneNAND sub-system\n",
170        "info   - show available OneNAND devices\n"
171        "onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
172        "onenand write addr ofs len - write data at ofs with len from addr\n"
173        "onenand erase saddr eaddr - erase block start addr to end addr\n"
174        "onenand block[.oob] addr block [page] [len] - "
175                "read data with (block [, page]) to addr"
176);
Note: See TracBrowser for help on using the repository browser.