Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Broadcom BCM63xx flash registration
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  *
0008  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
0009  * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
0010  * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
0011  */
0012 
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/mtd/mtd.h>
0017 #include <linux/mtd/partitions.h>
0018 #include <linux/mtd/physmap.h>
0019 
0020 #include <bcm63xx_cpu.h>
0021 #include <bcm63xx_dev_flash.h>
0022 #include <bcm63xx_regs.h>
0023 #include <bcm63xx_io.h>
0024 
0025 static struct mtd_partition mtd_partitions[] = {
0026     {
0027         .name       = "cfe",
0028         .offset     = 0x0,
0029         .size       = 0x40000,
0030     }
0031 };
0032 
0033 static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
0034 
0035 static struct physmap_flash_data flash_data = {
0036     .width          = 2,
0037     .parts          = mtd_partitions,
0038     .part_probe_types   = bcm63xx_part_types,
0039 };
0040 
0041 static struct resource mtd_resources[] = {
0042     {
0043         .start      = 0,    /* filled at runtime */
0044         .end        = 0,    /* filled at runtime */
0045         .flags      = IORESOURCE_MEM,
0046     }
0047 };
0048 
0049 static struct platform_device mtd_dev = {
0050     .name           = "physmap-flash",
0051     .resource       = mtd_resources,
0052     .num_resources      = ARRAY_SIZE(mtd_resources),
0053     .dev            = {
0054         .platform_data  = &flash_data,
0055     },
0056 };
0057 
0058 static int __init bcm63xx_detect_flash_type(void)
0059 {
0060     u32 val;
0061 
0062     switch (bcm63xx_get_cpu_id()) {
0063     case BCM6328_CPU_ID:
0064         val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
0065         if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
0066             return BCM63XX_FLASH_TYPE_SERIAL;
0067         else
0068             return BCM63XX_FLASH_TYPE_NAND;
0069     case BCM6338_CPU_ID:
0070     case BCM6345_CPU_ID:
0071     case BCM6348_CPU_ID:
0072         /* no way to auto detect so assume parallel */
0073         return BCM63XX_FLASH_TYPE_PARALLEL;
0074     case BCM3368_CPU_ID:
0075     case BCM6358_CPU_ID:
0076         val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
0077         if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
0078             return BCM63XX_FLASH_TYPE_PARALLEL;
0079         else
0080             return BCM63XX_FLASH_TYPE_SERIAL;
0081     case BCM6362_CPU_ID:
0082         val = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
0083         if (val & STRAPBUS_6362_BOOT_SEL_SERIAL)
0084             return BCM63XX_FLASH_TYPE_SERIAL;
0085         else
0086             return BCM63XX_FLASH_TYPE_NAND;
0087     case BCM6368_CPU_ID:
0088         val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
0089         switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
0090         case STRAPBUS_6368_BOOT_SEL_NAND:
0091             return BCM63XX_FLASH_TYPE_NAND;
0092         case STRAPBUS_6368_BOOT_SEL_SERIAL:
0093             return BCM63XX_FLASH_TYPE_SERIAL;
0094         case STRAPBUS_6368_BOOT_SEL_PARALLEL:
0095             return BCM63XX_FLASH_TYPE_PARALLEL;
0096         }
0097         fallthrough;
0098     default:
0099         return -EINVAL;
0100     }
0101 }
0102 
0103 int __init bcm63xx_flash_register(void)
0104 {
0105     int flash_type;
0106     u32 val;
0107 
0108     flash_type = bcm63xx_detect_flash_type();
0109 
0110     switch (flash_type) {
0111     case BCM63XX_FLASH_TYPE_PARALLEL:
0112         /* read base address of boot chip select (0) */
0113         val = bcm_mpi_readl(MPI_CSBASE_REG(0));
0114         val &= MPI_CSBASE_BASE_MASK;
0115 
0116         mtd_resources[0].start = val;
0117         mtd_resources[0].end = 0x1FFFFFFF;
0118 
0119         return platform_device_register(&mtd_dev);
0120     case BCM63XX_FLASH_TYPE_SERIAL:
0121         pr_warn("unsupported serial flash detected\n");
0122         return -ENODEV;
0123     case BCM63XX_FLASH_TYPE_NAND:
0124         pr_warn("unsupported NAND flash detected\n");
0125         return -ENODEV;
0126     default:
0127         pr_err("flash detection failed for BCM%x: %d\n",
0128                bcm63xx_get_cpu_id(), flash_type);
0129         return -ENODEV;
0130     }
0131 }