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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
2
                SBC-GXm and SBC-GX1 series boards.
3
 
4
   Copyright (C) 2001 Arcom Control System Ltd
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19
 
20
   $Id: sbc_gxx.c,v 1.1.1.1 2004-04-15 01:51:56 phoenix Exp $
21
 
22
The SBC-MediaGX / SBC-GXx has up to 16 MiB of
23
Intel StrataFlash (28F320/28F640) in x8 mode.
24
 
25
This driver uses the CFI probe and Intel Extended Command Set drivers.
26
 
27
The flash is accessed as follows:
28
 
29
   16 KiB memory window at 0xdc000-0xdffff
30
 
31
   Two IO address locations for paging
32
 
33
   0x258
34
       bit 0-7: address bit 14-21
35
   0x259
36
       bit 0-1: address bit 22-23
37
       bit 7:   0 - reset/powered down
38
                1 - device enabled
39
 
40
The single flash device is divided into 3 partition which appear as
41
separate MTD devices.
42
 
43
25/04/2001 AJL (Arcom)  Modified signon strings and partition sizes
44
                        (to support bzImages up to 638KiB-ish)
45
*/
46
 
47
// Includes
48
 
49
#include <linux/module.h>
50
#include <linux/slab.h>
51
#include <linux/ioport.h>
52
#include <linux/init.h>
53
#include <asm/io.h>
54
 
55
#include <linux/mtd/mtd.h>
56
#include <linux/mtd/map.h>
57
#include <linux/mtd/partitions.h>
58
 
59
// Defines
60
 
61
// - Hardware specific
62
 
63
#define WINDOW_START 0xdc000
64
 
65
/* Number of bits in offset. */
66
#define WINDOW_SHIFT 14
67
#define WINDOW_LENGTH (1 << WINDOW_SHIFT)
68
 
69
/* The bits for the offset into the window. */
70
#define WINDOW_MASK (WINDOW_LENGTH-1)
71
#define PAGE_IO 0x258
72
#define PAGE_IO_SIZE 2
73
 
74
/* bit 7 of 0x259 must be 1 to enable device. */
75
#define DEVICE_ENABLE 0x8000
76
 
77
// - Flash / Partition sizing
78
 
79
#define MAX_SIZE_KiB             16384
80
#define BOOT_PARTITION_SIZE_KiB  768
81
#define DATA_PARTITION_SIZE_KiB  1280
82
#define APP_PARTITION_SIZE_KiB   6144
83
 
84
// Globals
85
 
86
static volatile int page_in_window = -1; // Current page in window.
87
static unsigned long iomapadr;
88
static spinlock_t sbc_gxx_spin = SPIN_LOCK_UNLOCKED;
89
 
90
/* partition_info gives details on the logical partitions that the split the
91
 * single flash device into. If the size if zero we use up to the end of the
92
 * device. */
