source: trunk/target/linux/brcm63xx/patches-2.6.32/040-bcm963xx_flashmap.patch @ 21085

Last change on this file since 21085 was 21085, checked in by florian, 7 years ago

[brcm63xx] alwasy read imagetag with 64K erase block size

File size: 11.5 KB
  • drivers/mtd/maps/Kconfig

    From e734ace5baa04e0e8af1d4483475fbd6bd2b32a1 Mon Sep 17 00:00:00 2001
    From: Axel Gembe <ago@bastart.eu.org>
    Date: Mon, 12 May 2008 18:54:09 +0200
    Subject: [PATCH] bcm963xx: flashmap support
    
    
    Signed-off-by: Axel Gembe <ago@bastart.eu.org>
    ---
     drivers/mtd/maps/Kconfig  |    7 +++++++
     drivers/mtd/maps/Makefile |    1 +
     drivers/mtd/redboot.c     |   13 ++++++++++---
     3 files changed, 18 insertions(+), 3 deletions(-)
    
    old new  
    259259        help 
    260260          Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards 
    261261 
     262config MTD_BCM963XX 
     263        tristate "BCM963xx Flash device" 
     264        depends on MIPS && BCM63XX 
     265        help 
     266          Flash memory access on BCM963xx boards. Currently only works with 
     267          RedBoot and CFE. 
     268 
    262269config MTD_DILNETPC 
    263270        tristate "CFI Flash device mapped on DIL/Net PC" 
    264271        depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN 
  • drivers/mtd/redboot.c

    old new  
    3939        return 1; 
    4040} 
    4141 
    42 static int parse_redboot_partitions(struct mtd_info *master, 
     42int parse_redboot_partitions(struct mtd_info *master, 
    4343                             struct mtd_partition **pparts, 
    4444                             unsigned long fis_origin) 
    4545{ 
     
    162162                goto out; 
    163163        } 
    164164 
     165        if (!fis_origin) { 
     166                for (i = 0; i < numslots; i++) { 
     167                        if (!strncmp(buf[i].name, "RedBoot", 8)) { 
     168                                fis_origin = (buf[i].flash_base & (master->size << 1) - 1); 
     169                        } 
     170                } 
     171        } 
     172 
    165173        for (i = 0; i < numslots; i++) { 
    166174                struct fis_list *new_fl, **prev; 
    167175 
     
    184192                new_fl->img = &buf[i]; 
    185193                if (fis_origin) { 
    186194                        buf[i].flash_base -= fis_origin; 
    187                 } else { 
    188                         buf[i].flash_base &= master->size-1; 
    189195                } 
     196                buf[i].flash_base &= (master->size << 1) - 1; 
    190197 
    191198                /* I'm sure the JFFS2 code has done me permanent damage. 
    192199                 * I now think the following is _normal_ 
  • drivers/mtd/maps/Makefile

    old new  
    6161obj-$(CONFIG_MTD_RBTX4939)      += rbtx4939-flash.o 
    6262obj-$(CONFIG_MTD_VMU)           += vmu-flash.o 
    6363obj-$(CONFIG_MTD_GPIO_ADDR)     += gpio-addr-flash.o 
     64obj-$(CONFIG_MTD_BCM963XX)      += bcm963xx-flash.o 
  • new file linux-2.6.32.10/drivers/mtd/maps/bcm963xx-flash.c

    - +  
     1/* 
     2 * Copyright (C) 2006-2008  Florian Fainelli <florian@openwrt.org> 
     3 *                          Mike Albon <malbon@openwrt.org> 
     4 * 
     5 * This program is free software; you can redistribute it and/or modify 
     6 * it under the terms of the GNU General Public License as published by 
     7 * the Free Software Foundation; either version 2 of the License, or 
     8 * (at your option) any later version. 
     9 * 
     10 * This program is distributed in the hope that it will be useful, 
     11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13 * GNU General Public License for more details. 
     14 * 
     15 * You should have received a copy of the GNU General Public License 
     16 * along with this program; if not, write to the Free Software 
     17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
     18 */ 
     19 
     20#include <linux/init.h> 
     21#include <linux/kernel.h> 
     22#include <linux/mtd/map.h> 
     23#include <linux/mtd/mtd.h> 
     24#include <linux/mtd/partitions.h> 
     25#include <linux/vmalloc.h> 
     26#include <linux/platform_device.h> 
     27 
     28#include <bcm_tag.h> 
     29#include <asm/io.h> 
     30 
     31#define BUSWIDTH 2                     /* Buswidth */ 
     32#define EXTENDED_SIZE 0xBFC00000       /* Extended flash address */ 
     33 
     34#define PFX KBUILD_MODNAME ": " 
     35 
     36extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin); 
     37static struct mtd_partition *parsed_parts; 
     38 
     39static struct mtd_info *bcm963xx_mtd_info; 
     40 
     41static struct map_info bcm963xx_map = { 
     42       .name            = "bcm963xx", 
     43       .bankwidth       = BUSWIDTH, 
     44}; 
     45 
     46 
     47static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition **pparts) 
     48{ 
     49        int nrparts = 3, curpart = 0; /* CFE,NVRAM and global LINUX are always present. */ 
     50        struct bcm_tag *buf; 
     51        struct mtd_partition *parts; 
     52        int ret; 
     53        size_t retlen; 
     54        unsigned int rootfsaddr, kerneladdr, spareaddr; 
     55        unsigned int rootfslen, kernellen, sparelen, totallen; 
     56        int namelen = 0; 
     57        int i; 
     58        char *boardid; 
     59        char *tagversion; 
     60 
     61        /* Allocate memory for buffer */ 
     62        buf = vmalloc(sizeof(struct bcm_tag)); 
     63        if (!buf) 
     64                return -ENOMEM; 
     65 
     66        /* Get the tag */ 
     67        ret = master->read(master,0x10000,sizeof(struct bcm_tag), &retlen, (void *)buf); 
     68        if (retlen != sizeof(struct bcm_tag)){ 
     69                vfree(buf); 
     70                return -EIO; 
     71        } 
     72 
     73        sscanf(buf->kernelAddress, "%u", &kerneladdr); 
     74        sscanf(buf->kernelLength, "%u", &kernellen); 
     75        sscanf(buf->totalLength, "%u", &totallen); 
     76        tagversion = &(buf->tagVersion[0]); 
     77        boardid = &(buf->boardid[0]); 
     78 
     79        printk(KERN_INFO PFX "CFE boot tag found with version %s and board type %s\n",tagversion, boardid); 
     80 
     81        kerneladdr = kerneladdr - EXTENDED_SIZE; 
     82        rootfsaddr = kerneladdr + kernellen; 
     83        spareaddr = roundup(totallen, master->erasesize) + master->erasesize; 
     84        sparelen = master->size - spareaddr - master->erasesize; 
     85        rootfslen = spareaddr - rootfsaddr; 
     86 
     87        /* Determine number of partitions */ 
     88        namelen = 8; 
     89        if (rootfslen > 0){ 
     90                nrparts++; 
     91                namelen =+ 6; 
     92        }; 
     93        if (kernellen > 0) { 
     94                nrparts++; 
     95                namelen =+ 6; 
     96        }; 
     97 
     98        /* Ask kernel for more memory */ 
     99        parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); 
     100        if (!parts) { 
     101                vfree(buf); 
     102                return -ENOMEM; 
     103        }; 
     104 
     105        /* Start building partition list */ 
     106        parts[curpart].name = "CFE"; 
     107        parts[curpart].offset = 0; 
     108        parts[curpart].size = master->erasesize; 
     109        curpart++; 
     110 
     111        if (kernellen > 0) { 
     112                parts[curpart].name = "kernel"; 
     113                parts[curpart].offset = kerneladdr; 
     114                parts[curpart].size = kernellen; 
     115                curpart++; 
     116        }; 
     117 
     118        if (rootfslen > 0) { 
     119                parts[curpart].name = "rootfs"; 
     120                parts[curpart].offset = rootfsaddr; 
     121                parts[curpart].size = rootfslen; 
     122                if (sparelen > 0) 
     123                        parts[curpart].size += sparelen; 
     124                curpart++; 
     125        }; 
     126 
     127        parts[curpart].name = "nvram"; 
     128        parts[curpart].offset = master->size - master->erasesize; 
     129        parts[curpart].size = master->erasesize; 
     130 
     131        /* Global partition "linux" to make easy firmware upgrade */ 
     132        curpart++; 
     133        parts[curpart].name = "linux"; 
     134        parts[curpart].offset = parts[0].size; 
     135        parts[curpart].size = master->size - parts[0].size - parts[3].size; 
     136 
     137        for (i = 0; i < nrparts; i++) 
     138                printk(KERN_INFO PFX "Partition %d is %s offset %lx and length %lx\n", i, parts[i].name, (long unsigned int)(parts[i].offset), (long unsigned int)(parts[i].size)); 
     139 
     140        printk(KERN_INFO PFX "Spare partition is %x offset and length %x\n", spareaddr, sparelen); 
     141        *pparts = parts; 
     142        vfree(buf); 
     143 
     144        return nrparts; 
     145}; 
     146 
     147static int bcm963xx_detect_cfe(struct mtd_info *master) 
     148{ 
     149        int idoffset = 0x4e0; 
     150        static char idstring[8] = "CFE1CFE1"; 
     151        char buf[9]; 
     152        int ret; 
     153        size_t retlen; 
     154 
     155        ret = master->read(master, idoffset, 8, &retlen, (void *)buf); 
     156        buf[retlen] = 0; 
     157        printk(KERN_INFO PFX "Read Signature value of %s\n", buf); 
     158 
     159        return strncmp(idstring, buf, 8); 
     160} 
     161 
     162static int bcm963xx_probe(struct platform_device *pdev) 
     163{ 
     164        int err = 0; 
     165        int parsed_nr_parts = 0; 
     166        char *part_type; 
     167        struct resource *r; 
     168 
     169        r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 
     170        bcm963xx_map.phys = r->start; 
     171        bcm963xx_map.size = (r->end - r->start) + 1; 
     172        bcm963xx_map.virt = ioremap(r->start, r->end - r->start + 1); 
     173 
     174        if (!bcm963xx_map.virt) { 
     175                printk(KERN_ERR PFX "Failed to ioremap\n"); 
     176                return -EIO; 
     177        } 
     178        printk(KERN_INFO PFX "0x%08lx at 0x%08x\n", bcm963xx_map.size, bcm963xx_map.phys); 
     179 
     180        simple_map_init(&bcm963xx_map); 
     181 
     182        bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map); 
     183        if (!bcm963xx_mtd_info) { 
     184                printk(KERN_ERR PFX "Failed to probe using CFI\n"); 
     185                err = -EIO; 
     186                goto err_probe; 
     187        } 
     188 
     189        bcm963xx_mtd_info->owner = THIS_MODULE; 
     190 
     191        /* This is mutually exclusive */ 
     192        if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) { 
     193                printk(KERN_INFO PFX "CFE bootloader detected\n"); 
     194                if (parsed_nr_parts == 0) { 
     195                        int ret = parse_cfe_partitions(bcm963xx_mtd_info, &parsed_parts); 
     196                        if (ret > 0) { 
     197                                part_type = "CFE"; 
     198                                parsed_nr_parts = ret; 
     199                        } 
     200                } 
     201        } else { 
     202                printk(KERN_INFO PFX "assuming RedBoot bootloader\n"); 
     203                if (bcm963xx_mtd_info->size > 0x00400000) { 
     204                        printk(KERN_INFO PFX "Support for extended flash memory size : 0x%lx ; ONLY 64MBIT SUPPORT\n", bcm963xx_mtd_info->size); 
     205                        bcm963xx_map.virt = (u32)(EXTENDED_SIZE); 
     206                } 
     207 
     208#ifdef CONFIG_MTD_REDBOOT_PARTS 
     209                if (parsed_nr_parts == 0) { 
     210                        int ret = parse_redboot_partitions(bcm963xx_mtd_info, &parsed_parts, 0); 
     211                        if (ret > 0) { 
     212                                part_type = "RedBoot"; 
     213                                parsed_nr_parts = ret; 
     214                        } 
     215                } 
     216#endif 
     217        } 
     218 
     219        return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts); 
     220 
     221err_probe: 
     222        iounmap(bcm963xx_map.virt); 
     223        return err; 
     224} 
     225 
     226static int bcm963xx_remove(struct platform_device *pdev) 
     227{ 
     228        if (bcm963xx_mtd_info) { 
     229                del_mtd_partitions(bcm963xx_mtd_info); 
     230                map_destroy(bcm963xx_mtd_info); 
     231        } 
     232 
     233        if (bcm963xx_map.virt) { 
     234                iounmap(bcm963xx_map.virt); 
     235                bcm963xx_map.virt = 0; 
     236        } 
     237 
     238        return 0; 
     239} 
     240 
     241static struct platform_driver bcm63xx_mtd_dev = { 
     242        .probe  = bcm963xx_probe, 
     243        .remove = bcm963xx_remove, 
     244        .driver = { 
     245                .name   = "bcm963xx-flash", 
     246                .owner  = THIS_MODULE, 
     247        }, 
     248}; 
     249 
     250static int __init bcm963xx_mtd_init(void) 
     251{ 
     252        return platform_driver_register(&bcm63xx_mtd_dev); 
     253} 
     254 
     255static void __exit bcm963xx_mtd_exit(void) 
     256{ 
     257        platform_driver_unregister(&bcm63xx_mtd_dev); 
     258} 
     259 
     260module_init(bcm963xx_mtd_init); 
     261module_exit(bcm963xx_mtd_exit); 
     262 
     263MODULE_LICENSE("GPL"); 
     264MODULE_DESCRIPTION("Broadcom BCM63xx MTD partition parser/mapping for CFE and RedBoot"); 
     265MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); 
     266MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>"); 
  • arch/mips/bcm63xx/boards/board_bcm963xx.c

    old new  
    722722        return 0; 
    723723} 
    724724 
    725 static struct mtd_partition mtd_partitions[] = { 
    726         { 
    727                 .name           = "cfe", 
    728                 .offset         = 0x0, 
    729                 .size           = 0x40000, 
    730         } 
    731 }; 
    732  
    733 static struct physmap_flash_data flash_data = { 
    734         .width                  = 2, 
    735         .nr_parts               = ARRAY_SIZE(mtd_partitions), 
    736         .parts                  = mtd_partitions, 
    737 }; 
    738  
    739725static struct resource mtd_resources[] = { 
    740726        { 
    741727                .start          = 0,    /* filled at runtime */ 
     
    745731}; 
    746732 
    747733static struct platform_device mtd_dev = { 
    748         .name                   = "physmap-flash", 
     734        .name                   = "bcm963xx-flash", 
    749735        .resource               = mtd_resources, 
    750736        .num_resources          = ARRAY_SIZE(mtd_resources), 
    751         .dev                    = { 
    752                 .platform_data  = &flash_data, 
    753         }, 
    754737}; 
    755738 
    756739/* 
Note: See TracBrowser for help on using the repository browser.