^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* netsc520.c -- MTD map driver for AMD NetSc520 Demonstration Board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The NetSc520 is a demonstration board for the Elan Sc520 processor available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * from AMD. It has a single back of 16 megs of 32-bit Flash ROM and another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 16 megs of SDRAM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mtd/mtd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mtd/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mtd/partitions.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ** The single, 16 megabyte flash bank is divided into four virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ** partitions. The first partition is 768 KiB and is intended to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) ** store the kernel image loaded by the bootstrap loader. The second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ** partition is 256 KiB and holds the BIOS image. The third
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) ** partition is 14.5 MiB and is intended for the flash file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) ** image. The last partition is 512 KiB and contains another copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ** of the BIOS image and the reset vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ** Only the third partition should be mounted. The first partition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ** should not be mounted, but it can erased and written to using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ** MTD character routines. The second and fourth partitions should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ** not be touched - it is possible to corrupt the BIOS image by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ** mounting these partitions, and potentially the board will not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ** recoverable afterwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* partition_info gives details on the logical partitions that the split the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * single flash device into. If the size if zero we use up to the end of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct mtd_partition partition_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .name = "NetSc520 boot kernel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .size = 0xc0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .name = "NetSc520 Low BIOS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .offset = 0xc0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .size = 0x40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .name = "NetSc520 file system",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .offset = 0x100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .size = 0xe80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .name = "NetSc520 High BIOS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .offset = 0xf80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .size = 0x80000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define NUM_PARTITIONS ARRAY_SIZE(partition_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define WINDOW_SIZE 0x00100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define WINDOW_ADDR 0x00200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static struct map_info netsc520_map = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .name = "netsc520 Flash Bank",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .size = WINDOW_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .bankwidth = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .phys = WINDOW_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static struct mtd_info *mymtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int __init init_netsc520(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) printk(KERN_NOTICE "NetSc520 flash device: 0x%Lx at 0x%Lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) (unsigned long long)netsc520_map.size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) (unsigned long long)netsc520_map.phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) netsc520_map.virt = ioremap(netsc520_map.phys, netsc520_map.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!netsc520_map.virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) printk("Failed to ioremap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) simple_map_init(&netsc520_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mymtd = do_map_probe("cfi_probe", &netsc520_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if(!mymtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) mymtd = do_map_probe("map_ram", &netsc520_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if(!mymtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mymtd = do_map_probe("map_rom", &netsc520_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (!mymtd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) iounmap(netsc520_map.virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mymtd->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void __exit cleanup_netsc520(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (mymtd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mtd_device_unregister(mymtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) map_destroy(mymtd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (netsc520_map.virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) iounmap(netsc520_map.virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) netsc520_map.virt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) module_init(init_netsc520);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) module_exit(cleanup_netsc520);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) MODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@amd.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) MODULE_DESCRIPTION("MTD map driver for AMD NetSc520 Demonstration Board");