source: freewrt/target/linux/brcm-2.4/patches/003-flash-map.patch@ 476d5a8

freewrt_1_0 freewrt_2_0
Last change on this file since 476d5a8 was 476d5a8, checked in by Waldemar Brodkorb <wbx@…>, 19 years ago

rename configfs to fwcf, because the name configfs is already in use, suggested by tg@

git-svn-id: svn://www.freewrt.org/trunk/freewrt@598 afb5a338-a214-0410-bd46-81f09a774fd1

  • Property mode set to 100644
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 */
     61extern void *bcm947xx_sbh;
     62extern 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
     72static 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
     96void 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
     112void 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
     118void 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
     124void 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
     130void 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
     135struct 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
     151static 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
     161static int __init
     162find_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
     208struct mtd_partition * __init
     209init_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
     253mod_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
     335mod_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
     345module_init(init_bcm947xx_map);
     346module_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  
    4848fi
    4949
    5050if [ "$CONFIG_MIPS" = "y" ]; then
     51   dep_tristate '  CFI Flash device mapped on Broadcom BCM947XX boards' CONFIG_MTD_BCM947XX $CONFIG_MTD_CFI
    5152   dep_tristate '  Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
    5253   dep_tristate '  Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
    5354   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  
    33#
    44# $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $
    55
     6EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include
     7
    68BELOW25         := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
    79
    810ifeq ($(BELOW25),y)
     
    1012endif
    1113
    1214# Chip mappings
     15obj-$(CONFIG_MTD_BCM947XX)      += bcm947xx-flash.o
    1316obj-$(CONFIG_MTD_CDB89712)      += cdb89712.o
    1417obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
    1518obj-$(CONFIG_MTD_CFI_FLAGADM)   += cfi_flagadm.o
Note: See TracBrowser for help on using the repository browser.