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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Handle mapping of the flash memory access routines
3
 * on TQM8xxL based devices.
4
 *
5
 * $Id: tqm8xxl.c,v 1.1.1.1 2004-04-15 01:51:50 phoenix Exp $
6
 *
7
 * based on rpxlite.c
8
 *
9
 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
10
 *
11
 * This code is GPLed
12
 *
13
 */
14
 
15
/*
16
 * According to TQM8xxL hardware manual, TQM8xxL series have
17
 * following flash memory organisations:
18
 *      | capacity |    | chip type |   | bank0 |       | bank1 |
19
 *          2MiB           512Kx16        2MiB             0
20
 *          4MiB           1Mx16          4MiB             0
21
 *          8MiB           1Mx16          4MiB             4MiB
22
 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
23
 * kernel configuration.
24
 */
25
#include <linux/config.h>
26
#include <linux/module.h>
27
#include <linux/types.h>
28
#include <linux/kernel.h>
29
#include <asm/io.h>
30
 
31
#include <linux/mtd/mtd.h>
32
#include <linux/mtd/map.h>
33
#include <linux/mtd/partitions.h>
34
 
35
#define FLASH_ADDR 0x40000000
36
#define FLASH_SIZE 0x00800000
37
#define FLASH_BANK_MAX 4
38
 
39
// trivial struct to describe partition information
40
struct mtd_part_def
41
{
42
        int nums;
43
        unsigned char *type;
44
        struct mtd_partition* mtd_part;
45
};
46
 
47
//static struct mtd_info *mymtd;
48
static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
49
static struct map_info* map_banks[FLASH_BANK_MAX];
50
static struct mtd_part_def part_banks[FLASH_BANK_MAX];
51
static unsigned long num_banks;
52
static unsigned long start_scan_addr;
53
 
54
__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs)
55
{
56
        return *((__u8 *)(map->map_priv_1 + ofs));
57
}
58
 
59
__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs)
60
{
61
        return *((__u16 *)(map->map_priv_1 + ofs));
62
}
63
 
64
__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs)
65
{
66
        return *((__u32 *)(map->map_priv_1 + ofs));
67
}
68
 
69
void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
70
{
71
        memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
72
}
73
 
74
void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr)
75
{
76
        *((__u8 *)(map->map_priv_1 + adr)) = d;
77
}
78
 
79
void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr)
80
{
81
        *((__u16 *)( map->map_priv_1 + adr)) = d;
82
}
83
 
84
void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr)
85
{
86
        *((__u32 *)(map->map_priv_1 + adr)) = d;
87
}
88
 
89
void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
90
{
91
        memcpy_toio((void *)(map->map_priv_1 + to), from, len);
92
}
93
 
94
/*
95
 * Here are partition information for all known TQM8xxL series devices.
96
 * See include/linux/mtd/partitions.h for definition of the mtd_partition
97
 * structure.
98
 *
99
 * The *_max_flash_size is the maximum possible mapped flash size which
100
 * is not necessarily the actual flash size.  It must correspond to the
101
 * value specified in the mapping definition defined by the
102
 * "struct map_desc *_io_desc" for the corresponding machine.
103
 */
104
 
105
#ifdef CONFIG_MTD_PARTITIONS
106
/* Currently, TQM8xxL has upto 8MiB flash */
107
static unsigned long tqm8xxl_max_flash_size = 0x00800000;
108
 
109
/* partition definition for first flash bank
110
 * also ref. to "drivers\char\flash_config.c"
111
 */
112
static struct mtd_partition tqm8xxl_partitions[] = {
113
        {
114
          name: "ppcboot",
115
          offset: 0x00000000,
116
          size: 0x00020000,           /* 128KB           */
117
          mask_flags: MTD_WRITEABLE,  /* force read-only */
118
        },
119
        {
120
          name: "kernel",             /* default kernel image */
121
          offset: 0x00020000,
122
          size: 0x000e0000,
123
          mask_flags: MTD_WRITEABLE,  /* force read-only */
124
        },
125
        {
126
          name: "user",
127
          offset: 0x00100000,
128
          size: 0x00100000,
129
        },
130
        {
131
          name: "initrd",
132
          offset: 0x00200000,
133
          size: 0x00200000,
134
        }
135
};
136
/* partition definition for second flahs bank */
137
static struct mtd_partition tqm8xxl_fs_partitions[] = {
138
        {
139
          name: "cramfs",
140
          offset: 0x00000000,
141
          size: 0x00200000,
142
        },
143
        {
144
          name: "jffs",
145
          offset: 0x00200000,
146
          size: 0x00200000,
147
          //size: MTDPART_SIZ_FULL,
148
        }
149
};
150
#endif
151
 
152
#define NB_OF(x)  (sizeof(x)/sizeof(x[0]))
153
 
