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(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(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(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(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 /****************************************************************************/ 463