Lines Matching defs:cfi
47 #include <dev/nor/cfi.h>
51 static void cfi_0002_version_init(struct cfi * const);
57 static int cfi_0002_busy_wait(struct cfi * const, flash_off_t, u_long);
58 static int cfi_0002_busy_poll(struct cfi * const, flash_off_t, u_long);
59 static int cfi_0002_busy_yield(struct cfi * const, flash_off_t, u_long);
60 static int cfi_0002_busy_dq7(struct cfi * const , flash_off_t);
62 static int cfi_0002_busy_reg(struct cfi * const, flash_off_t);
105 cfi_0002_time_write_nbyte(struct cfi *cfi)
107 u_int shft = cfi->cfi_qry_data.write_nbyte_time_typ;
108 shft += cfi->cfi_qry_data.write_nbyte_time_max;
117 cfi_0002_time_erase_blk(struct cfi *cfi)
119 u_int shft = cfi->cfi_qry_data.erase_blk_time_typ;
120 shft += cfi->cfi_qry_data.erase_blk_time_max;
129 cfi_0002_time_erase_all(struct cfi *cfi)
131 u_int shft = cfi->cfi_qry_data.erase_chip_time_typ;
132 shft += cfi->cfi_qry_data.erase_chip_time_max;
144 cfi_0002_time_dflt(struct cfi *cfi)
146 return cfi_0002_time_erase_all(cfi);
150 cfi_0002_init(struct nor_softc * const sc, struct cfi * const cfi,
153 CFI_0002_STATS_INIT(sc->sc_dev, cfi);
155 cfi_0002_version_init(cfi);
157 cfi->cfi_ops.cfi_reset = cfi_reset_std;
158 cfi->cfi_yield_time = 500; /* 500 usec */
162 1 << cfi->cfi_qry_data.write_nbyte_size_max;
184 cfi_0002_version_init(struct cfi * const cfi)
186 const uint8_t major = cfi->cfi_qry_data.pri.cmd_0002.version_maj;
187 const uint8_t minor = cfi->cfi_qry_data.pri.cmd_0002.version_min;
191 cfi->cfi_ops.cfi_busy = cfi_0002_busy_dq7;
193 cfi->cfi_ops.cfi_erase_sector = cfi_0002_erase_sector_q;
194 cfi->cfi_ops.cfi_program_word = cfi_0002_program_word_ub;
197 cfi->cfi_ops.cfi_busy = cfi_0002_busy_reg;
198 cfi->cfi_ops.cfi_erase_sector = cfi_0002_erase_sector_1;
199 cfi->cfi_ops.cfi_program_word = cfi_0002_program_word_no_ub;
210 cfi_0002_print(device_t self, struct cfi * const cfi)
213 struct cmdset_0002_query_data *pri = &cfi->cfi_qry_data.pri.cmd_0002;
238 struct cfi *cfi = (struct cfi * const)sc->sc_nor_if->private;
239 KASSERT(cfi != NULL);
245 KASSERT((chip->nc_page_size & ((1 << cfi->cfi_portwidth) - 1)) == 0);
247 CFI_0002_STATS_INC(cfi, read_page);
249 bus_size_t count = chip->nc_page_size >> cfi->cfi_portwidth;
252 int error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_dflt(cfi));
256 switch(cfi->cfi_portwidth) {
258 bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, offset,
262 bus_space_read_region_2(cfi->cfi_bst, cfi->cfi_bsh, offset,
266 bus_space_read_region_4(cfi->cfi_bst, cfi->cfi_bsh, offset,
270 panic("%s: bad port width %d\n", __func__, cfi->cfi_portwidth);
282 struct cfi *cfi = (struct cfi * const)sc->sc_nor_if->private;
283 KASSERT(cfi != NULL);
289 KASSERT((chip->nc_page_size & ((1 << cfi->cfi_portwidth) - 1)) == 0);
291 CFI_0002_STATS_INC(cfi, program_page);
293 bus_size_t count = chip->nc_page_size >> cfi->cfi_portwidth;
295 bus_size_t sa = offset << (3 - cfi->cfi_portwidth);
299 int error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_dflt(cfi));
303 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
304 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
305 cfi_cmd(cfi, sa, 0x25); /* Write To Buffer */
306 cfi_cmd(cfi, sa, wc);
308 switch(cfi->cfi_portwidth) {
310 bus_space_write_region_1(cfi->cfi_bst, cfi->cfi_bsh, offset,
314 bus_space_write_region_2(cfi->cfi_bst, cfi->cfi_bsh, offset,
318 bus_space_write_region_4(cfi->cfi_bst, cfi->cfi_bsh, offset,
322 panic("%s: bad port width %d\n", __func__, cfi->cfi_portwidth);
325 cfi_cmd(cfi, sa, 0x29); /* Write Buffer Program Confirm */
327 error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_write_nbyte(cfi));
338 struct cfi *cfi = (struct cfi * const)sc->sc_nor_if->private;
339 KASSERT(cfi != NULL);
341 CFI_0002_STATS_INC(cfi, erase_all);
343 int error = cfi_0002_busy_wait(cfi, 0, cfi_0002_time_dflt(cfi));
347 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
348 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
349 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0x80); /* erase start */
350 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
351 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
352 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0x10); /* erase chip */
354 error = cfi_0002_busy_wait(cfi, 0, cfi_0002_time_erase_all(cfi));
365 struct cfi *cfi = (struct cfi * const)sc->sc_nor_if->private;
366 KASSERT(cfi != NULL);
368 CFI_0002_STATS_INC(cfi, erase_block);
370 bus_size_t sa = offset << (3 - cfi->cfi_portwidth);
372 int error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_dflt(cfi));
376 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
377 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
378 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0x80); /* erase start */
379 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
380 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
381 cfi_cmd(cfi, sa, 0x30); /* erase sector */
383 error = cfi_0002_busy_wait(cfi, offset, cfi_0002_time_erase_blk(cfi));
397 struct cfi * const cfi = (struct cfi * const)sc->sc_nor_if->private;
399 CFI_0002_STATS_INC(cfi, busy);
401 return cfi_0002_busy_wait(cfi, offset, usec);
408 cfi_0002_busy_wait(struct cfi * const cfi, flash_off_t offset, u_long usec)
417 if (usec > cfi->cfi_0002_stats.busy_usec_max)
418 cfi->cfi_0002_stats.busy_usec_max = usec;
419 if (usec < cfi->cfi_0002_stats.busy_usec_min)
420 cfi->cfi_0002_stats.busy_usec_min = usec;
423 if (usec > cfi->cfi_yield_time) {
424 error = cfi_0002_busy_yield(cfi, offset, usec);
427 cfi->cfi_0002_stats.busy_yield++;
430 &cfi->cfi_0002_stats.busy_yield_tv,
431 &cfi->cfi_0002_stats.busy_yield_tv);
434 error = cfi_0002_busy_poll(cfi, offset, usec);
437 cfi->cfi_0002_stats.busy_poll++;
440 &cfi->cfi_0002_stats.busy_poll_tv,
441 &cfi->cfi_0002_stats.busy_poll_tv);
451 cfi_0002_busy_poll(struct cfi * const cfi, flash_off_t offset, u_long usec)
457 if (! cfi->cfi_ops.cfi_busy(cfi, offset))
469 cfi_0002_busy_yield(struct cfi * const cfi, flash_off_t offset, u_long usec)
479 if (! cfi->cfi_ops.cfi_busy(cfi, offset)) {
480 CFI_0002_STATS_INC(cfi, busy_yield_hit);
483 CFI_0002_STATS_INC(cfi, busy_yield_miss);
491 if (! cfi->cfi_ops.cfi_busy(cfi, offset))
495 CFI_0002_STATS_INC(cfi, busy_yield_timo);
509 cfi_0002_busy_dq7(struct cfi * const cfi, flash_off_t offset)
511 bus_space_tag_t bst = cfi->cfi_bst;
512 bus_space_handle_t bsh = cfi->cfi_bsh;
515 switch(cfi->cfi_portwidth) {
537 __func__, cfi->cfi_portwidth);
551 cfi_0002_busy_reg(struct cfi * const cfi, flash_off_t offset)
553 bus_space_tag_t bst = cfi->cfi_bst;
554 bus_space_handle_t bsh = cfi->cfi_bsh;
557 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0x70); /* Status Register Read */
559 switch(cfi->cfi_portwidth) {
571 __func__, cfi->cfi_portwidth);
580 cfi_0002_stats_reset(struct cfi *cfi)
582 cfi->cfi_0002_stats, 0, sizeof(struct cfi_0002_stats));
583 cfi->cfi_0002_stats.busy_usec_min = ~0;
587 cfi_0002_stats_print(struct cfi *cfi)
589 printf("read_page %lu\n", cfi->cfi_0002_stats.read_page);
590 printf("program_page %lu\n", cfi->cfi_0002_stats.program_page);
591 printf("erase_all %lu\n", cfi->cfi_0002_stats.erase_all);
592 printf("erase_block %lu\n", cfi->cfi_0002_stats.erase_block);
593 printf("busy %lu\n", cfi->cfi_0002_stats.busy);
596 cfi->cfi_qry_data.write_nbyte_time_typ);
598 cfi->cfi_qry_data.write_nbyte_time_max);
601 cfi->cfi_qry_data.erase_blk_time_typ);
603 cfi->cfi_qry_data.erase_blk_time_max);
606 cfi->cfi_qry_data.erase_chip_time_typ);
608 cfi->cfi_qry_data.erase_chip_time_max);
610 printf("time_write_nbyte %lu\n", cfi_0002_time_write_nbyte(cfi));
611 printf("time_erase_blk %lu\n", cfi_0002_time_erase_blk(cfi));
612 printf("time_erase_all %lu\n", cfi_0002_time_erase_all(cfi));
614 printf("busy_usec_min %lu\n", cfi->cfi_0002_stats.busy_usec_min);
615 printf("busy_usec_max %lu\n", cfi->cfi_0002_stats.busy_usec_max);
618 cfi->cfi_0002_stats.busy_poll_tv.tv_sec,
619 cfi->cfi_0002_stats.busy_poll_tv.tv_usec);
621 cfi->cfi_0002_stats.busy_yield_tv.tv_sec,
622 cfi->cfi_0002_stats.busy_yield_tv.tv_usec);
623 printf("busy_poll %lu\n", cfi->cfi_0002_stats.busy_poll);
624 printf("busy_yield %lu\n", cfi->cfi_0002_stats.busy_yield);
625 printf("busy_yield_hit %lu\n", cfi->cfi_0002_stats.busy_yield_hit);
626 printf("busy_yield_miss %lu\n", cfi->cfi_0002_stats.busy_yield_miss);
627 printf("busy_yield_timo %lu\n", cfi->cfi_0002_stats.busy_yield_timo);