154
int __init init_tqm_mtd(void)
155
{
156
        int idx = 0, ret = 0;
157
        unsigned long flash_addr, flash_size, mtd_size = 0;
158
        /* pointer to TQM8xxL board info data */
159
        bd_t *bd = (bd_t *)__res;
160
 
161
        flash_addr = bd->bi_flashstart;
162
        flash_size = bd->bi_flashsize;
163
        //request maximum flash size address spzce
164
        start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
165
        if (!start_scan_addr) {
166
                //printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR);
167
                printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
168
                return -EIO;
169
        }
170
        for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
171
        {
172
                if(mtd_size >= flash_size)
173
                        break;
174
 
175
                printk("%s: chip probing count %d\n", __FUNCTION__, idx);
176
 
177
                map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
178
                if(map_banks[idx] == NULL)
179
                {
180
                        //return -ENOMEM;
181
                        ret = -ENOMEM;
182
                        goto error_mem;
183
                }
184
                memset((void *)map_banks[idx], 0, sizeof(struct map_info));
185
                map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
186
                if(map_banks[idx]->name == NULL)
187
                {
188
                        //return -ENOMEM;
189
                        ret = -ENOMEM;
190
                        goto error_mem;
191
                }
192
                memset((void *)map_banks[idx]->name, 0, 16);
193
 
194
                sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
195
                map_banks[idx]->size = flash_size;
196
                map_banks[idx]->buswidth = 4;
197
                map_banks[idx]->read8 = tqm8xxl_read8;
198
                map_banks[idx]->read16 = tqm8xxl_read16;
199
                map_banks[idx]->read32 = tqm8xxl_read32;
200
                map_banks[idx]->copy_from = tqm8xxl_copy_from;
201
                map_banks[idx]->write8 = tqm8xxl_write8;
202
                map_banks[idx]->write16 = tqm8xxl_write16;
203
                map_banks[idx]->write32 = tqm8xxl_write32;
204
                map_banks[idx]->copy_to = tqm8xxl_copy_to;
205
                map_banks[idx]->map_priv_1 =
206
                start_scan_addr + ((idx > 0) ?
207
                (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
208
                //start to probe flash chips
209
                mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
210
                if(mtd_banks[idx])
211
                {
212
                        mtd_banks[idx]->module = THIS_MODULE;
213
                        mtd_size += mtd_banks[idx]->size;
214
                        num_banks++;
215
                        printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
216
                        mtd_banks[idx]->name, mtd_banks[idx]->size);
217
                }
218
        }
219
 
220
        /* no supported flash chips found */
221
        if(!num_banks)
222
        {
223
                printk("TQM8xxL: No support flash chips found!\n");
224
                ret = -ENXIO;
225
                goto error_mem;
226
        }
227
 
228
#ifdef CONFIG_MTD_PARTITIONS
229
        /*
230
         * Select Static partition definitions
231
         */
232
        part_banks[0].mtd_part = tqm8xxl_partitions;
233
        part_banks[0].type = "Static image";
234
        part_banks[0].nums = NB_OF(tqm8xxl_partitions);
235
        part_banks[1].mtd_part = tqm8xxl_fs_partitions;
236
        part_banks[1].type = "Static file system";
237
        part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
238
        for(idx = 0; idx < num_banks ; idx++)
239
        {
240
                if (part_banks[idx].nums == 0) {
241
                        printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
242
                        add_mtd_device(mtd_banks[idx]);
243
                } else {
244
                        printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
245
                                        idx, part_banks[idx].type);
246
                        add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
247
                                                                part_banks[idx].nums);
248
                }
249
        }
250
#else
251
        printk(KERN_NOTICE "TQM flash: registering %d whole flash banks at once\n", num_banks);
252
        for(idx = 0 ; idx < num_banks ; idx++)
253
                add_mtd_device(mtd_banks[idx]);
254
#endif
255
        return 0;
256
error_mem:
257
        for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
258
        {
259
                if(map_banks[idx] != NULL)
260
                {
261
                        if(map_banks[idx]->name != NULL)
262
                        {
263
                                kfree(map_banks[idx]->name);
264
                                map_banks[idx]->name = NULL;
265
                        }
266
                        kfree(map_banks[idx]);
267
                        map_banks[idx] = NULL;
268
                }
269
        }
270
        //return -ENOMEM;
271
error:
272
        iounmap((void *)start_scan_addr);
273
        //return -ENXIO;
274
        return ret;
275
}
276
 
277
static void __exit cleanup_tqm_mtd(void)
278
{
279
        unsigned int idx = 0;
280
        for(idx = 0 ; idx < num_banks ; idx++)
281
        {
282
                /* destroy mtd_info previously allocated */
283
                if (mtd_banks[idx]) {
284
                        del_mtd_partitions(mtd_banks[idx]);
285
                        map_destroy(mtd_banks[idx]);
286
                }
287
                /* release map_info not used anymore */
288
                kfree(map_banks[idx]->name);
289
                kfree(map_banks[idx]);
290
        }
291
        if (start_scan_addr) {
292
                iounmap((void *)start_scan_addr);
293
                start_scan_addr = 0;
294
        }
295
}
296
 
297
module_init(init_tqm_mtd);
298
module_exit(cleanup_tqm_mtd);
299
 
300
MODULE_LICENSE("GPL");
301
MODULE_AUTHOR("Kirk Lee <kirk@hpc.ee.ntu.edu.tw>");
302
MODULE_DESCRIPTION("MTD map driver for TQM8xxL boards");

powered by: WebSVN 2.1.0

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