93
static struct mtd_partition partition_info[]={
94
    { name: "SBC-GXx flash boot partition",
95
      offset: 0,
96
      size:   BOOT_PARTITION_SIZE_KiB*1024 },
97
    { name: "SBC-GXx flash data partition",
98
      offset: BOOT_PARTITION_SIZE_KiB*1024,
99
      size: (DATA_PARTITION_SIZE_KiB)*1024 },
100
    { name: "SBC-GXx flash application partition",
101
      offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
102
};
103
 
104
#define NUM_PARTITIONS 3
105
 
106
static inline void sbc_gxx_page(struct map_info *map, unsigned long ofs)
107
{
108
        unsigned long page = ofs >> WINDOW_SHIFT;
109
 
110
        if( page!=page_in_window ) {
111
                outw( page | DEVICE_ENABLE, PAGE_IO );
112
                page_in_window = page;
113
        }
114
}
115
 
116
 
117
static __u8 sbc_gxx_read8(struct map_info *map, unsigned long ofs)
118
{
119
        __u8 ret;
120
        spin_lock(&sbc_gxx_spin);
121
        sbc_gxx_page(map, ofs);
122
        ret = readb(iomapadr + (ofs & WINDOW_MASK));
123
        spin_unlock(&sbc_gxx_spin);
124
        return ret;
125
}
126
 
127
static __u16 sbc_gxx_read16(struct map_info *map, unsigned long ofs)
128
{
129
        __u16 ret;
130
        spin_lock(&sbc_gxx_spin);
131
        sbc_gxx_page(map, ofs);
132
        ret = readw(iomapadr + (ofs & WINDOW_MASK));
133
        spin_unlock(&sbc_gxx_spin);
134
        return ret;
135
}
136
 
137
static __u32 sbc_gxx_read32(struct map_info *map, unsigned long ofs)
138
{
139
        __u32 ret;
140
        spin_lock(&sbc_gxx_spin);
141
        sbc_gxx_page(map, ofs);
142
        ret = readl(iomapadr + (ofs & WINDOW_MASK));
143
        spin_unlock(&sbc_gxx_spin);
144
        return ret;
145
}
146
 
147
static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
148
{
149
        while(len) {
150
                unsigned long thislen = len;
151
                if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
152
                        thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
153
 
154
                spin_lock(&sbc_gxx_spin);
155
                sbc_gxx_page(map, from);
156
                memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
157
                spin_unlock(&sbc_gxx_spin);
158
                (__u8*)to += thislen;
159
                from += thislen;
160
                len -= thislen;
161
        }
162
}
163
 
164
static void sbc_gxx_write8(struct map_info *map, __u8 d, unsigned long adr)
165
{
166
        spin_lock(&sbc_gxx_spin);
167
        sbc_gxx_page(map, adr);
168
        writeb(d, iomapadr + (adr & WINDOW_MASK));
169
        spin_unlock(&sbc_gxx_spin);
170
}
171
 
172
static void sbc_gxx_write16(struct map_info *map, __u16 d, unsigned long adr)
173
{
174
        spin_lock(&sbc_gxx_spin);
175
        sbc_gxx_page(map, adr);
176
        writew(d, iomapadr + (adr & WINDOW_MASK));
177
        spin_unlock(&sbc_gxx_spin);
178
}
179
 
180
static void sbc_gxx_write32(struct map_info *map, __u32 d, unsigned long adr)
181
{
182
        spin_lock(&sbc_gxx_spin);
183
        sbc_gxx_page(map, adr);
184
        writel(d, iomapadr + (adr & WINDOW_MASK));
185
        spin_unlock(&sbc_gxx_spin);
186
}
187
 
188
static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
189
{
190
        while(len) {
191
                unsigned long thislen = len;
192
                if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
193
                        thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
194
 
195
                spin_lock(&sbc_gxx_spin);
196
                sbc_gxx_page(map, to);
197
                memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
198
                spin_unlock(&sbc_gxx_spin);
199
                to += thislen;
200
                from += thislen;
201
                len -= thislen;
202
        }
203
}
204
 
205
static struct map_info sbc_gxx_map = {
206
        name: "SBC-GXx flash",
207
        size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
208
                         of flash so the cfi probe routines find all
209
                         the chips */
210
        buswidth: 1,
211
        read8: sbc_gxx_read8,
212
        read16: sbc_gxx_read16,
213
        read32: sbc_gxx_read32,
214
        copy_from: sbc_gxx_copy_from,
215
        write8: sbc_gxx_write8,
216
        write16: sbc_gxx_write16,
217
        write32: sbc_gxx_write32,
218
        copy_to: sbc_gxx_copy_to
219
};
220
 
221
/* MTD device for all of the flash. */
222
static struct mtd_info *all_mtd;
223
 
224
static void cleanup_sbc_gxx(void)
225
{
226
        if( all_mtd ) {
227
                del_mtd_partitions( all_mtd );
228
                map_destroy( all_mtd );
229
        }
230
 
231
        iounmap((void *)iomapadr);
232
        release_region(PAGE_IO,PAGE_IO_SIZE);
233
}
234
 
235
int __init init_sbc_gxx(void)
236
{
237
        if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
238
                printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
239
                        sbc_gxx_map.name,
240
                        PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
241
                return -EAGAIN;
242
        }
243
        iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
244
        if (!iomapadr) {
245
                printk( KERN_ERR"%s: failed to ioremap memory region\n",
246
                        sbc_gxx_map.name );
247
                return -EIO;
248
        }
249
 
250
        request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" );
251
 
252
        printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
253
                sbc_gxx_map.name,
254
                PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
255
                WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 );
256
 
257
        /* Probe for chip. */
258
        all_mtd = do_map_probe( "cfi_probe", &sbc_gxx_map );
259
        if( !all_mtd ) {
260
                cleanup_sbc_gxx();
261
                return -ENXIO;
262
        }
263
 
264
        all_mtd->module=THIS_MODULE;
265
 
266
        /* Create MTD devices for each partition. */
267
        add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
268
 
269
        return 0;
270
}
271
 
272
module_init(init_sbc_gxx);
273
module_exit(cleanup_sbc_gxx);
274
 
275
MODULE_LICENSE("GPL");
276
MODULE_AUTHOR("Arcom Control Systems Ltd.");
277
MODULE_DESCRIPTION("MTD map driver for SBC-GXm and SBC-GX1 series boards");

powered by: WebSVN 2.1.0

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