root/drivers/mtd/maps/nettel.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nettel_reboot_notifier
  2. nettel_init
  3. nettel_cleanup

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /****************************************************************************/
   3 
   4 /*
   5  *      nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards.
   6  *
   7  *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
   8  *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
   9  */
  10 
  11 /****************************************************************************/
  12 
  13 #include <linux/module.h>
  14 #include <linux/init.h>
  15 #include <linux/types.h>
  16 #include <linux/kernel.h>
  17 #include <linux/mtd/mtd.h>
  18 #include <linux/mtd/map.h>
  19 #include <linux/mtd/partitions.h>
  20 #include <linux/mtd/cfi.h>
  21 #include <linux/reboot.h>
  22 #include <linux/err.h>
  23 #include <linux/kdev_t.h>
  24 #include <linux/root_dev.h>
  25 #include <asm/io.h>
  26 
  27 /****************************************************************************/
  28 
  29 #define INTEL_BUSWIDTH          1
  30 #define AMD_WINDOW_MAXSIZE      0x00200000
  31 #define AMD_BUSWIDTH            1
  32 
  33 /*
  34  *      PAR masks and shifts, assuming 64K pages.
  35  */
  36 #define SC520_PAR_ADDR_MASK     0x00003fff
  37 #define SC520_PAR_ADDR_SHIFT    16
  38 #define SC520_PAR_TO_ADDR(par) \
  39         (((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)
  40 
  41 #define SC520_PAR_SIZE_MASK     0x01ffc000
  42 #define SC520_PAR_SIZE_SHIFT    2
  43 #define SC520_PAR_TO_SIZE(par) \
  44         ((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))
  45 
  46 #define SC520_PAR(cs, addr, size) \
  47         ((cs) | \
  48         ((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
  49         (((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))
  50 
  51 #define SC520_PAR_BOOTCS        0x8a000000
  52 #define SC520_PAR_ROMCS1        0xaa000000
  53 #define SC520_PAR_ROMCS2        0xca000000      /* Cache disabled, 64K page */
  54 
  55 static void *nettel_mmcrp = NULL;
  56 
  57 #ifdef CONFIG_MTD_CFI_INTELEXT
  58 static struct mtd_info *intel_mtd;
  59 #endif
  60 static struct mtd_info *amd_mtd;
  61 
  62 /****************************************************************************/
  63 
  64 /****************************************************************************/
  65 
  66 #ifdef CONFIG_MTD_CFI_INTELEXT
  67 static struct map_info nettel_intel_map = {
  68         .name = "SnapGear Intel",
  69         .size = 0,
  70         .bankwidth = INTEL_BUSWIDTH,
  71 };
  72 
  73 static struct mtd_partition nettel_intel_partitions[] = {
  74         {
  75                 .name = "SnapGear kernel",
  76                 .offset = 0,
  77                 .size = 0x000e0000
  78         },
  79         {
  80                 .name = "SnapGear filesystem",
  81                 .offset = 0x00100000,
  82         },
  83         {
  84                 .name = "SnapGear config",
  85                 .offset = 0x000e0000,
  86                 .size = 0x00020000
  87         },
  88         {
  89                 .name = "SnapGear Intel",
  90                 .offset = 0
  91         },
  92         {
  93                 .name = "SnapGear BIOS Config",
  94                 .offset = 0x007e0000,
  95                 .size = 0x00020000
  96         },
  97         {
  98                 .name = "SnapGear BIOS",
  99                 .offset = 0x007e0000,
 100                 .size = 0x00020000
 101         },
 102 };
 103 #endif
 104 
 105 static struct map_info nettel_amd_map = {
 106         .name = "SnapGear AMD",
 107         .size = AMD_WINDOW_MAXSIZE,
 108         .bankwidth = AMD_BUSWIDTH,
 109 };
 110 
 111 static const struct mtd_partition nettel_amd_partitions[] = {
 112         {
 113                 .name = "SnapGear BIOS config",
 114                 .offset = 0x000e0000,
 115                 .size = 0x00010000
 116         },
 117         {
 118                 .name = "SnapGear BIOS",
 119                 .offset = 0x000f0000,
 120                 .size = 0x00010000
 121         },
 122         {
 123                 .name = "SnapGear AMD",
 124                 .offset = 0
 125         },
 126         {
 127                 .name = "SnapGear high BIOS",
 128                 .offset = 0x001f0000,
 129                 .size = 0x00010000
 130         }
 131 };
 132 
 133 #define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
 134 
 135 /****************************************************************************/
 136 
 137 #ifdef CONFIG_MTD_CFI_INTELEXT
 138 
 139 /*
 140  *      Set the Intel flash back to read mode since some old boot
 141  *      loaders don't.
 142  */
 143 static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
 144 {
 145         struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
 146         unsigned long b;
 147 
 148         /* Make sure all FLASH chips are put back into read mode */
 149         for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
 150                 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
 151                         cfi->device_type, NULL);
 152         }
 153         return(NOTIFY_OK);
 154 }
 155 
 156 static struct notifier_block nettel_notifier_block = {
 157         nettel_reboot_notifier, NULL, 0
 158 };
 159 
 160 #endif
 161 
 162 /****************************************************************************/
 163 
 164 static int __init nettel_init(void)
 165 {
 166         volatile unsigned long *amdpar;
 167         unsigned long amdaddr, maxsize;
 168         int num_amd_partitions=0;
 169 #ifdef CONFIG_MTD_CFI_INTELEXT
 170         volatile unsigned long *intel0par, *intel1par;
 171         unsigned long orig_bootcspar, orig_romcs1par;
 172         unsigned long intel0addr, intel0size;
 173         unsigned long intel1addr, intel1size;
 174         int intelboot, intel0cs, intel1cs;
 175         int num_intel_partitions;
 176 #endif
 177         int rc = 0;
 178 
 179         nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);
 180         if (nettel_mmcrp == NULL) {
 181                 printk("SNAPGEAR: failed to disable MMCR cache??\n");
 182                 return(-EIO);
 183         }
 184 
 185         /* Set CPU clock to be 33.000MHz */
 186         *((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01;
 187 
 188         amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4);
 189 
 190 #ifdef CONFIG_MTD_CFI_INTELEXT
 191         intelboot = 0;
 192         intel0cs = SC520_PAR_ROMCS1;
 193         intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0);
 194         intel1cs = SC520_PAR_ROMCS2;
 195         intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc);
 196 
 197         /*
 198          *      Save the CS settings then ensure ROMCS1 and ROMCS2 are off,
 199          *      otherwise they might clash with where we try to map BOOTCS.
 200          */
 201         orig_bootcspar = *amdpar;
 202         orig_romcs1par = *intel0par;
 203         *intel0par = 0;
 204         *intel1par = 0;
 205 #endif
 206 
 207         /*
 208          *      The first thing to do is determine if we have a separate
 209          *      boot FLASH device. Typically this is a small (1 to 2MB)
 210          *      AMD FLASH part. It seems that device size is about the
 211          *      only way to tell if this is the case...
 212          */
 213         amdaddr = 0x20000000;
 214         maxsize = AMD_WINDOW_MAXSIZE;
 215 
 216         *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
 217         __asm__ ("wbinvd");
 218 
 219         nettel_amd_map.phys = amdaddr;
 220         nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
 221         if (!nettel_amd_map.virt) {
 222                 printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
 223                 iounmap(nettel_mmcrp);
 224                 return(-EIO);
 225         }
 226         simple_map_init(&nettel_amd_map);
 227 
 228         if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
 229                 printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
 230                         (int)(amd_mtd->size>>10));
 231 
 232                 amd_mtd->owner = THIS_MODULE;
 233 
 234                 /* The high BIOS partition is only present for 2MB units */
 235                 num_amd_partitions = NUM_AMD_PARTITIONS;
 236                 if (amd_mtd->size < AMD_WINDOW_MAXSIZE)
 237                         num_amd_partitions--;
 238                 /* Don't add the partition until after the primary INTEL's */
 239 
 240 #ifdef CONFIG_MTD_CFI_INTELEXT
 241                 /*
 242                  *      Map the Intel flash into memory after the AMD
 243                  *      It has to start on a multiple of maxsize.
 244                  */
 245                 maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
 246                 if (maxsize < (32 * 1024 * 1024))
 247                         maxsize = (32 * 1024 * 1024);
 248                 intel0addr = amdaddr + maxsize;
 249 #endif
 250         } else {
 251 #ifdef CONFIG_MTD_CFI_INTELEXT
 252                 /* INTEL boot FLASH */
 253                 intelboot++;
 254 
 255                 if (!orig_romcs1par) {
 256                         intel0cs = SC520_PAR_BOOTCS;
 257                         intel0par = (volatile unsigned long *)
 258                                 (nettel_mmcrp + 0xc4);
 259                         intel1cs = SC520_PAR_ROMCS1;
 260                         intel1par = (volatile unsigned long *)
 261                                 (nettel_mmcrp + 0xc0);
 262 
 263                         intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar);
 264                         maxsize = SC520_PAR_TO_SIZE(orig_bootcspar);
 265                 } else {
 266                         /* Kernel base is on ROMCS1, not BOOTCS */
 267                         intel0cs = SC520_PAR_ROMCS1;
 268                         intel0par = (volatile unsigned long *)
 269                                 (nettel_mmcrp + 0xc0);
 270                         intel1cs = SC520_PAR_BOOTCS;
 271                         intel1par = (volatile unsigned long *)
 272                                 (nettel_mmcrp + 0xc4);
 273 
 274                         intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par);
 275                         maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
 276                 }
 277 
 278                 /* Destroy useless AMD MTD mapping */
 279                 amd_mtd = NULL;
 280                 iounmap(nettel_amd_map.virt);
 281                 nettel_amd_map.virt = NULL;
 282 #else
 283                 /* Only AMD flash supported */
 284                 rc = -ENXIO;
 285                 goto out_unmap2;
 286 #endif
 287         }
 288 
 289 #ifdef CONFIG_MTD_CFI_INTELEXT
 290         /*
 291          *      We have determined the INTEL FLASH configuration, so lets
 292          *      go ahead and probe for them now.
 293          */
 294 
 295         /* Set PAR to the maximum size */
 296         if (maxsize < (32 * 1024 * 1024))
 297                 maxsize = (32 * 1024 * 1024);
 298         *intel0par = SC520_PAR(intel0cs, intel0addr, maxsize);
 299 
 300         /* Turn other PAR off so the first probe doesn't find it */
 301         *intel1par = 0;
 302 
 303         /* Probe for the size of the first Intel flash */
 304         nettel_intel_map.size = maxsize;
 305         nettel_intel_map.phys = intel0addr;
 306         nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 307         if (!nettel_intel_map.virt) {
 308                 printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
 309                 rc = -EIO;
 310                 goto out_unmap2;
 311         }
 312         simple_map_init(&nettel_intel_map);
 313 
 314         intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
 315         if (!intel_mtd) {
 316                 rc = -ENXIO;
 317                 goto out_unmap1;
 318         }
 319 
 320         /* Set PAR to the detected size */
 321         intel0size = intel_mtd->size;
 322         *intel0par = SC520_PAR(intel0cs, intel0addr, intel0size);
 323 
 324         /*
 325          *      Map second Intel FLASH right after first. Set its size to the
 326          *      same maxsize used for the first Intel FLASH.
 327          */
 328         intel1addr = intel0addr + intel0size;
 329         *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize);
 330         __asm__ ("wbinvd");
 331 
 332         maxsize += intel0size;
 333 
 334         /* Delete the old map and probe again to do both chips */
 335         map_destroy(intel_mtd);
 336         intel_mtd = NULL;
 337         iounmap(nettel_intel_map.virt);
 338 
 339         nettel_intel_map.size = maxsize;
 340         nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
 341         if (!nettel_intel_map.virt) {
 342                 printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
 343                 rc = -EIO;
 344                 goto out_unmap2;
 345         }
 346 
 347         intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
 348         if (! intel_mtd) {
 349                 rc = -ENXIO;
 350                 goto out_unmap1;
 351         }
 352 
 353         intel1size = intel_mtd->size - intel0size;
 354         if (intel1size > 0) {
 355                 *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size);
 356                 __asm__ ("wbinvd");
 357         } else {
 358                 *intel1par = 0;
 359         }
 360 
 361         printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %lldKiB\n",
 362                (unsigned long long)(intel_mtd->size >> 10));
 363 
 364         intel_mtd->owner = THIS_MODULE;
 365 
 366         num_intel_partitions = ARRAY_SIZE(nettel_intel_partitions);
 367 
 368         if (intelboot) {
 369                 /*
 370                  *      Adjust offset and size of last boot partition.
 371                  *      Must allow for BIOS region at end of FLASH.
 372                  */
 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;
 383         } else {
 384                 /* No BIOS regions when AMD boot */
 385                 num_intel_partitions -= 2;
 386         }
 387         rc = mtd_device_register(intel_mtd, nettel_intel_partitions,
 388                                  num_intel_partitions);
 389         if (rc)
 390                 goto out_map_destroy;
 391 #endif
 392 
 393         if (amd_mtd) {
 394                 rc = mtd_device_register(amd_mtd, nettel_amd_partitions,
 395                                          num_amd_partitions);
 396                 if (rc)
 397                         goto out_mtd_unreg;
 398         }
 399 
 400 #ifdef CONFIG_MTD_CFI_INTELEXT
 401         register_reboot_notifier(&nettel_notifier_block);
 402 #endif
 403 
 404         return rc;
 405 
 406 out_mtd_unreg:
 407 #ifdef CONFIG_MTD_CFI_INTELEXT
 408         mtd_device_unregister(intel_mtd);
 409 out_map_destroy:
 410         map_destroy(intel_mtd);
 411 out_unmap1:
 412         iounmap(nettel_intel_map.virt);
 413 #endif
 414 
 415 out_unmap2:
 416         iounmap(nettel_mmcrp);
 417         iounmap(nettel_amd_map.virt);
 418 
 419         return rc;
 420 }
 421 
 422 /****************************************************************************/
 423 
 424 static void __exit nettel_cleanup(void)
 425 {
 426 #ifdef CONFIG_MTD_CFI_INTELEXT
 427         unregister_reboot_notifier(&nettel_notifier_block);
 428 #endif
 429         if (amd_mtd) {
 430                 mtd_device_unregister(amd_mtd);
 431                 map_destroy(amd_mtd);
 432         }
 433         if (nettel_mmcrp) {
 434                 iounmap(nettel_mmcrp);
 435                 nettel_mmcrp = NULL;
 436         }
 437         if (nettel_amd_map.virt) {
 438                 iounmap(nettel_amd_map.virt);
 439                 nettel_amd_map.virt = NULL;
 440         }
 441 #ifdef CONFIG_MTD_CFI_INTELEXT
 442         if (intel_mtd) {
 443                 mtd_device_unregister(intel_mtd);
 444                 map_destroy(intel_mtd);
 445         }
 446         if (nettel_intel_map.virt) {
 447                 iounmap(nettel_intel_map.virt);
 448                 nettel_intel_map.virt = NULL;
 449         }
 450 #endif
 451 }
 452 
 453 /****************************************************************************/
 454 
 455 module_init(nettel_init);
 456 module_exit(nettel_cleanup);
 457 
 458 MODULE_LICENSE("GPL");
 459 MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
 460 MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support");
 461 
 462 /****************************************************************************/

/* [<][>][^][v][top][bottom][index][help] */