OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [maps/] [integrator-flash.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*======================================================================
2
 
3
    drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
4
 
5
    Copyright (C) 2000 ARM Limited
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 as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
21
   This is access code for flashes using ARM's flash partitioning
22
   standards.
23
 
24
   $Id: integrator-flash.c,v 1.1.1.1 2004-04-15 01:51:50 phoenix Exp $
25
 
26
======================================================================*/
27
 
28
#include <linux/config.h>
29
#include <linux/module.h>
30
#include <linux/types.h>
31
#include <linux/kernel.h>
32
#include <linux/slab.h>
33
#include <linux/ioport.h>
34
#include <linux/init.h>
35
 
36
#include <linux/mtd/mtd.h>
37
#include <linux/mtd/map.h>
38
#include <linux/mtd/partitions.h>
39
 
40
#include <asm/hardware.h>
41
#include <asm/io.h>
42
#include <asm/system.h>
43
 
44
extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **);
45
 
46
// board specific stuff - sorry, it should be in arch/arm/mach-*.
47
#ifdef CONFIG_ARCH_INTEGRATOR
48
 
49
#define FLASH_BASE      INTEGRATOR_FLASH_BASE
50
#define FLASH_SIZE      INTEGRATOR_FLASH_SIZE
51
 
52
#define FLASH_PART_SIZE 0x400000
53
 
54
#define SC_CTRLC        (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
55
#define SC_CTRLS        (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
56
#define EBI_CSR1        (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
57
#define EBI_LOCK        (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
58
 
59
/*
60
 * Initialise the flash access systems:
61
 *  - Disable VPP
62
 *  - Assert WP
63
 *  - Set write enable bit in EBI reg
64
 */
65
static void armflash_flash_init(void)
66
{
67
        unsigned int tmp;
68
 
69
        __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
70
 
71
        tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
72
        __raw_writel(tmp, EBI_CSR1);
73
 
74
        if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
75
                __raw_writel(0xa05f, EBI_LOCK);
76
                __raw_writel(tmp, EBI_CSR1);
77
                __raw_writel(0, EBI_LOCK);
78
        }
79
}
80
 
81
/*
82
 * Shutdown the flash access systems:
83
 *  - Disable VPP
84
 *  - Assert WP
85
 *  - Clear write enable bit in EBI reg
86
 */
87
static void armflash_flash_exit(void)
88
{
89
        unsigned int tmp;
90
 
91
        __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
92
 
93
        /*
94
         * Clear the write enable bit in system controller EBI register.
95
         */
96
        tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
97
        __raw_writel(tmp, EBI_CSR1);
98
 
99
        if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
100
                __raw_writel(0xa05f, EBI_LOCK);
101
                __raw_writel(tmp, EBI_CSR1);
102
                __raw_writel(0, EBI_LOCK);
103
        }
104
}
105
 
106
static void armflash_flash_wp(int on)
107
{
108
        unsigned int reg;
109
 
110
        if (on)
111
                reg = SC_CTRLC;
112
        else
113
                reg = SC_CTRLS;
114
 
115
        __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
116
}
117
 
118
static void armflash_set_vpp(struct map_info *map, int on)
119
{
120
        unsigned int reg;
121
 
122
        if (on)
123
                reg = SC_CTRLS;
124
        else
125
                reg = SC_CTRLC;
126
 
127
        __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
128
}
129
#endif
130
 
131
#ifdef CONFIG_ARCH_P720T
132
 
133
#define FLASH_BASE              (0x04000000)
134
#define FLASH_SIZE              (64*1024*1024)
135
 
136
#define FLASH_PART_SIZE         (4*1024*1024)
137
#define FLASH_BLOCK_SIZE        (128*1024)
138
 
139
static void armflash_flash_init(void)
140
{
141
}
142
 
143
static void armflash_flash_exit(void)
144
{
145
}
146
 
147
static void armflash_flash_wp(int on)
148
{
149
}
150
 
151
static void armflash_set_vpp(struct map_info *map, int on)
152
{
153
}
154
#endif
155
 
156
static __u8 armflash_read8(struct map_info *map, unsigned long ofs)
157
{
158
        return readb(ofs + map->map_priv_2);
159
}
160
 
