1 /* $NetBSD: nor.h,v 1.5 2018/04/19 21:50:09 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 Department of Software Engineering, 5 * University of Szeged, Hungary 6 * Copyright (c) 2011 Adam Hoka <ahoka (at) NetBSD.org> 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to The NetBSD Foundation 10 * by the Department of Software Engineering, University of Szeged, Hungary 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef _NOR_H_ 35 #define _NOR_H_ 36 37 #include <sys/param.h> 38 #include <sys/cdefs.h> 39 40 #include <sys/bufq.h> 41 #include <sys/buf.h> 42 #include <sys/device.h> 43 44 #include <sys/bus.h> 45 46 #include <dev/flash/flash.h> 47 #include <dev/flash/flash_io.h> 48 49 #ifdef NOR_DEBUG 50 #define DPRINTF(x) do { printf x ; } while (0) 51 #else 52 #define DPRINTF(x) 53 #endif 54 55 /** 56 * nor_chip: structure containing the required information 57 * about the NOR chip. 58 */ 59 struct nor_chip { 60 struct nor_ecc *nc_ecc; /* ecc information */ 61 uint8_t *nc_oob_cache; /* buffer for oob cache */ 62 uint8_t *nc_page_cache; /* buffer for page cache */ 63 uint8_t *nc_ecc_cache; 64 size_t nc_size; /* storage size in bytes */ 65 size_t nc_page_size; /* page (write buf) size in bytes */ 66 size_t nc_line_size; /* read line in bytes */ 67 size_t nc_block_pages; /* block size in pages */ 68 size_t nc_block_size; /* block size in bytes */ 69 size_t nc_spare_size; /* spare (oob) size in bytes */ 70 uint32_t nc_lun_blocks; /* LUN size in blocks */ 71 uint32_t nc_flags; /* bitfield flags */ 72 uint32_t nc_quirks; /* bitfield quirks */ 73 unsigned int nc_page_shift; /* page shift for page alignment */ 74 unsigned int nc_page_mask; /* page mask for page alignment */ 75 unsigned int nc_block_shift; /* write shift */ 76 unsigned int nc_block_mask; /* write mask */ 77 uint8_t nc_num_luns; /* number of LUNs */ 78 uint8_t nc_manf_id; /* manufacturer id */ 79 uint8_t nc_dev_id; /* device id */ 80 uint8_t nc_badmarker_offs; /* offset for marking bad blocks */ 81 }; 82 83 /* driver softc for nor */ 84 struct nor_softc { 85 device_t sc_dev; 86 device_t sc_controller_dev; 87 struct flash_interface sc_flash_if; 88 struct nor_interface *sc_nor_if; 89 void *nor_softc; 90 struct nor_chip sc_chip; 91 bus_addr_t sc_bus_addr; /* chip base address */ 92 bus_size_t sc_bus_size; /* total NOR size */ 93 off_t sc_part_offset; /* partition start, offset from base */ 94 size_t sc_part_size; /* partition size */ 95 bus_space_tag_t sc_bst; 96 bus_space_handle_t sc_bsh; 97 kmutex_t sc_device_lock; /* serialize access to chip */ 98 struct flash_io sc_flash_io; 99 }; 100 101 /* structure holding the nor api */ 102 struct nor_interface { 103 /* basic nor controller commands */ 104 int (*scan_media)(device_t self, struct nor_chip *chip); 105 void (*init) (device_t); 106 void (*select) (device_t, bool); /* optional */ 107 void (*read_1) (device_t, flash_off_t, uint8_t *); 108 void (*read_2) (device_t, flash_off_t, uint16_t *); 109 void (*read_4) (device_t, flash_off_t, uint32_t *); 110 void (*read_buf_1) (device_t, flash_off_t, uint8_t *, size_t); 111 void (*read_buf_2) (device_t, flash_off_t, uint16_t *, size_t); 112 void (*read_buf_4) (device_t, flash_off_t, uint32_t *, size_t); 113 void (*write_1) (device_t, flash_off_t, uint8_t); 114 void (*write_2) (device_t, flash_off_t, uint16_t); 115 void (*write_4) (device_t, flash_off_t, uint32_t); 116 void (*write_buf_1) (device_t, flash_off_t, const uint8_t *, size_t); 117 void (*write_buf_2) (device_t, flash_off_t, const uint16_t *, size_t); 118 void (*write_buf_4) (device_t, flash_off_t, const uint32_t *, size_t); 119 int (*busy) (device_t, flash_off_t, u_long); 120 121 int (*read_page) (device_t, flash_off_t, uint8_t *); 122 int (*program_page) (device_t, flash_off_t, const uint8_t *); 123 int (*erase_block) (device_t, flash_off_t); 124 int (*erase_all) (device_t); 125 126 void *private; /* where to attach e.g. struct cfi */ 127 int access_width; /* x8/x16/x32: 1/2/4 */ 128 129 /* flash partition information */ 130 const struct flash_partition *part_info; 131 int part_num; 132 }; 133 134 /* attach args */ 135 struct nor_attach_args { 136 struct nor_interface *naa_nor_if; 137 }; 138 139 static __inline bool 140 nor_busy(device_t device, flash_off_t offset, u_long usec) 141 { 142 struct nor_softc *sc = device_private(device); 143 bool rv; 144 145 KASSERT(sc->sc_nor_if->select != NULL); 146 KASSERT(sc->sc_controller_dev != NULL); 147 148 sc->sc_nor_if->select(sc->sc_controller_dev, true); 149 150 if (sc->sc_nor_if->busy != NULL) { 151 rv = sc->sc_nor_if->busy(sc->sc_controller_dev, offset, usec); 152 } else { 153 DELAY(usec); 154 rv = false; 155 } 156 157 sc->sc_nor_if->select(sc->sc_controller_dev, false); 158 159 return rv; 160 } 161 162 static __inline void 163 nor_select(device_t self, bool enable) 164 { 165 struct nor_softc *sc = device_private(self); 166 167 KASSERT(sc->sc_nor_if->select != NULL); 168 KASSERT(sc->sc_controller_dev != NULL); 169 170 sc->sc_nor_if->select(sc->sc_controller_dev, enable); 171 } 172 173 static __inline void 174 nor_read_1(device_t self, flash_off_t offset, uint8_t *data) 175 { 176 struct nor_softc *sc = device_private(self); 177 178 KASSERT(sc->sc_nor_if->read_1 != NULL); 179 KASSERT(sc->sc_controller_dev != NULL); 180 181 sc->sc_nor_if->read_1(sc->sc_controller_dev, offset, data); 182 } 183 184 static __inline void 185 nor_read_2(device_t self, flash_off_t offset, uint16_t *data) 186 { 187 struct nor_softc *sc = device_private(self); 188 189 KASSERT(sc->sc_nor_if->read_2 != NULL); 190 KASSERT(sc->sc_controller_dev != NULL); 191 192 sc->sc_nor_if->read_2(sc->sc_controller_dev, offset, data); 193 } 194 195 static __inline void 196 nor_read_4(device_t self, flash_off_t offset, uint32_t *data) 197 { 198 struct nor_softc *sc = device_private(self); 199 200 KASSERT(sc->sc_nor_if->read_4 != NULL); 201 KASSERT(sc->sc_controller_dev != NULL); 202 203 sc->sc_nor_if->read_4(sc->sc_controller_dev, offset, data); 204 } 205 206 static __inline void 207 nor_write_1(device_t self, flash_off_t offset, uint8_t data) 208 { 209 struct nor_softc *sc = device_private(self); 210 211 KASSERT(sc->sc_nor_if->write_1 != NULL); 212 KASSERT(sc->sc_controller_dev != NULL); 213 214 sc->sc_nor_if->write_1(sc->sc_controller_dev, offset, data); 215 } 216 217 static __inline void 218 nor_write_2(device_t self, flash_off_t offset, uint16_t data) 219 { 220 struct nor_softc *sc = device_private(self); 221 222 KASSERT(sc->sc_nor_if->write_2 != NULL); 223 KASSERT(sc->sc_controller_dev != NULL); 224 225 sc->sc_nor_if->write_2(sc->sc_controller_dev, offset, data); 226 } 227 228 static __inline void 229 nor_write_4(device_t self, flash_off_t offset, uint16_t data) 230 { 231 struct nor_softc *sc = device_private(self); 232 233 KASSERT(sc->sc_nor_if->write_4 != NULL); 234 KASSERT(sc->sc_controller_dev != NULL); 235 236 sc->sc_nor_if->write_4(sc->sc_controller_dev, offset, data); 237 } 238 239 static __inline void 240 nor_read_buf_1(device_t self, flash_off_t offset, void *buf, size_t size) 241 { 242 struct nor_softc *sc = device_private(self); 243 244 KASSERT(sc->sc_nor_if->read_buf_1 != NULL); 245 KASSERT(sc->sc_controller_dev != NULL); 246 247 sc->sc_nor_if->read_buf_1(sc->sc_controller_dev, offset, buf, size); 248 } 249 250 static __inline void 251 nor_read_buf_2(device_t self, flash_off_t offset, void *buf, size_t size) 252 { 253 struct nor_softc *sc = device_private(self); 254 255 KASSERT(sc->sc_nor_if->read_buf_2 != NULL); 256 KASSERT(sc->sc_controller_dev != NULL); 257 258 sc->sc_nor_if->read_buf_2(sc->sc_controller_dev, offset, buf, size); 259 } 260 261 static __inline void 262 nor_read_buf_4(device_t self, flash_off_t offset, void *buf, size_t size) 263 { 264 struct nor_softc *sc = device_private(self); 265 266 KASSERT(sc->sc_nor_if->read_buf_4 != NULL); 267 KASSERT(sc->sc_controller_dev != NULL); 268 269 sc->sc_nor_if->read_buf_4(sc->sc_controller_dev, offset, buf, size); 270 } 271 272 static __inline void 273 nor_write_buf_1(device_t self, flash_off_t offset, const void *buf, size_t size) 274 { 275 struct nor_softc *sc = device_private(self); 276 277 KASSERT(sc->sc_nor_if->write_buf_1 != NULL); 278 KASSERT(sc->sc_controller_dev != NULL); 279 280 sc->sc_nor_if->write_buf_1(sc->sc_controller_dev, offset, buf, size); 281 } 282 283 static __inline void 284 nor_write_buf_2(device_t self, flash_off_t offset, const void *buf, size_t size) 285 { 286 struct nor_softc *sc = device_private(self); 287 288 KASSERT(sc->sc_nor_if->write_buf_2 != NULL); 289 KASSERT(sc->sc_controller_dev != NULL); 290 291 sc->sc_nor_if->write_buf_2(sc->sc_controller_dev, offset, buf, size); 292 } 293 294 static __inline void 295 nor_write_buf_4(device_t self, flash_off_t offset, const void *buf, size_t size) 296 { 297 struct nor_softc *sc = device_private(self); 298 299 KASSERT(sc->sc_nor_if->write_buf_4 != NULL); 300 KASSERT(sc->sc_controller_dev != NULL); 301 302 sc->sc_nor_if->write_buf_4(sc->sc_controller_dev, offset, buf, size); 303 } 304 305 static __inline int 306 nor_read_page(device_t self, flash_off_t offset, uint8_t *data) 307 { 308 struct nor_softc *sc = device_private(self); 309 310 KASSERT(sc->sc_nor_if->read_page != NULL); 311 312 return sc->sc_nor_if->read_page(self, offset, data); 313 } 314 315 static __inline int 316 nor_program_page(device_t self, flash_off_t offset, const uint8_t *data) 317 { 318 struct nor_softc *sc = device_private(self); 319 320 KASSERT(sc->sc_nor_if->program_page != NULL); 321 322 return sc->sc_nor_if->program_page(self, offset, data); 323 } 324 325 static __inline int 326 nor_erase_all(device_t self) 327 { 328 struct nor_softc *sc = device_private(self); 329 330 KASSERT(sc->sc_nor_if->erase_all != NULL); 331 332 return sc->sc_nor_if->erase_all(self); 333 } 334 335 static __inline int 336 nor_erase_block(device_t self, flash_off_t offset) 337 { 338 struct nor_softc *sc = device_private(self); 339 340 KASSERT(sc->sc_nor_if->erase_block != NULL); 341 342 return sc->sc_nor_if->erase_block(self, offset); 343 } 344 345 /* Manufacturer IDs defined by JEDEC */ 346 enum { 347 NOR_MFR_UNKNOWN = 0x00, 348 NOR_MFR_AMD = 0x01, 349 NOR_MFR_FUJITSU = 0x04, 350 NOR_MFR_RENESAS = 0x07, 351 NOR_MFR_STMICRO = 0x20, 352 NOR_MFR_MICRON = 0x2c, 353 NOR_MFR_NATIONAL = 0x8f, 354 NOR_MFR_TOSHIBA = 0x98, 355 NOR_MFR_HYNIX = 0xad, 356 NOR_MFGR_MACRONIX = 0xc2, 357 NOR_MFR_SAMSUNG = 0xec 358 }; 359 360 struct nor_manufacturer { 361 int id; 362 const char *name; 363 }; 364 365 extern const struct nor_manufacturer nor_mfrs[]; 366 367 /* public nor specific functions */ 368 device_t nor_attach_mi(struct nor_interface *, device_t); 369 void nor_init_interface(struct nor_interface *); 370 371 372 #endif /* _NOR_H_ */ 373