1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX, 3 SBC-GXm and SBC-GX1 series boards. 4 5 Copyright (C) 2001 Arcom Control System Ltd 6 7 8 The SBC-MediaGX / SBC-GXx has up to 16 MiB of 9 Intel StrataFlash (28F320/28F640) in x8 mode. 10 11 This driver uses the CFI probe and Intel Extended Command Set drivers. 12 13 The flash is accessed as follows: 14 15 16 KiB memory window at 0xdc000-0xdffff 16 17 Two IO address locations for paging 18 19 0x258 20 bit 0-7: address bit 14-21 21 0x259 22 bit 0-1: address bit 22-23 23 bit 7: 0 - reset/powered down 24 1 - device enabled 25 26 The single flash device is divided into 3 partition which appear as 27 separate MTD devices. 28 29 25/04/2001 AJL (Arcom) Modified signon strings and partition sizes 30 (to support bzImages up to 638KiB-ish) 31 */ 32 33 // Includes 34 35 #include <linux/module.h> 36 #include <linux/ioport.h> 37 #include <linux/init.h> 38 #include <asm/io.h> 39 40 #include <linux/mtd/mtd.h> 41 #include <linux/mtd/map.h> 42 #include <linux/mtd/partitions.h> 43 44 // Defines 45 46 // - Hardware specific 47 48 #define WINDOW_START 0xdc000 49 50 /* Number of bits in offset. */ 51 #define WINDOW_SHIFT 14 52 #define WINDOW_LENGTH (1 << WINDOW_SHIFT) 53 54 /* The bits for the offset into the window. */ 55 #define WINDOW_MASK (WINDOW_LENGTH-1) 56 #define PAGE_IO 0x258 57 #define PAGE_IO_SIZE 2 58 59 /* bit 7 of 0x259 must be 1 to enable device. */ 60 #define DEVICE_ENABLE 0x8000 61 62 // - Flash / Partition sizing 63 64 #define MAX_SIZE_KiB 16384 65 #define BOOT_PARTITION_SIZE_KiB 768 66 #define DATA_PARTITION_SIZE_KiB 1280 67 #define APP_PARTITION_SIZE_KiB 6144 68 69 // Globals 70 71 static volatile int page_in_window = -1; // Current page in window. 72 static void __iomem *iomapadr; 73 static DEFINE_SPINLOCK(sbc_gxx_spin); 74 75 /* partition_info gives details on the logical partitions that the split the 76 * single flash device into. If the size if zero we use up to the end of the 77 * device. */ 78 static const struct mtd_partition partition_info[] = { 79 { .name = "SBC-GXx flash boot partition", 80 .offset = 0, 81 .size = BOOT_PARTITION_SIZE_KiB*1024 }, 82 { .name = "SBC-GXx flash data partition", 83 .offset = BOOT_PARTITION_SIZE_KiB*1024, 84 .size = (DATA_PARTITION_SIZE_KiB)*1024 }, 85 { .name = "SBC-GXx flash application partition", 86 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } 87 }; 88 89 #define NUM_PARTITIONS 3 90 91 static inline void sbc_gxx_page(struct map_info *map, unsigned long ofs) 92 { 93 unsigned long page = ofs >> WINDOW_SHIFT; 94 95 if( page!=page_in_window ) { 96 outw( page | DEVICE_ENABLE, PAGE_IO ); 97 page_in_window = page; 98 } 99 } 100 101 102 static map_word sbc_gxx_read8(struct map_info *map, unsigned long ofs) 103 { 104 map_word ret; 105 spin_lock(&sbc_gxx_spin); 106 sbc_gxx_page(map, ofs); 107 ret.x[0] = readb(iomapadr + (ofs & WINDOW_MASK)); 108 spin_unlock(&sbc_gxx_spin); 109 return ret; 110 } 111 112 static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) 113 { 114 while(len) { 115 unsigned long thislen = len; 116 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 117 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 118 119 spin_lock(&sbc_gxx_spin); 120 sbc_gxx_page(map, from); 121 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); 122 spin_unlock(&sbc_gxx_spin); 123 to += thislen; 124 from += thislen; 125 len -= thislen; 126 } 127 } 128 129 static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr) 130 { 131 spin_lock(&sbc_gxx_spin); 132 sbc_gxx_page(map, adr); 133 writeb(d.x[0], iomapadr + (adr & WINDOW_MASK)); 134 spin_unlock(&sbc_gxx_spin); 135 } 136 137 static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 138 { 139 while(len) { 140 unsigned long thislen = len; 141 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 142 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 143 144 spin_lock(&sbc_gxx_spin); 145 sbc_gxx_page(map, to); 146 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen); 147 spin_unlock(&sbc_gxx_spin); 148 to += thislen; 149 from += thislen; 150 len -= thislen; 151 } 152 } 153 154 static struct map_info sbc_gxx_map = { 155 .name = "SBC-GXx flash", 156 .phys = NO_XIP, 157 .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount 158 of flash so the cfi probe routines find all 159 the chips */ 160 .bankwidth = 1, 161 .read = sbc_gxx_read8, 162 .copy_from = sbc_gxx_copy_from, 163 .write = sbc_gxx_write8, 164 .copy_to = sbc_gxx_copy_to 165 }; 166 167 /* MTD device for all of the flash. */ 168 static struct mtd_info *all_mtd; 169 170 static void cleanup_sbc_gxx(void) 171 { 172 if( all_mtd ) { 173 mtd_device_unregister(all_mtd); 174 map_destroy( all_mtd ); 175 } 176 177 iounmap(iomapadr); 178 release_region(PAGE_IO,PAGE_IO_SIZE); 179 } 180 181 static int __init init_sbc_gxx(void) 182 { 183 iomapadr = ioremap(WINDOW_START, WINDOW_LENGTH); 184 if (!iomapadr) { 185 printk( KERN_ERR"%s: failed to ioremap memory region\n", 186 sbc_gxx_map.name ); 187 return -EIO; 188 } 189 190 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { 191 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", 192 sbc_gxx_map.name, 193 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); 194 iounmap(iomapadr); 195 return -EAGAIN; 196 } 197 198 199 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", 200 sbc_gxx_map.name, 201 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, 202 WINDOW_START, WINDOW_START+WINDOW_LENGTH-1 ); 203 204 /* Probe for chip. */ 205 all_mtd = do_map_probe( "cfi_probe", &sbc_gxx_map ); 206 if( !all_mtd ) { 207 cleanup_sbc_gxx(); 208 return -ENXIO; 209 } 210 211 all_mtd->owner = THIS_MODULE; 212 213 /* Create MTD devices for each partition. */ 214 mtd_device_register(all_mtd, partition_info, NUM_PARTITIONS); 215 216 return 0; 217 } 218 219 module_init(init_sbc_gxx); 220 module_exit(cleanup_sbc_gxx); 221 222 MODULE_LICENSE("GPL"); 223 MODULE_AUTHOR("Arcom Control Systems Ltd."); 224 MODULE_DESCRIPTION("MTD map driver for SBC-GXm and SBC-GX1 series boards"); 225