18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/* netsc520.c -- MTD map driver for AMD NetSc520 Demonstration Board
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
58c2ecf20Sopenharmony_ci *	based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * The NetSc520 is a demonstration board for the Elan Sc520 processor available
88c2ecf20Sopenharmony_ci * from AMD.  It has a single back of 16 megs of 32-bit Flash ROM and another
98c2ecf20Sopenharmony_ci * 16 megs of SDRAM.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/module.h>
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <linux/kernel.h>
158c2ecf20Sopenharmony_ci#include <linux/init.h>
168c2ecf20Sopenharmony_ci#include <asm/io.h>
178c2ecf20Sopenharmony_ci#include <linux/mtd/mtd.h>
188c2ecf20Sopenharmony_ci#include <linux/mtd/map.h>
198c2ecf20Sopenharmony_ci#include <linux/mtd/partitions.h>
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci** The single, 16 megabyte flash bank is divided into four virtual
248c2ecf20Sopenharmony_ci** partitions.  The first partition is 768 KiB and is intended to
258c2ecf20Sopenharmony_ci** store the kernel image loaded by the bootstrap loader.  The second
268c2ecf20Sopenharmony_ci** partition is 256 KiB and holds the BIOS image.  The third
278c2ecf20Sopenharmony_ci** partition is 14.5 MiB and is intended for the flash file system
288c2ecf20Sopenharmony_ci** image.  The last partition is 512 KiB and contains another copy
298c2ecf20Sopenharmony_ci** of the BIOS image and the reset vector.
308c2ecf20Sopenharmony_ci**
318c2ecf20Sopenharmony_ci** Only the third partition should be mounted.  The first partition
328c2ecf20Sopenharmony_ci** should not be mounted, but it can erased and written to using the
338c2ecf20Sopenharmony_ci** MTD character routines.  The second and fourth partitions should
348c2ecf20Sopenharmony_ci** not be touched - it is possible to corrupt the BIOS image by
358c2ecf20Sopenharmony_ci** mounting these partitions, and potentially the board will not be
368c2ecf20Sopenharmony_ci** recoverable afterwards.
378c2ecf20Sopenharmony_ci*/
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/* partition_info gives details on the logical partitions that the split the
408c2ecf20Sopenharmony_ci * single flash device into. If the size if zero we use up to the end of the
418c2ecf20Sopenharmony_ci * device. */
428c2ecf20Sopenharmony_cistatic const struct mtd_partition partition_info[] = {
438c2ecf20Sopenharmony_ci    {
448c2ecf20Sopenharmony_ci	    .name = "NetSc520 boot kernel",
458c2ecf20Sopenharmony_ci	    .offset = 0,
468c2ecf20Sopenharmony_ci	    .size = 0xc0000
478c2ecf20Sopenharmony_ci    },
488c2ecf20Sopenharmony_ci    {
498c2ecf20Sopenharmony_ci	    .name = "NetSc520 Low BIOS",
508c2ecf20Sopenharmony_ci	    .offset = 0xc0000,
518c2ecf20Sopenharmony_ci	    .size = 0x40000
528c2ecf20Sopenharmony_ci    },
538c2ecf20Sopenharmony_ci    {
548c2ecf20Sopenharmony_ci	    .name = "NetSc520 file system",
558c2ecf20Sopenharmony_ci	    .offset = 0x100000,
568c2ecf20Sopenharmony_ci	    .size = 0xe80000
578c2ecf20Sopenharmony_ci    },
588c2ecf20Sopenharmony_ci    {
598c2ecf20Sopenharmony_ci	    .name = "NetSc520 High BIOS",
608c2ecf20Sopenharmony_ci	    .offset = 0xf80000,
618c2ecf20Sopenharmony_ci	    .size = 0x80000
628c2ecf20Sopenharmony_ci    },
638c2ecf20Sopenharmony_ci};
648c2ecf20Sopenharmony_ci#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define WINDOW_SIZE	0x00100000
678c2ecf20Sopenharmony_ci#define WINDOW_ADDR	0x00200000
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic struct map_info netsc520_map = {
708c2ecf20Sopenharmony_ci	.name = "netsc520 Flash Bank",
718c2ecf20Sopenharmony_ci	.size = WINDOW_SIZE,
728c2ecf20Sopenharmony_ci	.bankwidth = 4,
738c2ecf20Sopenharmony_ci	.phys = WINDOW_ADDR,
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#define NUM_FLASH_BANKS	ARRAY_SIZE(netsc520_map)
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistatic struct mtd_info *mymtd;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic int __init init_netsc520(void)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	printk(KERN_NOTICE "NetSc520 flash device: 0x%Lx at 0x%Lx\n",
838c2ecf20Sopenharmony_ci			(unsigned long long)netsc520_map.size,
848c2ecf20Sopenharmony_ci			(unsigned long long)netsc520_map.phys);
858c2ecf20Sopenharmony_ci	netsc520_map.virt = ioremap(netsc520_map.phys, netsc520_map.size);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	if (!netsc520_map.virt) {
888c2ecf20Sopenharmony_ci		printk("Failed to ioremap\n");
898c2ecf20Sopenharmony_ci		return -EIO;
908c2ecf20Sopenharmony_ci	}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	simple_map_init(&netsc520_map);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	mymtd = do_map_probe("cfi_probe", &netsc520_map);
958c2ecf20Sopenharmony_ci	if(!mymtd)
968c2ecf20Sopenharmony_ci		mymtd = do_map_probe("map_ram", &netsc520_map);
978c2ecf20Sopenharmony_ci	if(!mymtd)
988c2ecf20Sopenharmony_ci		mymtd = do_map_probe("map_rom", &netsc520_map);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	if (!mymtd) {
1018c2ecf20Sopenharmony_ci		iounmap(netsc520_map.virt);
1028c2ecf20Sopenharmony_ci		return -ENXIO;
1038c2ecf20Sopenharmony_ci	}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	mymtd->owner = THIS_MODULE;
1068c2ecf20Sopenharmony_ci	mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
1078c2ecf20Sopenharmony_ci	return 0;
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic void __exit cleanup_netsc520(void)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	if (mymtd) {
1138c2ecf20Sopenharmony_ci		mtd_device_unregister(mymtd);
1148c2ecf20Sopenharmony_ci		map_destroy(mymtd);
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci	if (netsc520_map.virt) {
1178c2ecf20Sopenharmony_ci		iounmap(netsc520_map.virt);
1188c2ecf20Sopenharmony_ci		netsc520_map.virt = NULL;
1198c2ecf20Sopenharmony_ci	}
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cimodule_init(init_netsc520);
1238c2ecf20Sopenharmony_cimodule_exit(cleanup_netsc520);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
1268c2ecf20Sopenharmony_ciMODULE_AUTHOR("Mark Langsdorf <mark.langsdorf@amd.com>");
1278c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MTD map driver for AMD NetSc520 Demonstration Board");
128