Home | History | Annotate | Download | only in nor

Lines Matching defs:cfi

1 /*	$NetBSD: cfi.c,v 1.9 2019/02/06 04:20:40 mrg Exp $	*/
36 __KERNEL_RCSID(0, "$NetBSD: cfi.c,v 1.9 2019/02/06 04:20:40 mrg Exp $");
47 #include <dev/nor/cfi.h>
66 static uint8_t cfi_read_qry(struct cfi * const, bus_size_t);
67 static bool cfi_jedec_id(struct cfi * const);
68 static bool cfi_emulate(struct cfi * const);
69 static const struct cfi_jedec_tab * cfi_jedec_search(struct cfi *);
70 static void cfi_jedec_fill(struct cfi * const,
252 #define CFI_QRY_UNPACK_COMMON(cfi, data, type) \
254 struct cfi_query_data * const qryp = &cfi->cfi_qry_data; \
293 cfi_chip_query_1(struct cfi * const cfi)
297 bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
300 CFI_QRY_UNPACK_COMMON(cfi, data, uint8_t);
304 cfi_chip_query_2(struct cfi * const cfi)
308 bus_space_read_region_2(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
311 CFI_QRY_UNPACK_COMMON(cfi, data, uint16_t);
315 cfi_chip_query_4(struct cfi * const cfi)
319 bus_space_read_region_4(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
322 CFI_QRY_UNPACK_COMMON(cfi, data, uint32_t);
326 cfi_chip_query_8(struct cfi * const cfi)
331 bus_space_read_region_8(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
334 CFI_QRY_UNPACK_COMMON(cfi, data, uint64_t);
339 * cfi_chip_query - detect a CFI chip
341 * fill in the struct cfi as we discover what's there
344 cfi_chip_query(struct cfi * const cfi)
351 KASSERT(cfi != NULL);
352 KASSERT(cfi->cfi_bst != NULL);
356 cfi_reset_default(cfi);
357 cfi_cmd(cfi, cfi_query_offset[j], CFI_QUERY_DATA);
359 if (cfi_read_qry(cfi, 0x10) == 'Q' &&
360 cfi_read_qry(cfi, 0x11) == 'R' &&
361 cfi_read_qry(cfi, 0x12) == 'Y') {
362 switch(cfi->cfi_portwidth) {
364 cfi_chip_query_1(cfi);
367 cfi_chip_query_2(cfi);
370 cfi_chip_query_4(cfi);
373 cfi_chip_query_8(cfi);
377 __func__, cfi->cfi_portwidth);
380 switch (cfi->cfi_qry_data.id_pri) {
382 cfi->cfi_unlock_addr1 = CFI_AMD_UNLOCK_ADDR1;
383 cfi->cfi_unlock_addr2 = CFI_AMD_UNLOCK_ADDR2;
386 DPRINTF(("%s: unsupported CFI cmdset %#04x\n",
387 __func__, cfi->cfi_qry_data.id_pri));
391 cfi->cfi_emulated = false;
400 * cfi_probe - search for a CFI NOR trying various port & chip widths
402 * - gather CFI QRY and PRI data
404 * - if cfi_chip_query() fails, emulate CFI using table data if possible,
411 cfi_probe(struct cfi * const cfi)
415 KASSERT(cfi != NULL);
418 cfi->cfi_unlock_addr1 = CFI_AMD_UNLOCK_ADDR1;
419 cfi->cfi_unlock_addr2 = CFI_AMD_UNLOCK_ADDR2;
423 cfi->cfi_portwidth = pw;
424 cfi->cfi_chipwidth = cw;
425 found = cfi_chip_query(cfi);
426 cfi_jedec_id(cfi);
428 found = cfi_emulate(cfi);
435 cfi_reset_default(cfi); /* exit QRY mode */
440 cfi_identify(struct cfi * const cfi)
442 const bus_space_tag_t bst = cfi->cfi_bst;
443 const bus_space_handle_t bsh = cfi->cfi_bsh;
445 KASSERT(cfi != NULL);
448 memset(cfi, 0, sizeof(struct cfi)); /* XXX clean slate */
449 cfi->cfi_bst = bst; /* restore bus space */
450 cfi->cfi_bsh = bsh; /* " " " */
452 return cfi_probe(cfi);
461 struct cfi * const cfi = (struct cfi * const)sc->sc_nor_if->private;
462 KASSERT(cfi != NULL);
464 sc->sc_nor_if->access_width = cfi->cfi_portwidth;
466 chip->nc_manf_id = cfi->cfi_id_data.id_mid;
467 chip->nc_dev_id = cfi->cfi_id_data.id_did[0]; /* XXX 3 words */
468 chip->nc_size = 1 << cfi->cfi_qry_data.device_size;
471 chip->nc_line_size = 1 << cfi->cfi_qry_data.pri.cmd_0002.page_size;
478 chip->nc_lun_blocks = cfi->cfi_qry_data.erase_blk_info[0].y + 1;
479 chip->nc_block_size = cfi->cfi_qry_data.erase_blk_info[0].z ?
480 cfi->cfi_qry_data.erase_blk_info[0].z * 256 : 128;
482 switch (cfi->cfi_qry_data.id_pri) {
484 cfi_0002_init(sc, cfi, chip);
567 * cfi_cmd - write a CFI command word.
575 cfi_cmd(struct cficfi, bus_size_t off, uint32_t val)
577 const bus_space_tag_t bst = cfi->cfi_bst;
578 bus_space_handle_t bsh = cfi->cfi_bsh;
582 off >>= 3 - cfi->cfi_portwidth;
584 pw = 1 << cfi->cfi_portwidth;
585 cw = 1 << cfi->cfi_chipwidth;
595 switch (cfi->cfi_portwidth) {
612 __func__, 1 << cfi->cfi_portwidth);
617 cfi_read_qry(struct cfi * const cfi, bus_size_t off)
619 const bus_space_tag_t bst = cfi->cfi_bst;
620 bus_space_handle_t bsh = cfi->cfi_bsh;
623 off <<= cfi->cfi_portwidth;
625 switch (cfi->cfi_portwidth) {
649 cfi_reset_default(struct cfi * const cfi)
652 cfi_cmd(cfi, CFI_ADDR_ANY, CFI_RESET_DATA);
653 cfi_cmd(cfi, CFI_ADDR_ANY, CFI_ALT_RESET_DATA);
660 cfi_reset_std(struct cfi * const cfi)
663 cfi_cmd(cfi, CFI_ADDR_ANY, CFI_RESET_DATA);
670 cfi_reset_alt(struct cfi * const cfi)
673 cfi_cmd(cfi, CFI_ADDR_ANY, CFI_ALT_RESET_DATA);
677 cfi_jedec_id_1(struct cfi * const cfi)
679 struct cfi_jedec_id_data *idp = &cfi->cfi_id_data;
682 bus_space_read_region_1(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
701 cfi_jedec_id_2(struct cfi * const cfi)
703 struct cfi_jedec_id_data *idp = &cfi->cfi_id_data;
706 bus_space_read_region_2(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
728 cfi_jedec_id_4(struct cfi * const cfi)
730 struct cfi_jedec_id_data *idp = &cfi->cfi_id_data;
733 bus_space_read_region_4(cfi->cfi_bst, cfi->cfi_bsh, 0, data,
758 cfi_jedec_id(struct cfi * const cfi)
763 cfi_reset_default(cfi);
764 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0xaa);
765 cfi_cmd(cfi, cfi->cfi_unlock_addr2, 0x55);
766 cfi_cmd(cfi, cfi->cfi_unlock_addr1, 0x90);
768 switch(cfi->cfi_portwidth) {
770 cfi_jedec_id_1(cfi);
773 cfi_jedec_id_2(cfi);
776 cfi_jedec_id_4(cfi);
780 cfi_jedec_id_8(cfi);
785 __func__, 1 << cfi->cfi_portwidth);
792 cfi_emulate(struct cfi * const cfi)
795 const struct cfi_jedec_tab *jt = cfi_jedec_search(cfi);
798 cfi->cfi_emulated = true;
799 cfi_jedec_fill(cfi, jt);
808 cfi_jedec_search(struct cfi *cfi)
810 struct cfi_jedec_id_data *idp = &cfi->cfi_id_data;
823 * cfi_jedec_fill - fill in cfi with info from table entry
826 cfi_jedec_fill(struct cfi *cfi, const struct cfi_jedec_tab *jt)
829 cfi->cfi_name = jt->jt_name;
831 struct cfi_query_data *qryp = &cfi->cfi_qry_data;
854 cfi_print(device_t self, struct cfi * const cfi)
857 struct cfi_query_data * const qryp = &cfi->cfi_qry_data;
860 if (cfi->cfi_emulated) {
862 cfi->cfi_name, pbuf,
865 aprint_normal_dev(self, "CFI NOR flash %s %s\n", pbuf,
870 cfi->cfi_id_data.id_mid,
871 cfi->cfi_id_data.id_did[0],
872 cfi->cfi_id_data.id_did[1],
873 cfi->cfi_id_data.id_did[2]);
875 8 << cfi->cfi_portwidth, 8 << cfi->cfi_chipwidth);
877 cfi->cfi_id_data.id_swb_lo,
878 cfi->cfi_id_data.id_swb_hi);
892 switch (cfi->cfi_qry_data.id_pri) {
894 cfi_0002_print(self, cfi);