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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [maps/] [dc21285.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip)
3
 *
4
 * (C) 2000  Nicolas Pitre <nico@cam.org>
5
 *
6
 * This code is GPL
7
 *
8
 * $Id: dc21285.c,v 1.1.1.1 2004-04-15 01:51:44 phoenix Exp $
9
 */
10
#include <linux/config.h>
11
#include <linux/module.h>
12
#include <linux/types.h>
13
#include <linux/kernel.h>
14
 
15
#include <linux/mtd/mtd.h>
16
#include <linux/mtd/map.h>
17
#include <linux/mtd/partitions.h>
18
 
19
#include <asm/io.h>
20
#include <asm/hardware/dec21285.h>
21
 
22
 
23
static struct mtd_info *mymtd;
24
 
25
__u8 dc21285_read8(struct map_info *map, unsigned long ofs)
26
{
27
        return *(__u8*)(map->map_priv_1 + ofs);
28
}
29
 
30
__u16 dc21285_read16(struct map_info *map, unsigned long ofs)
31
{
32
        return *(__u16*)(map->map_priv_1 + ofs);
33
}
34
 
35
__u32 dc21285_read32(struct map_info *map, unsigned long ofs)
36
{
37
        return *(__u32*)(map->map_priv_1 + ofs);
38
}
39
 
40
void dc21285_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
41
{
42
        memcpy(to, (void*)(map->map_priv_1 + from), len);
43
}
44
 
45
void dc21285_write8(struct map_info *map, __u8 d, unsigned long adr)
46
{
47
        *CSR_ROMWRITEREG = adr & 3;
48
        adr &= ~3;
49
        *(__u8*)(map->map_priv_1 + adr) = d;
50
}
51
 
52
void dc21285_write16(struct map_info *map, __u16 d, unsigned long adr)
53
{
54
        *CSR_ROMWRITEREG = adr & 3;
55
        adr &= ~3;
56
        *(__u16*)(map->map_priv_1 + adr) = d;
57
}
58
 
59
void dc21285_write32(struct map_info *map, __u32 d, unsigned long adr)
60
{
61
        *(__u32*)(map->map_priv_1 + adr) = d;
62
}
63
 
64
void dc21285_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
65
{
66
        switch (map->buswidth) {
67
                case 4:
68
                        while (len > 0) {
69
                                __u32 d = *((__u32*)from)++;
70
                                dc21285_write32(map, d, to);
71
                                to += 4;
72
                                len -= 4;
73
                        }
74
                        break;
75
                case 2:
76
                        while (len > 0) {
77
                                __u16 d = *((__u16*)from)++;
78
                                dc21285_write16(map, d, to);
79
                                to += 2;
80
                                len -= 2;
81
                        }
82
                        break;
83
                case 1:
84
                        while (len > 0) {
85
                                __u8 d = *((__u8*)from)++;
86
                                dc21285_write8(map, d, to);
87
                                to++;
88
                                len--;
89
                        }
90
                        break;
91
        }
92
}
93
 
94
struct map_info dc21285_map = {
95
        name: "DC21285 flash",
96
        size: 16*1024*1024,
97
        read8: dc21285_read8,
98
        read16: dc21285_read16,
99
        read32: dc21285_read32,
100
        copy_from: dc21285_copy_from,
101
        write8: dc21285_write8,
102
        write16: dc21285_write16,
103
        write32: dc21285_write32,
104
        copy_to: dc21285_copy_to
105
};
106
 
107
 
108
/* Partition stuff */
109
static struct mtd_partition *dc21285_parts;
110
 
111
extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
112
 
113
int __init init_dc21285(void)
114
{
115
        /* Determine buswidth */
116
        switch (*CSR_SA110_CNTL & (3<<14)) {
117
                case SA110_CNTL_ROMWIDTH_8:
118
                        dc21285_map.buswidth = 1;
119
                        break;
120
                case SA110_CNTL_ROMWIDTH_16:
121
                        dc21285_map.buswidth = 2;
122
                        break;
123
                case SA110_CNTL_ROMWIDTH_32:
124
                        dc21285_map.buswidth = 4;
125
                        break;
126
                default:
127
                        printk (KERN_ERR "DC21285 flash: undefined buswidth\n");
128
                        return -ENXIO;
129
        }
130
        printk (KERN_NOTICE "DC21285 flash support (%d-bit buswidth)\n",
131
                dc21285_map.buswidth*8);
132
 
133
        /* Let's map the flash area */
134
        dc21285_map.map_priv_1 = (unsigned long)ioremap(DC21285_FLASH, 16*1024*1024);
135
        if (!dc21285_map.map_priv_1) {
136
                printk("Failed to ioremap\n");
137
                return -EIO;
138
        }
139
 
140
        mymtd = do_map_probe("cfi_probe", &dc21285_map);
141
        if (mymtd) {
142
                int nrparts = 0;
143
 
144
                mymtd->module = THIS_MODULE;
145
 
146
                /* partition fixup */
147
 
148
#ifdef CONFIG_MTD_REDBOOT_PARTS
149
                nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
150
#endif
151
                if (nrparts > 0) {
152
                        add_mtd_partitions(mymtd, dc21285_parts, nrparts);
153
                } else if (nrparts == 0) {
154
                        printk(KERN_NOTICE "RedBoot partition table failed\n");
155
                        add_mtd_device(mymtd);
156
                }
157
 
158
                /*
159
                 * Flash timing is determined with bits 19-16 of the
160
                 * CSR_SA110_CNTL.  The value is the number of wait cycles, or
161
                 * 0 for 16 cycles (the default).  Cycles are 20 ns.
162
                 * Here we use 7 for 140 ns flash chips.
163
                 */
164
                /* access time */
165
                *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
166
                /* burst time */
167
                *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
168
                /* tristate time */
169
                *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
170
 
171
                return 0;
172
        }
173
 
174
        iounmap((void *)dc21285_map.map_priv_1);
175
        return -ENXIO;
176
}
177
 
178
static void __exit cleanup_dc21285(void)
179
{
180
        if (mymtd) {
181
                del_mtd_device(mymtd);
182
                map_destroy(mymtd);
183
                mymtd = NULL;
184
        }
185
        if (dc21285_map.map_priv_1) {
186
                iounmap((void *)dc21285_map.map_priv_1);
187
                dc21285_map.map_priv_1 = 0;
188
        }
189
        if(dc21285_parts)
190
                kfree(dc21285_parts);
191
}
192
 
193
module_init(init_dc21285);
194
module_exit(cleanup_dc21285);
195
 
196
 
197
MODULE_LICENSE("GPL");
198
MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
199
MODULE_DESCRIPTION("MTD map driver for DC21285 boards");

powered by: WebSVN 2.1.0

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