161
static __u16 armflash_read16(struct map_info *map, unsigned long ofs)
162
{
163
        return readw(ofs + map->map_priv_2);
164
}
165
 
166
static __u32 armflash_read32(struct map_info *map, unsigned long ofs)
167
{
168
        return readl(ofs + map->map_priv_2);
169
}
170
 
171
static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
172
{
173
        memcpy(to, (void *) (from + map->map_priv_2), len);
174
}
175
 
176
static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr)
177
{
178
        writeb(d, adr + map->map_priv_2);
179
}
180
 
181
static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr)
182
{
183
        writew(d, adr + map->map_priv_2);
184
}
185
 
186
static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr)
187
{
188
        writel(d, adr + map->map_priv_2);
189
}
190
 
191
static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
192
{
193
        memcpy((void *) (to + map->map_priv_2), from, len);
194
}
195
 
196
static struct map_info armflash_map =
197
{
198
        name:           "AFS",
199
        read8:          armflash_read8,
200
        read16:         armflash_read16,
201
        read32:         armflash_read32,
202
        copy_from:      armflash_copy_from,
203
        write8:         armflash_write8,
204
        write16:        armflash_write16,
205
        write32:        armflash_write32,
206
        copy_to:        armflash_copy_to,
207
        set_vpp:        armflash_set_vpp,
208
};
209
 
210
static struct mtd_info *mtd;
211
static struct mtd_partition *parts;
212
 
213
static int __init armflash_cfi_init(void *base, u_int size)
214
{
215
        int ret;
216
 
217
        armflash_flash_init();
218
        armflash_flash_wp(1);
219
 
220
        /*
221
         * look for CFI based flash parts fitted to this board
222
         */
223
        armflash_map.size       = size;
224
        armflash_map.buswidth   = 4;
225
        armflash_map.map_priv_2 = (unsigned long) base;
226
 
227
        /*
228
         * Also, the CFI layer automatically works out what size
229
         * of chips we have, and does the necessary identification
230
         * for us automatically.
231
         */
232
        mtd = do_map_probe("cfi_probe", &armflash_map);
233
        if (!mtd)
234
                return -ENXIO;
235
 
236
        mtd->module = THIS_MODULE;
237
 
238
        ret = parse_afs_partitions(mtd, &parts);
239
        if (ret > 0) {
240
                ret = add_mtd_partitions(mtd, parts, ret);
241
                if (ret)
242
                        printk(KERN_ERR "mtd partition registration "
243
                                "failed: %d\n", ret);
244
        }
245
 
246
        /*
247
         * If we got an error, free all resources.
248
         */
249
        if (ret < 0) {
250
                del_mtd_partitions(mtd);
251
                map_destroy(mtd);
252
        }
253
 
254
        return ret;
255
}
256
 
257
static void armflash_cfi_exit(void)
258
{
259
        if (mtd) {
260
                del_mtd_partitions(mtd);
261
                map_destroy(mtd);
262
        }
263
        if (parts)
264
                kfree(parts);
265
}
266
 
267
static int __init armflash_init(void)
268
{
269
        int err = -EBUSY;
270
        void *base;
271
 
272
        if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
273
                goto out;
274
 
275
        base = ioremap(FLASH_BASE, FLASH_SIZE);
276
        err = -ENOMEM;
277
        if (base == NULL)
278
                goto release;
279
 
280
        err = armflash_cfi_init(base, FLASH_SIZE);
281
        if (err) {
282
                iounmap(base);
283
release:
284
                release_mem_region(FLASH_BASE, FLASH_SIZE);
285
        }
286
out:
287
        return err;
288
}
289
 
290
static void __exit armflash_exit(void)
291
{
292
        armflash_cfi_exit();
293
        iounmap((void *)armflash_map.map_priv_2);
294
        release_mem_region(FLASH_BASE, FLASH_SIZE);
295
        armflash_flash_exit();
296
}
297
 
298
module_init(armflash_init);
299
module_exit(armflash_exit);
300
 
301
MODULE_AUTHOR("ARM Ltd");
302
MODULE_DESCRIPTION("ARM Integrator CFI map driver");
303
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.