source:
freewrt/target/linux/brcm-2.4/patches/003-flash-map.patch@
476d5a8
| Last change on this file since 476d5a8 was 476d5a8, checked in by , 19 years ago | |
|---|---|
|
|
| File size: 10.9 KB | |
-
drivers/mtd/maps/bcm947xx-flash.c
diff -Nur linux-2.4.32/drivers/mtd/maps/bcm947xx-flash.c linux-2.4.32-freewrt/drivers/mtd/maps/bcm947xx-flash.c
old new 1 /* 2 * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org) 3 * Copyright (C) 2006 Waldemar Brodkorb <wbx@freewrt.org> 4 * 5 * original functions for finding root filesystem from Mike Baker 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * 23 * You should have received a copy of the GNU General Public License along 24 * with this program; if not, write to the Free Software Foundation, Inc., 25 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 27 * 28 * Copyright 2004, Broadcom Corporation 29 * All Rights Reserved. 30 * 31 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 32 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 33 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 34 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 35 * 36 * Flash mapping for BCM947XX boards 37 * 38 */ 39 40 #include <linux/module.h> 41 #include <linux/types.h> 42 #include <linux/kernel.h> 43 #include <asm/io.h> 44 #include <linux/mtd/mtd.h> 45 #include <linux/mtd/map.h> 46 #ifdef CONFIG_MTD_PARTITIONS 47 #include <linux/mtd/partitions.h> 48 #endif 49 #include <linux/config.h> 50 51 #include <typedefs.h> 52 #include <osl.h> 53 #include <bcmnvram.h> 54 #include <bcmutils.h> 55 #include <sbconfig.h> 56 #include <sbchipc.h> 57 #include <sbutils.h> 58 #include <trxhdr.h> 59 60 /* Global SB handle */ 61 extern void *bcm947xx_sbh; 62 extern spinlock_t bcm947xx_sbh_lock; 63 64 /* Convenience */ 65 #define sbh bcm947xx_sbh 66 #define sbh_lock bcm947xx_sbh_lock 67 68 #define WINDOW_ADDR 0x1fc00000 69 #define WINDOW_SIZE 0x400000 70 #define BUSWIDTH 2 71 72 static struct mtd_info *bcm947xx_mtd; 73 74 __u8 bcm947xx_map_read8(struct map_info *map, unsigned long ofs) 75 { 76 if (map->map_priv_2 == 1) 77 return __raw_readb(map->map_priv_1 + ofs); 78 79 u16 val = __raw_readw(map->map_priv_1 + (ofs & ~1)); 80 if (ofs & 1) 81 return ((val >> 8) & 0xff); 82 else 83 return (val & 0xff); 84 } 85 86 __u16 bcm947xx_map_read16(struct map_info *map, unsigned long ofs) 87 { 88 return __raw_readw(map->map_priv_1 + ofs); 89 } 90 91 __u32 bcm947xx_map_read32(struct map_info *map, unsigned long ofs) 92 { 93 return __raw_readl(map->map_priv_1 + ofs); 94 } 95 96 void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 97 { 98 if (len==1) { 99 memcpy_fromio(to, map->map_priv_1 + from, len); 100 } else { 101 int i; 102 u16 *dest = (u16 *) to; 103 u16 *src = (u16 *) (map->map_priv_1 + from); 104 for (i = 0; i < (len / 2); i++) { 105 dest[i] = src[i]; 106 } 107 if (len & 1) 108 *((u8 *)dest+len-1) = src[i] & 0xff; 109 } 110 } 111 112 void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr) 113 { 114 __raw_writeb(d, map->map_priv_1 + adr); 115 mb(); 116 } 117 118 void bcm947xx_map_write16(struct map_info *map, __u16 d, unsigned long adr) 119 { 120 __raw_writew(d, map->map_priv_1 + adr); 121 mb(); 122 } 123 124 void bcm947xx_map_write32(struct map_info *map, __u32 d, unsigned long adr) 125 { 126 __raw_writel(d, map->map_priv_1 + adr); 127 mb(); 128 } 129 130 void bcm947xx_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 131 { 132 memcpy_toio(map->map_priv_1 + to, from, len); 133 } 134 135 struct map_info bcm947xx_map = { 136 name: "Physically mapped flash", 137 size: WINDOW_SIZE, 138 buswidth: BUSWIDTH, 139 read8: bcm947xx_map_read8, 140 read16: bcm947xx_map_read16, 141 read32: bcm947xx_map_read32, 142 copy_from: bcm947xx_map_copy_from, 143 write8: bcm947xx_map_write8, 144 write16: bcm947xx_map_write16, 145 write32: bcm947xx_map_write32, 146 copy_to: bcm947xx_map_copy_to 147 }; 148 149 #ifdef CONFIG_MTD_PARTITIONS 150 151 static struct mtd_partition bcm947xx_parts[] = { 152 { name: "cfe", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, 153 { name: "linux", offset: 0, size: 0, }, 154 { name: "rootfs", offset: 0, size: 0, }, 155 { name: "fwcf", offset: 0, size: 0, }, 156 { name: "nvram", offset: 0, size: 0, }, 157 { name: "data", offset: 0, size: 0, }, 158 { name: NULL, }, 159 }; 160 161 static int __init 162 find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) 163 { 164 struct trx_header *trx; 165 unsigned char buf[512]; 166 int off; 167 size_t len; 168 int blocksize; 169 170 trx = (struct trx_header *) buf; 171 172 blocksize = mtd->erasesize; 173 if (blocksize < 0x10000) 174 blocksize = 0x10000; 175 176 for (off = (256*1024); off < size; off += blocksize) { 177 memset(buf, 0xe5, sizeof(buf)); 178 179 /* 180 * Read into buffer 181 */ 182 if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || 183 len != sizeof(buf)) 184 continue; 185 186 /* found a TRX header */ 187 if (le32_to_cpu(trx->magic) == TRX_MAGIC) { 188 part->offset = le32_to_cpu(trx->offsets[2]) ? : 189 le32_to_cpu(trx->offsets[1]); 190 part->size = le32_to_cpu(trx->len); 191 192 part->size -= part->offset; 193 part->offset += off; 194 195 goto done; 196 } 197 } 198 199 printk(KERN_NOTICE 200 "%s: Couldn't find root filesystem\n", 201 mtd->name); 202 return -1; 203 204 done: 205 return part->size; 206 } 207 208 struct mtd_partition * __init 209 init_mtd_partitions(struct mtd_info *mtd, size_t size) 210 { 211 212 /* boot loader 256 kB */ 213 bcm947xx_parts[0].offset = 0; 214 bcm947xx_parts[0].size = 256*1024; 215 216 /* nvram */ 217 bcm947xx_parts[4].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); 218 bcm947xx_parts[4].size = ROUNDUP(NVRAM_SPACE, mtd->erasesize); 219 220 /* fwcf 128 kB before nvram */ 221 bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize) 222 - 128*1024; 223 bcm947xx_parts[3].size = 128*1024; 224 225 /* linux (kernel and rootfs) */ 226 bcm947xx_parts[1].offset = bcm947xx_parts[0].size; 227 bcm947xx_parts[1].size = bcm947xx_parts[3].offset - 228 bcm947xx_parts[1].offset; 229 230 /* find and size rootfs */ 231 if (find_root(mtd,size,&bcm947xx_parts[2])==0) { 232 /* entirely jffs2 */ 233 bcm947xx_parts[5].name = NULL; 234 bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - 235 bcm947xx_parts[4].size - bcm947xx_parts[3].size; 236 } else { 237 /* calculate leftover flash and assign it to a jffs2 partition */ 238 bcm947xx_parts[5].offset = bcm947xx_parts[2].offset + 239 bcm947xx_parts[2].size; 240 if ((bcm947xx_parts[5].offset % mtd->erasesize) > 0) { 241 bcm947xx_parts[5].offset += mtd->erasesize - 242 (bcm947xx_parts[5].offset % mtd->erasesize); 243 } 244 bcm947xx_parts[5].size = bcm947xx_parts[3].offset - 245 bcm947xx_parts[5].offset; 246 } 247 return bcm947xx_parts; 248 } 249 250 #endif 251 252 253 mod_init_t init_bcm947xx_map(void) 254 { 255 ulong flags; 256 uint coreidx; 257 chipcregs_t *cc; 258 uint32 fltype; 259 uint window_addr = 0, window_size = 0; 260 size_t size; 261 int ret = 0; 262 #ifdef CONFIG_MTD_PARTITIONS 263 struct mtd_partition *parts; 264 int i; 265 #endif 266 267 spin_lock_irqsave(&sbh_lock, flags); 268 coreidx = sb_coreidx(sbh); 269 270 /* Check strapping option if chipcommon exists */ 271 if ((cc = sb_setcore(sbh, SB_CC, 0))) { 272 fltype = readl(&cc->capabilities) & CAP_FLASH_MASK; 273 if (fltype == PFLASH) { 274 bcm947xx_map.map_priv_2 = 1; 275 window_addr = 0x1c000000; 276 bcm947xx_map.size = window_size = 32 * 1024 * 1024; 277 if ((readl(&cc->flash_config) & CC_CFG_DS) == 0) 278 bcm947xx_map.buswidth = 1; 279 } 280 } else { 281 fltype = PFLASH; 282 bcm947xx_map.map_priv_2 = 0; 283 window_addr = WINDOW_ADDR; 284 window_size = WINDOW_SIZE; 285 } 286 287 sb_setcoreidx(sbh, coreidx); 288 spin_unlock_irqrestore(&sbh_lock, flags); 289 290 if (fltype != PFLASH) { 291 ret = -ENODEV; 292 goto fail; 293 } 294 295 bcm947xx_map.map_priv_1 = (unsigned long) ioremap(window_addr, window_size); 296 297 if (!bcm947xx_map.map_priv_1) { 298 printk(KERN_ERR "Failed to ioremap\n"); 299 return -EIO; 300 } 301 302 if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) { 303 printk(KERN_ERR "pflash: cfi_probe failed\n"); 304 iounmap((void *)bcm947xx_map.map_priv_1); 305 return -ENXIO; 306 } 307 308 bcm947xx_mtd->module = THIS_MODULE; 309 310 size = bcm947xx_mtd->size; 311 312 printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, window_addr); 313 314 #ifdef CONFIG_MTD_PARTITIONS 315 parts = init_mtd_partitions(bcm947xx_mtd, size); 316 for (i = 0; parts[i].name; i++); 317 ret = add_mtd_partitions(bcm947xx_mtd, parts, i); 318 if (ret) { 319 printk(KERN_ERR "Flash: add_mtd_partitions failed\n"); 320 goto fail; 321 } 322 #endif 323 324 return 0; 325 326 fail: 327 if (bcm947xx_mtd) 328 map_destroy(bcm947xx_mtd); 329 if (bcm947xx_map.map_priv_1) 330 iounmap((void *) bcm947xx_map.map_priv_1); 331 bcm947xx_map.map_priv_1 = 0; 332 return ret; 333 } 334 335 mod_exit_t cleanup_bcm947xx_map(void) 336 { 337 #ifdef CONFIG_MTD_PARTITIONS 338 del_mtd_partitions(bcm947xx_mtd); 339 #endif 340 map_destroy(bcm947xx_mtd); 341 iounmap((void *) bcm947xx_map.map_priv_1); 342 bcm947xx_map.map_priv_1 = 0; 343 } 344 345 module_init(init_bcm947xx_map); 346 module_exit(cleanup_bcm947xx_map); -
drivers/mtd/maps/Config.in
diff -Nur linux-2.4.32/drivers/mtd/maps/Config.in linux-2.4.32-freewrt/drivers/mtd/maps/Config.in
old new 48 48 fi 49 49 50 50 if [ "$CONFIG_MIPS" = "y" ]; then 51 dep_tristate ' CFI Flash device mapped on Broadcom BCM947XX boards' CONFIG_MTD_BCM947XX $CONFIG_MTD_CFI 51 52 dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000 52 53 dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 53 54 dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 -
drivers/mtd/maps/Makefile
diff -Nur linux-2.4.32/drivers/mtd/maps/Makefile linux-2.4.32-freewrt/drivers/mtd/maps/Makefile
old new 3 3 # 4 4 # $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $ 5 5 6 EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include 7 6 8 BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/) 7 9 8 10 ifeq ($(BELOW25),y) … … 10 12 endif 11 13 12 14 # Chip mappings 15 obj-$(CONFIG_MTD_BCM947XX) += bcm947xx-flash.o 13 16 obj-$(CONFIG_MTD_CDB89712) += cdb89712.o 14 17 obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o 15 18 obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o
Note:
See TracBrowser
for help on using the repository browser.
