1 /****************************************************************************/
 
   4  *      nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards.
 
   6  *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
 
   7  *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
 
  10 /****************************************************************************/
 
  12 #include <linux/module.h>
 
  13 #include <linux/init.h>
 
  14 #include <linux/types.h>
 
  15 #include <linux/kernel.h>
 
  16 #include <linux/mtd/mtd.h>
 
  17 #include <linux/mtd/map.h>
 
  18 #include <linux/mtd/partitions.h>
 
  19 #include <linux/mtd/cfi.h>
 
  20 #include <linux/reboot.h>
 
  21 #include <linux/err.h>
 
  22 #include <linux/kdev_t.h>
 
  23 #include <linux/root_dev.h>
 
  26 /****************************************************************************/
 
  28 #define INTEL_BUSWIDTH          1
 
  29 #define AMD_WINDOW_MAXSIZE      0x00200000
 
  30 #define AMD_BUSWIDTH            1
 
  33  *      PAR masks and shifts, assuming 64K pages.
 
  35 #define SC520_PAR_ADDR_MASK     0x00003fff
 
  36 #define SC520_PAR_ADDR_SHIFT    16
 
  37 #define SC520_PAR_TO_ADDR(par) \
 
  38         (((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)
 
  40 #define SC520_PAR_SIZE_MASK     0x01ffc000
 
  41 #define SC520_PAR_SIZE_SHIFT    2
 
  42 #define SC520_PAR_TO_SIZE(par) \
 
  43         ((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))
 
  45 #define SC520_PAR(cs, addr, size) \
 
  47         ((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
 
  48         (((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))
 
  50 #define SC520_PAR_BOOTCS        0x8a000000
 
  51 #define SC520_PAR_ROMCS1        0xaa000000
 
  52 #define SC520_PAR_ROMCS2        0xca000000      /* Cache disabled, 64K page */
 
  54 static void *nettel_mmcrp = NULL;
 
  56 #ifdef CONFIG_MTD_CFI_INTELEXT
 
  57 static struct mtd_info *intel_mtd;
 
  59 static struct mtd_info *amd_mtd;
 
  61 /****************************************************************************/
 
  63 /****************************************************************************/
 
  65 #ifdef CONFIG_MTD_CFI_INTELEXT
 
  66 static struct map_info nettel_intel_map = {
 
  67         .name = "SnapGear Intel",
 
  69         .bankwidth = INTEL_BUSWIDTH,
 
  72 static struct mtd_partition nettel_intel_partitions[] = {
 
  74                 .name = "SnapGear kernel",
 
  79                 .name = "SnapGear filesystem",
 
  83                 .name = "SnapGear config",
 
  88                 .name = "SnapGear Intel",
 
  92                 .name = "SnapGear BIOS Config",
 
  97                 .name = "SnapGear BIOS",
 
 104 static struct map_info nettel_amd_map = {
 
 105         .name = "SnapGear AMD",
 
 106         .size = AMD_WINDOW_MAXSIZE,
 
 107         .bankwidth = AMD_BUSWIDTH,
 
 110 static struct mtd_partition nettel_amd_partitions[] = {
 
 112                 .name = "SnapGear BIOS config",
 
 113                 .offset = 0x000e0000,
 
 117                 .name = "SnapGear BIOS",
 
 118                 .offset = 0x000f0000,
 
 122                 .name = "SnapGear AMD",
 
 126                 .name = "SnapGear high BIOS",
 
 127                 .offset = 0x001f0000,
 
 132 #define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
 
 134 /****************************************************************************/
 
 136 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 139  *      Set the Intel flash back to read mode since some old boot
 
 142 static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
 
 144         struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
 
 147         /* Make sure all FLASH chips are put back into read mode */
 
 148         for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
 
 149                 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
 
 150                         cfi->device_type, NULL);
 
 155 static struct notifier_block nettel_notifier_block = {
 
 156         nettel_reboot_notifier, NULL, 0
 
 161 /****************************************************************************/
 
 163 static int __init nettel_init(void)
 
 165         volatile unsigned long *amdpar;
 
 166         unsigned long amdaddr, maxsize;
 
 167         int num_amd_partitions=0;
 
 168 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 169         volatile unsigned long *intel0par, *intel1par;
 
 170         unsigned long orig_bootcspar, orig_romcs1par;
 
 171         unsigned long intel0addr, intel0size;
 
 172         unsigned long intel1addr, intel1size;
 
 173         int intelboot, intel0cs, intel1cs;
 
 174         int num_intel_partitions;
 
 178         nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);
 
 179         if (nettel_mmcrp == NULL) {
 
 180                 printk("SNAPGEAR: failed to disable MMCR cache??\n");
 
 184         /* Set CPU clock to be 33.000MHz */
 
 185         *((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01;
 
 187         amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4);
 
 189 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 191         intel0cs = SC520_PAR_ROMCS1;
 
 192         intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0);
 
 193         intel1cs = SC520_PAR_ROMCS2;
 
 194         intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc);
 
 197          *      Save the CS settings then ensure ROMCS1 and ROMCS2 are off,
 
 198          *      otherwise they might clash with where we try to map BOOTCS.
 
 200         orig_bootcspar = *amdpar;
 
 201         orig_romcs1par = *intel0par;
 
 207          *      The first thing to do is determine if we have a separate
 
 208          *      boot FLASH device. Typically this is a small (1 to 2MB)
 
 209          *      AMD FLASH part. It seems that device size is about the
 
 210          *      only way to tell if this is the case...
 
 212         amdaddr = 0x20000000;
 
 213         maxsize = AMD_WINDOW_MAXSIZE;
 
 215         *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
 
 218         nettel_amd_map.phys = amdaddr;
 
 219         nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
 
 220         if (!nettel_amd_map.virt) {
 
 221                 printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
 
 222                 iounmap(nettel_mmcrp);
 
 225         simple_map_init(&nettel_amd_map);
 
 227         if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
 
 228                 printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
 
 231                 amd_mtd->owner = THIS_MODULE;
 
 233                 /* The high BIOS partition is only present for 2MB units */
 
 234                 num_amd_partitions = NUM_AMD_PARTITIONS;
 
 235                 if (amd_mtd->size < AMD_WINDOW_MAXSIZE)
 
 236                         num_amd_partitions--;
 
 237                 /* Don't add the partition until after the primary INTEL's */
 
 239 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 241                  *      Map the Intel flash into memory after the AMD
 
 242                  *      It has to start on a multiple of maxsize.
 
 244                 maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
 
 245                 if (maxsize < (32 * 1024 * 1024))
 
 246                         maxsize = (32 * 1024 * 1024);
 
 247                 intel0addr = amdaddr + maxsize;
 
 250 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 251                 /* INTEL boot FLASH */
 
 254                 if (!orig_romcs1par) {
 
 255                         intel0cs = SC520_PAR_BOOTCS;
 
 256                         intel0par = (volatile unsigned long *)
 
 257                                 (nettel_mmcrp + 0xc4);
 
 258                         intel1cs = SC520_PAR_ROMCS1;
 
 259                         intel1par = (volatile unsigned long *)
 
 260                                 (nettel_mmcrp + 0xc0);
 
 262                         intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar);
 
 263                         maxsize = SC520_PAR_TO_SIZE(orig_bootcspar);
 
 265                         /* Kernel base is on ROMCS1, not BOOTCS */
 
 266                         intel0cs = SC520_PAR_ROMCS1;
 
 267                         intel0par = (volatile unsigned long *)
 
 268                                 (nettel_mmcrp + 0xc0);
 
 269                         intel1cs = SC520_PAR_BOOTCS;
 
 270                         intel1par = (volatile unsigned long *)
 
 271                                 (nettel_mmcrp + 0xc4);
 
 273                         intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par);
 
 274                         maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
 
 277                 /* Destroy useless AMD MTD mapping */
 
 279                 iounmap(nettel_amd_map.virt);
 
 280                 nettel_amd_map.virt = NULL;
 
 282                 /* Only AMD flash supported */
 
 288 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 290          *      We have determined the INTEL FLASH configuration, so lets
 
 291          *      go ahead and probe for them now.
 
 294         /* Set PAR to the maximum size */
 
 295         if (maxsize < (32 * 1024 * 1024))
 
 296                 maxsize = (32 * 1024 * 1024);
 
 297         *intel0par = SC520_PAR(intel0cs, intel0addr, maxsize);
 
 299         /* Turn other PAR off so the first probe doesn't find it */
 
 302         /* Probe for the size of the first Intel flash */
 
 303         nettel_intel_map.size = maxsize;
 
 304         nettel_intel_map.phys = intel0addr;
 
 305         nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 
 306         if (!nettel_intel_map.virt) {
 
 307                 printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
 
 311         simple_map_init(&nettel_intel_map);
 
 313         intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
 
 319         /* Set PAR to the detected size */
 
 320         intel0size = intel_mtd->size;
 
 321         *intel0par = SC520_PAR(intel0cs, intel0addr, intel0size);
 
 324          *      Map second Intel FLASH right after first. Set its size to the
 
 325          *      same maxsize used for the first Intel FLASH.
 
 327         intel1addr = intel0addr + intel0size;
 
 328         *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize);
 
 331         maxsize += intel0size;
 
 333         /* Delete the old map and probe again to do both chips */
 
 334         map_destroy(intel_mtd);
 
 336         iounmap(nettel_intel_map.virt);
 
 338         nettel_intel_map.size = maxsize;
 
 339         nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 
 340         if (!nettel_intel_map.virt) {
 
 341                 printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
 
 346         intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
 
 352         intel1size = intel_mtd->size - intel0size;
 
 353         if (intel1size > 0) {
 
 354                 *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size);
 
 360         printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",
 
 361                 (intel_mtd->size >> 10));
 
 363         intel_mtd->owner = THIS_MODULE;
 
 365         num_intel_partitions = sizeof(nettel_intel_partitions) /
 
 366                 sizeof(nettel_intel_partitions[0]);
 
 370                  *      Adjust offset and size of last boot partition.
 
 371                  *      Must allow for BIOS region at end of FLASH.
 
 373                 nettel_intel_partitions[1].size = (intel0size + intel1size) -
 
 374                         (1024*1024 + intel_mtd->erasesize);
 
 375                 nettel_intel_partitions[3].size = intel0size + intel1size;
 
 376                 nettel_intel_partitions[4].offset =
 
 377                         (intel0size + intel1size) - intel_mtd->erasesize;
 
 378                 nettel_intel_partitions[4].size = intel_mtd->erasesize;
 
 379                 nettel_intel_partitions[5].offset =
 
 380                         nettel_intel_partitions[4].offset;
 
 381                 nettel_intel_partitions[5].size =
 
 382                         nettel_intel_partitions[4].size;
 
 384                 /* No BIOS regions when AMD boot */
 
 385                 num_intel_partitions -= 2;
 
 387         rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions,
 
 388                 num_intel_partitions);
 
 392                 rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions,
 
 396 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 397         register_reboot_notifier(&nettel_notifier_block);
 
 402 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 404         iounmap(nettel_intel_map.virt);
 
 408         iounmap(nettel_mmcrp);
 
 409         iounmap(nettel_amd_map.virt);
 
 415 /****************************************************************************/
 
 417 static void __exit nettel_cleanup(void)
 
 419 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 420         unregister_reboot_notifier(&nettel_notifier_block);
 
 423                 del_mtd_partitions(amd_mtd);
 
 424                 map_destroy(amd_mtd);
 
 427                 iounmap(nettel_mmcrp);
 
 430         if (nettel_amd_map.virt) {
 
 431                 iounmap(nettel_amd_map.virt);
 
 432                 nettel_amd_map.virt = NULL;
 
 434 #ifdef CONFIG_MTD_CFI_INTELEXT
 
 436                 del_mtd_partitions(intel_mtd);
 
 437                 map_destroy(intel_mtd);
 
 439         if (nettel_intel_map.virt) {
 
 440                 iounmap(nettel_intel_map.virt);
 
 441                 nettel_intel_map.virt = NULL;
 
 446 /****************************************************************************/
 
 448 module_init(nettel_init);
 
 449 module_exit(nettel_cleanup);
 
 451 MODULE_LICENSE("GPL");
 
 452 MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
 
 453 MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support");
 
 455 /****************************************************************************/