0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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,
0044 .end = 0,
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
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
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 }