1 1.8 andvar /* $NetBSD: cfi.h,v 1.8 2022/01/05 16:01:54 andvar Exp $ */ 2 1.2 cliff 3 1.1 ahoka #ifndef _CFI_H_ 4 1.1 ahoka #define _CFI_H_ 5 1.1 ahoka 6 1.2 cliff #include <dev/nor/cfi_0002.h> 7 1.3 dyoung #include <sys/bus.h> 8 1.2 cliff 9 1.2 cliff /* 10 1.2 cliff * minimum size to bus_space_map for probe/identify QRY: 11 1.2 cliff * larget offset needed is CFI_QUERY_MODE_ALT_ADDRESS 12 1.2 cliff * scaled by maximum attempted port width, so 13 1.2 cliff * min >= (0x555 * sizeof(uint32_t)) 14 1.2 cliff */ 15 1.2 cliff #define CFI_QRY_MIN_MAP_SIZE 0x2000 16 1.2 cliff 17 1.2 cliff 18 1.2 cliff typedef enum { 19 1.2 cliff CFI_STATE_DATA_ARRAY = 0, 20 1.2 cliff CFI_STATE_QUERY, 21 1.2 cliff /* TBD */ 22 1.2 cliff } cfi_state_t; 23 1.2 cliff 24 1.2 cliff 25 1.4 cliff struct cfi_erase_blk_info { 26 1.4 cliff uint16_t z; /* Erase Blocks are z * 256 bytes */ 27 1.4 cliff uint16_t y; /* y+1 = #Erase Blocks in region */ 28 1.4 cliff }; 29 1.4 cliff 30 1.2 cliff /* 31 1.2 cliff * CFI Query structure 32 1.2 cliff */ 33 1.2 cliff struct cfi_query_data { 34 1.2 cliff /* Query info */ 35 1.2 cliff uint8_t qry[3]; /* { 'Q', 'R', 'Y' } */ 36 1.8 andvar uint16_t id_pri; /* primary command set ID */ 37 1.2 cliff uint16_t addr_pri; /* primary table addr */ 38 1.2 cliff uint16_t id_alt; /* alternate command set ID */ 39 1.2 cliff uint16_t addr_alt; /* alternate table addr */ 40 1.2 cliff /* System Interface info */ 41 1.2 cliff uint8_t vcc_min; /* min Vcc */ 42 1.2 cliff uint8_t vcc_max; /* max Vcc */ 43 1.2 cliff uint8_t vpp_min; /* min Vpp */ 44 1.2 cliff uint8_t vpp_max; /* max Vpp */ 45 1.2 cliff uint8_t write_word_time_typ; /* typ 1-word timeout, 1<<N usec */ 46 1.2 cliff uint8_t write_nbyte_time_typ; /* typ multi-byte timeout, 1<<N usec */ 47 1.2 cliff uint8_t erase_blk_time_typ; /* typ 1-blk erase timeout, 1<<N msec */ 48 1.4 cliff uint8_t erase_chip_time_typ; /* typ chip erase timeout, 1<<N msec */ 49 1.2 cliff uint8_t write_word_time_max; /* max 1-word timeout, typ<<N */ 50 1.2 cliff uint8_t write_nbyte_time_max; /* max multi-byte timeout, typ<<N */ 51 1.2 cliff uint8_t erase_blk_time_max; /* max 1-blk erase timeout, typ<<N */ 52 1.4 cliff uint8_t erase_chip_time_max; /* max chip erase timeout, typ<<N */ 53 1.2 cliff /* Device Geometry Definition */ 54 1.2 cliff uint8_t device_size; /* 1<<N bytes */ 55 1.2 cliff uint16_t interface_code_desc; /* JEP137 interface code description */ 56 1.2 cliff uint16_t write_nbyte_size_max; /* max size of multi-byte write, 1<<N */ 57 1.2 cliff uint8_t erase_blk_regions; /* number of erase block regions */ 58 1.4 cliff struct cfi_erase_blk_info 59 1.4 cliff erase_blk_info[4]; /* describe erase block regions */ 60 1.2 cliff /* Vendor-specific Primary command set info */ 61 1.2 cliff union { 62 1.2 cliff struct cmdset_0002_query_data cmd_0002; 63 1.2 cliff } pri; 64 1.2 cliff #ifdef NOTYET 65 1.2 cliff /* Vendor-specific Alternate command set info */ 66 1.2 cliff union { 67 1.2 cliff /* some command set structure here */ 68 1.2 cliff } pri; 69 1.2 cliff #endif 70 1.2 cliff }; 71 1.2 cliff 72 1.2 cliff /* 73 1.2 cliff * decode interface_code_desc 74 1.2 cliff */ 75 1.4 cliff #define CFI_IFCODE_X8 0 76 1.4 cliff #define CFI_IFCODE_X16 1 77 1.4 cliff #define CFI_IFCODE_X8X16 2 78 1.7 christos static __inline const char * 79 1.2 cliff cfi_interface_desc_str(uint16_t icd) 80 1.2 cliff { 81 1.2 cliff switch(icd) { 82 1.4 cliff case CFI_IFCODE_X8: 83 1.2 cliff return "x8"; 84 1.4 cliff case CFI_IFCODE_X16: 85 1.2 cliff return "x16"; 86 1.4 cliff case CFI_IFCODE_X8X16: 87 1.2 cliff return "x8/x16"; 88 1.2 cliff default: 89 1.2 cliff return ""; 90 1.2 cliff } 91 1.2 cliff } 92 1.2 cliff 93 1.2 cliff /* 94 1.2 cliff * id_pri: CFI Command set and control assignments 95 1.2 cliff */ 96 1.2 cliff #define CFI_ID_PRI_NONE 0x0000 97 1.2 cliff #define CFI_ID_PRI_INTEL_EXT 0x0001 98 1.2 cliff #define CFI_ID_PRI_AMD_STD 0x0002 99 1.2 cliff #define CFI_ID_PRI_INTEL_STD 0x0003 100 1.2 cliff #define CFI_ID_PRI_AMD_EXT 0x0004 101 1.2 cliff #define CFI_ID_PRI_WINBOND 0x0005 102 1.2 cliff #define CFI_ID_PRI_ST_ADV 0x0020 103 1.2 cliff #define CFI_ID_PRI_MITSU_ADV 0x0100 104 1.2 cliff #define CFI_ID_PRI_MITSU_EXT 0x0101 105 1.2 cliff #define CFI_ID_PRI_SST_PAGE 0x0102 106 1.2 cliff #define CFI_ID_PRI_SST_OLD 0x0701 107 1.2 cliff #define CFI_ID_PRI_INTEL_PERF 0x0200 108 1.2 cliff #define CFI_ID_PRI_INTEL_DATA 0x0210 109 1.2 cliff #define CFI_ID_PRI_RESV 0xffff /* not allowed, reserved */ 110 1.2 cliff 111 1.2 cliff /* 112 1.2 cliff * JEDEC ID (autoselect) data 113 1.2 cliff */ 114 1.2 cliff struct cfi_jedec_id_data { 115 1.2 cliff uint16_t id_mid; /* manufacturer ID */ 116 1.2 cliff uint16_t id_did[3]; /* device ID */ 117 1.2 cliff uint16_t id_prot_state; 118 1.2 cliff uint16_t id_indicators; 119 1.2 cliff uint8_t id_swb_lo; /* lower software bits */ 120 1.2 cliff uint8_t id_swb_hi; /* upper software bits */ 121 1.2 cliff }; 122 1.2 cliff 123 1.2 cliff struct cfi; /* fwd ref */ 124 1.2 cliff 125 1.2 cliff struct cfi_ops { 126 1.2 cliff void (*cfi_reset)(struct cfi *); 127 1.2 cliff int (*cfi_busy)(struct cfi *, flash_off_t); 128 1.2 cliff int (*cfi_program_word)(struct cfi *, flash_off_t); 129 1.2 cliff int (*cfi_erase_sector)(struct cfi *, flash_off_t); 130 1.2 cliff }; 131 1.2 cliff 132 1.2 cliff /* NOTE: 133 1.2 cliff * CFI_0002_STATS are just meant temporarily for debugging 134 1.2 cliff * not for long-term use. Some event counters at the flash and nor 135 1.2 cliff * layers might be helpful eventually 136 1.2 cliff */ 137 1.2 cliff #ifdef CFI_0002_STATS 138 1.2 cliff struct cfi_0002_stats { 139 1.2 cliff u_long read_page; 140 1.2 cliff u_long program_page; 141 1.2 cliff u_long erase_all; 142 1.2 cliff u_long erase_block; 143 1.2 cliff u_long busy; 144 1.2 cliff u_long busy_usec_min; 145 1.2 cliff u_long busy_usec_max; 146 1.2 cliff struct timeval busy_poll_tv; 147 1.2 cliff struct timeval busy_yield_tv; 148 1.2 cliff u_long busy_poll; 149 1.2 cliff u_long busy_yield; 150 1.2 cliff u_long busy_yield_hit; 151 1.2 cliff u_long busy_yield_miss; 152 1.2 cliff u_long busy_yield_timo; 153 1.2 cliff }; 154 1.2 cliff 155 1.2 cliff extern void cfi_0002_stats_reset(struct cfi *); 156 1.2 cliff extern void cfi_0002_stats_print(struct cfi *); 157 1.2 cliff #define CFI_0002_STATS_INIT(dev, cfi) \ 158 1.2 cliff do { \ 159 1.2 cliff aprint_normal_dev(dev, "cfi=%p\n", cfi); \ 160 1.2 cliff cfi_0002_stats_reset(cfi); \ 161 1.2 cliff } while (0) 162 1.2 cliff #define CFI_0002_STATS_INC(cfi, field) (cfi)->cfi_0002_stats.field++ 163 1.2 cliff 164 1.2 cliff #else 165 1.2 cliff 166 1.5 cliff #define CFI_0002_STATS_INIT(dev, cfi) 167 1.2 cliff #define CFI_0002_STATS_INC(cfi, field) 168 1.2 cliff 169 1.2 cliff #endif /* CFI_0002_STATS */ 170 1.2 cliff 171 1.2 cliff struct cfi { 172 1.2 cliff bus_space_tag_t cfi_bst; 173 1.2 cliff bus_space_handle_t cfi_bsh; 174 1.2 cliff cfi_state_t cfi_state; 175 1.2 cliff uint8_t cfi_portwidth; /* port width, 1<<N bytes */ 176 1.2 cliff uint8_t cfi_chipwidth; /* chip width, 1<<N bytes */ 177 1.4 cliff bool cfi_emulated; /* ary data are faked */ 178 1.6 phx bus_size_t cfi_unlock_addr1; 179 1.6 phx bus_size_t cfi_unlock_addr2; 180 1.2 cliff struct cfi_query_data cfi_qry_data; /* CFI Query data */ 181 1.2 cliff struct cfi_jedec_id_data 182 1.2 cliff cfi_id_data; /* JEDEC ID data */ 183 1.4 cliff const char *cfi_name; /* optional chip name */ 184 1.2 cliff struct cfi_ops cfi_ops; /* chip dependent functions */ 185 1.2 cliff u_long cfi_yield_time; /* thresh. for yield in wait */ 186 1.2 cliff #ifdef CFI_0002_STATS 187 1.2 cliff struct cfi_0002_stats cfi_0002_stats; 188 1.2 cliff #endif 189 1.2 cliff }; 190 1.2 cliff 191 1.4 cliff /* 192 1.4 cliff * struct cfi_jedec_tab is an amalgamation of 193 1.4 cliff * - info to identify a chip based on JEDEC ID data, and 194 1.4 cliff * - values needed to fill in struct cfi (i.e. fields we depend on) 195 1.4 cliff */ 196 1.4 cliff struct cfi_jedec_tab { 197 1.4 cliff /* ID */ 198 1.4 cliff const char *jt_name; 199 1.4 cliff uint32_t jt_mid; 200 1.4 cliff uint32_t jt_did; 201 1.4 cliff /* cmdset */ 202 1.4 cliff uint16_t jt_id_pri; 203 1.4 cliff uint16_t jt_id_alt; 204 1.4 cliff /* geometry */ 205 1.4 cliff uint8_t jt_device_size; /* 1<<N bytes */ 206 1.4 cliff uint16_t jt_interface_code_desc; 207 1.4 cliff uint8_t jt_write_nbyte_size_max; /* 1<<N bytes */ 208 1.4 cliff uint8_t jt_erase_blk_regions; 209 1.4 cliff struct cfi_erase_blk_info 210 1.4 cliff jt_erase_blk_info[4]; 211 1.4 cliff /* timing */ 212 1.4 cliff uint8_t jt_write_word_time_typ; /* 1<<N usec */ 213 1.4 cliff uint8_t jt_write_nbyte_time_typ; /* 1<<N msec */ 214 1.4 cliff uint8_t jt_erase_blk_time_typ; /* 1<<N msec */ 215 1.4 cliff uint8_t jt_erase_chip_time_typ; /* 1<<N msec */ 216 1.4 cliff uint8_t jt_write_word_time_max; /* typ<<N usec */ 217 1.4 cliff uint8_t jt_write_nbyte_time_max; /* typ<<N msec */ 218 1.4 cliff uint8_t jt_erase_blk_time_max; /* typ<<N msec */ 219 1.4 cliff uint8_t jt_erase_chip_time_max; /* typ<<N msec */ 220 1.4 cliff }; 221 1.4 cliff 222 1.2 cliff 223 1.1 ahoka enum { 224 1.6 phx CFI_ADDR_ANY = 0x00*8, /* XXX "don't care" */ 225 1.2 cliff CFI_RESET_DATA = 0xf0, 226 1.2 cliff CFI_ALT_RESET_DATA = 0xff, 227 1.2 cliff 228 1.6 phx CFI_QUERY_MODE_ADDR = 0x55*8, /* some devices accept anything */ 229 1.6 phx CFI_QUERY_MODE_ALT_ADDR = 0x555*8, 230 1.1 ahoka CFI_QUERY_DATA = 0x98, 231 1.6 phx 232 1.6 phx CFI_AMD_UNLOCK_ADDR1 = 0x555*8, 233 1.6 phx CFI_AMD_UNLOCK_ADDR2 = 0x555*4, 234 1.2 cliff }; 235 1.2 cliff 236 1.7 christos static __inline void 237 1.2 cliff cfi_reset(struct cfi * const cfi) 238 1.2 cliff { 239 1.2 cliff KASSERT(cfi->cfi_ops.cfi_reset != NULL); 240 1.2 cliff cfi->cfi_ops.cfi_reset(cfi); 241 1.2 cliff } 242 1.1 ahoka 243 1.7 christos static __inline int 244 1.2 cliff cfi_erase_sector(struct cfi * const cfi, flash_off_t offset) 245 1.2 cliff { 246 1.2 cliff KASSERT(cfi->cfi_ops.cfi_erase_sector != NULL); 247 1.2 cliff return cfi->cfi_ops.cfi_erase_sector(cfi, offset); 248 1.2 cliff } 249 1.1 ahoka 250 1.7 christos static __inline int 251 1.2 cliff cfi_program_word(struct cfi * const cfi, flash_off_t offset) 252 1.2 cliff { 253 1.2 cliff KASSERT(cfi->cfi_ops.cfi_program_word != NULL); 254 1.2 cliff return cfi->cfi_ops.cfi_program_word(cfi, offset); 255 1.2 cliff } 256 1.2 cliff 257 1.2 cliff extern const struct nor_interface nor_interface_cfi; 258 1.2 cliff 259 1.2 cliff extern bool cfi_probe(struct cfi * const); 260 1.2 cliff extern bool cfi_identify(struct cfi * const); 261 1.2 cliff extern void cfi_print(device_t, struct cfi * const); 262 1.2 cliff extern void cfi_reset_default(struct cfi * const); 263 1.2 cliff extern void cfi_reset_std(struct cfi * const); 264 1.2 cliff extern void cfi_reset_alt(struct cfi * const); 265 1.2 cliff extern void cfi_cmd(struct cfi * const, bus_size_t, uint32_t); 266 1.1 ahoka 267 1.2 cliff #endif /* _CFI_H_ */ 268