Lines Matching full:sc
65 cfi_read_raw(struct cfi_softc *sc, u_int ofs) in cfi_read_raw() argument
69 ofs &= ~(sc->sc_width - 1); in cfi_read_raw()
70 switch (sc->sc_width) { in cfi_read_raw()
72 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs); in cfi_read_raw()
75 val = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs); in cfi_read_raw()
78 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs); in cfi_read_raw()
88 cfi_read(struct cfi_softc *sc, u_int ofs) in cfi_read() argument
93 ofs &= ~(sc->sc_width - 1); in cfi_read()
94 switch (sc->sc_width) { in cfi_read()
96 val = bus_space_read_1(sc->sc_tag, sc->sc_handle, ofs); in cfi_read()
99 sval = bus_space_read_2(sc->sc_tag, sc->sc_handle, ofs); in cfi_read()
107 val = bus_space_read_4(sc->sc_tag, sc->sc_handle, ofs); in cfi_read()
120 cfi_write(struct cfi_softc *sc, u_int ofs, u_int val) in cfi_write() argument
123 ofs &= ~(sc->sc_width - 1); in cfi_write()
124 switch (sc->sc_width) { in cfi_write()
126 bus_space_write_1(sc->sc_tag, sc->sc_handle, ofs, val); in cfi_write()
130 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, val); in cfi_write()
132 bus_space_write_2(sc->sc_tag, sc->sc_handle, ofs, htole16(val)); in cfi_write()
138 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, val); in cfi_write()
140 bus_space_write_4(sc->sc_tag, sc->sc_handle, ofs, htole32(val)); in cfi_write()
150 cfi_reset_default(struct cfi_softc *sc) in cfi_reset_default() argument
153 cfi_write(sc, 0, CFI_BCS_READ_ARRAY2); in cfi_reset_default()
154 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_reset_default()
158 cfi_read_qry(struct cfi_softc *sc, u_int ofs) in cfi_read_qry() argument
162 cfi_write(sc, CFI_QRY_CMD_ADDR * sc->sc_width, CFI_QRY_CMD_DATA); in cfi_read_qry()
163 val = cfi_read(sc, ofs * sc->sc_width); in cfi_read_qry()
164 cfi_reset_default(sc); in cfi_read_qry()
169 cfi_amd_write(struct cfi_softc *sc, u_int ofs, u_int addr, u_int data) in cfi_amd_write() argument
172 cfi_write(sc, ofs + AMD_ADDR_START, CFI_AMD_UNLOCK); in cfi_amd_write()
173 cfi_write(sc, ofs + AMD_ADDR_ACK, CFI_AMD_UNLOCK_ACK); in cfi_amd_write()
174 cfi_write(sc, ofs + addr, data); in cfi_amd_write()
197 struct cfi_softc *sc; in cfi_probe() local
202 sc = device_get_softc(dev); in cfi_probe()
203 sc->sc_dev = dev; in cfi_probe()
205 sc->sc_rid = 0; in cfi_probe()
206 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, in cfi_probe()
208 if (sc->sc_res == NULL) in cfi_probe()
211 sc->sc_tag = rman_get_bustag(sc->sc_res); in cfi_probe()
212 sc->sc_handle = rman_get_bushandle(sc->sc_res); in cfi_probe()
214 if (sc->sc_width == 0) { in cfi_probe()
215 sc->sc_width = 1; in cfi_probe()
216 while (sc->sc_width <= 4) { in cfi_probe()
217 if (cfi_read_qry(sc, CFI_QRY_IDENT) == 'Q') in cfi_probe()
219 sc->sc_width <<= 1; in cfi_probe()
221 } else if (cfi_read_qry(sc, CFI_QRY_IDENT) != 'Q') { in cfi_probe()
225 if (sc->sc_width > 4) { in cfi_probe()
231 if (cfi_read_qry(sc, CFI_QRY_IDENT + 1) != 'R' || in cfi_probe()
232 cfi_read_qry(sc, CFI_QRY_IDENT + 2) != 'Y') { in cfi_probe()
238 vend = cfi_read_qry(sc, CFI_QRY_VEND) | in cfi_probe()
239 (cfi_read_qry(sc, CFI_QRY_VEND + 1) << 8); in cfi_probe()
241 sc->sc_cmdset = vend; in cfi_probe()
264 sc->sc_size = 1U << cfi_read_qry(sc, CFI_QRY_SIZE); in cfi_probe()
267 iface = cfi_read_qry(sc, CFI_QRY_IFACE) | in cfi_probe()
268 (cfi_read_qry(sc, CFI_QRY_IFACE + 1) << 8); in cfi_probe()
277 error = (iface & sc->sc_width) ? 0 : EINVAL; in cfi_probe()
281 device_set_descf(dev, "%s - %s", vend_str, cfi_fmtsize(sc->sc_size)); in cfi_probe()
284 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); in cfi_probe()
291 struct cfi_softc *sc; in cfi_attach() local
300 sc = device_get_softc(dev); in cfi_attach()
301 sc->sc_dev = dev; in cfi_attach()
303 sc->sc_rid = 0; in cfi_attach()
304 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, in cfi_attach()
310 if (sc->sc_res == NULL) in cfi_attach()
313 sc->sc_tag = rman_get_bustag(sc->sc_res); in cfi_attach()
314 sc->sc_handle = rman_get_bushandle(sc->sc_res); in cfi_attach()
317 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_ERASE); in cfi_attach()
318 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_ERASE); in cfi_attach()
337 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] = SBT_1MS * (1ULL << ttoexp); in cfi_attach()
338 sc->sc_max_timeouts[CFI_TIMEOUT_ERASE] = in cfi_attach()
339 sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] * (1ULL << mtoexp); in cfi_attach()
341 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_WRITE); in cfi_attach()
342 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_WRITE); in cfi_attach()
361 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] = SBT_1US * (1ULL << ttoexp); in cfi_attach()
362 sc->sc_max_timeouts[CFI_TIMEOUT_WRITE] = in cfi_attach()
363 sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] * (1ULL << mtoexp); in cfi_attach()
365 ttoexp = cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE); in cfi_attach()
366 mtoexp = cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE); in cfi_attach()
377 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] = in cfi_attach()
378 SBT_1US * (1ULL << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE)); in cfi_attach()
379 sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE] = in cfi_attach()
380 sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] * in cfi_attach()
381 (1ULL << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE)); in cfi_attach()
384 if (sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] != 0) in cfi_attach()
385 sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) | in cfi_attach()
386 cfi_read_qry(sc, CFI_QRY_MAXBUF) << 8); in cfi_attach()
388 sc->sc_maxbuf = 0; in cfi_attach()
391 sc->sc_regions = cfi_read_qry(sc, CFI_QRY_NREGIONS); in cfi_attach()
392 sc->sc_region = malloc(sc->sc_regions * sizeof(struct cfi_region), in cfi_attach()
394 for (r = 0; r < sc->sc_regions; r++) { in cfi_attach()
395 blocks = cfi_read_qry(sc, CFI_QRY_REGION(r)) | in cfi_attach()
396 (cfi_read_qry(sc, CFI_QRY_REGION(r) + 1) << 8); in cfi_attach()
397 sc->sc_region[r].r_blocks = blocks + 1; in cfi_attach()
399 blksz = cfi_read_qry(sc, CFI_QRY_REGION(r) + 2) | in cfi_attach()
400 (cfi_read_qry(sc, CFI_QRY_REGION(r) + 3) << 8); in cfi_attach()
401 sc->sc_region[r].r_blksz = (blksz == 0) ? 128 : in cfi_attach()
406 cfi_write(sc, 0, CFI_BCS_CLEAR_STATUS); in cfi_attach()
410 for (r = 0; r < sc->sc_regions; r++) { in cfi_attach()
411 printf("%ux%s%s", sc->sc_region[r].r_blocks, in cfi_attach()
412 cfi_fmtsize(sc->sc_region[r].r_blksz), in cfi_attach()
413 (r == sc->sc_regions - 1) ? "]\n" : ","); in cfi_attach()
417 if (sc->sc_cmdset == CFI_VEND_AMD_ECS || in cfi_attach()
418 sc->sc_cmdset == CFI_VEND_AMD_SCS) { in cfi_attach()
419 cfi_amd_write(sc, 0, AMD_ADDR_START, CFI_AMD_AUTO_SELECT); in cfi_attach()
420 sc->sc_manid = cfi_read(sc, 0); in cfi_attach()
421 sc->sc_devid = cfi_read(sc, 2); in cfi_attach()
423 sc->sc_manid, sc->sc_devid); in cfi_attach()
424 cfi_write(sc, 0, CFI_BCS_READ_ARRAY2); in cfi_attach()
428 sc->sc_nod = make_dev(&cfi_cdevsw, u, UID_ROOT, GID_WHEEL, 0600, in cfi_attach()
430 sc->sc_nod->si_drv1 = sc; in cfi_attach()
432 cfi_add_sysctls(sc); in cfi_attach()
439 if (cfi_intel_get_factory_pr(sc, &ppr) == 0) { in cfi_attach()
455 cfi_add_sysctls(struct cfi_softc *sc) in cfi_add_sysctls() argument
460 ctx = device_get_sysctl_ctx(sc->sc_dev); in cfi_add_sysctls()
461 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)); in cfi_add_sysctls()
465 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_ERASE], in cfi_add_sysctls()
469 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_ERASE], 0, in cfi_add_sysctls()
473 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_WRITE], 0, in cfi_add_sysctls()
477 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_WRITE], 0, in cfi_add_sysctls()
479 if (sc->sc_maxbuf > 0) { in cfi_add_sysctls()
482 CTLFLAG_RD, &sc->sc_tto_counts[CFI_TIMEOUT_BUFWRITE], 0, in cfi_add_sysctls()
487 CTLFLAG_RD, &sc->sc_mto_counts[CFI_TIMEOUT_BUFWRITE], 0, in cfi_add_sysctls()
496 struct cfi_softc *sc; in cfi_detach() local
498 sc = device_get_softc(dev); in cfi_detach()
500 destroy_dev(sc->sc_nod); in cfi_detach()
501 free(sc->sc_region, M_TEMP); in cfi_detach()
502 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_res); in cfi_detach()
507 cfi_check_erase(struct cfi_softc *sc, u_int ofs, u_int sz) in cfi_check_erase() argument
514 for (i = 0; i < sz; i += sc->sc_width) { in cfi_check_erase()
515 val = cfi_read(sc, ofs + i); in cfi_check_erase()
516 switch (sc->sc_width) { in cfi_check_erase()
538 cfi_wait_ready(struct cfi_softc *sc, u_int ofs, sbintime_t start, in cfi_wait_ready() argument
555 switch (sc->sc_cmdset) { in cfi_wait_ready()
558 st = cfi_read(sc, ofs); in cfi_wait_ready()
577 st0 = cfi_read(sc, ofs); in cfi_wait_ready()
578 st = cfi_read(sc, ofs); in cfi_wait_ready()
584 now > start + sc->sc_typical_timeouts[cmd]) { in cfi_wait_ready()
587 sc->sc_tto_counts[cmd]++; in cfi_wait_ready()
589 device_printf(sc->sc_dev, in cfi_wait_ready()
593 if (now > start + sc->sc_max_timeouts[cmd]) { in cfi_wait_ready()
594 sc->sc_mto_counts[cmd]++; in cfi_wait_ready()
596 device_printf(sc->sc_dev, in cfi_wait_ready()
610 cfi_write_block(struct cfi_softc *sc) in cfi_write_block() argument
626 switch (sc->sc_cmdset) { in cfi_write_block()
629 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS); in cfi_write_block()
630 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_UB); in cfi_write_block()
631 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY); in cfi_write_block()
636 for (i = 0; i < sc->sc_wrbufsz; i++) in cfi_write_block()
637 if ((sc->sc_wrbuf[i] & sc->sc_wrbufcpy[i]) != sc->sc_wrbuf[i]) { in cfi_write_block()
646 switch (sc->sc_cmdset) { in cfi_write_block()
649 cfi_write(sc, sc->sc_wrofs, CFI_BCS_BLOCK_ERASE); in cfi_write_block()
650 cfi_write(sc, sc->sc_wrofs, CFI_BCS_CONFIRM); in cfi_write_block()
655 minsz = sc->sc_region[0].r_blksz; in cfi_write_block()
656 for (i = 1; i < sc->sc_regions; i++) { in cfi_write_block()
657 if (sc->sc_region[i].r_blksz < minsz) in cfi_write_block()
658 minsz = sc->sc_region[i].r_blksz; in cfi_write_block()
660 cfi_amd_write(sc, sc->sc_wrofs, AMD_ADDR_START, in cfi_write_block()
662 cfi_amd_write(sc, sc->sc_wrofs, in cfi_write_block()
663 sc->sc_wrofs >> (ffs(minsz) - 1), in cfi_write_block()
666 if (cfi_check_erase(sc, sc->sc_wrofs, in cfi_write_block()
667 sc->sc_wrbufsz)) in cfi_write_block()
682 error = cfi_wait_ready(sc, sc->sc_wrofs, start, in cfi_write_block()
690 ptr.x8 = sc->sc_wrbuf; in cfi_write_block()
691 cpyprt.x8 = sc->sc_wrbufcpy; in cfi_write_block()
692 if (sc->sc_maxbuf > sc->sc_width) { in cfi_write_block()
693 switch (sc->sc_cmdset) { in cfi_write_block()
696 for (i = 0; i < sc->sc_wrbufsz; i += wlen) { in cfi_write_block()
697 wlen = MIN(sc->sc_maxbuf, sc->sc_wrbufsz - i); in cfi_write_block()
703 cfi_write(sc, sc->sc_wrofs + i, in cfi_write_block()
705 if (sbinuptime() > start + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE]) { in cfi_write_block()
709 st = cfi_read(sc, sc->sc_wrofs + i); in cfi_write_block()
712 cfi_write(sc, sc->sc_wrofs + i, in cfi_write_block()
713 (wlen / sc->sc_width) - 1); in cfi_write_block()
714 switch (sc->sc_width) { in cfi_write_block()
716 bus_space_write_region_1(sc->sc_tag, in cfi_write_block()
717 sc->sc_handle, sc->sc_wrofs + i, in cfi_write_block()
721 bus_space_write_region_2(sc->sc_tag, in cfi_write_block()
722 sc->sc_handle, sc->sc_wrofs + i, in cfi_write_block()
726 bus_space_write_region_4(sc->sc_tag, in cfi_write_block()
727 sc->sc_handle, sc->sc_wrofs + i, in cfi_write_block()
732 cfi_write(sc, sc->sc_wrofs + i, in cfi_write_block()
737 error = cfi_wait_ready(sc, sc->sc_wrofs + i, in cfi_write_block()
750 for (i = 0; i < sc->sc_wrbufsz; i += sc->sc_width) { in cfi_write_block()
753 switch (sc->sc_width) { in cfi_write_block()
777 switch (sc->sc_cmdset) { in cfi_write_block()
780 cfi_write(sc, sc->sc_wrofs + i, CFI_BCS_PROGRAM); in cfi_write_block()
784 cfi_amd_write(sc, 0, AMD_ADDR_START, CFI_AMD_PROGRAM); in cfi_write_block()
787 switch (sc->sc_width) { in cfi_write_block()
789 bus_space_write_1(sc->sc_tag, sc->sc_handle, in cfi_write_block()
790 sc->sc_wrofs + i, *(ptr.x8 + i)); in cfi_write_block()
793 bus_space_write_2(sc->sc_tag, sc->sc_handle, in cfi_write_block()
794 sc->sc_wrofs + i, *(ptr.x16 + i / 2)); in cfi_write_block()
797 bus_space_write_4(sc->sc_tag, sc->sc_handle, in cfi_write_block()
798 sc->sc_wrofs + i, *(ptr.x32 + i / 4)); in cfi_write_block()
804 if (sc->sc_cmdset == CFI_VEND_AMD_ECS || in cfi_write_block()
805 sc->sc_cmdset == CFI_VEND_AMD_SCS) { in cfi_write_block()
807 switch (sc->sc_width) { in cfi_write_block()
819 if (cfi_read(sc, sc->sc_wrofs + i) == val) in cfi_write_block()
830 error = cfi_wait_ready(sc, sc->sc_wrofs, start, in cfi_write_block()
840 cfi_reset_default(sc); in cfi_write_block()
843 switch (sc->sc_cmdset) { in cfi_write_block()
846 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LBS); in cfi_write_block()
847 cfi_write(sc, sc->sc_wrofs, CFI_INTEL_LB); in cfi_write_block()
848 cfi_write(sc, sc->sc_wrofs, CFI_BCS_READ_ARRAY); in cfi_write_block()
868 cfi_get16(struct cfi_softc *sc, int off) in cfi_get16() argument
870 uint16_t v = bus_space_read_2(sc->sc_tag, sc->sc_handle, off<<1); in cfi_get16()
876 cfi_put16(struct cfi_softc *sc, int off, uint16_t v) in cfi_put16() argument
878 bus_space_write_2(sc->sc_tag, sc->sc_handle, off<<1, v); in cfi_put16()
886 cfi_intel_get_factory_pr(struct cfi_softc *sc, uint64_t *id) in cfi_intel_get_factory_pr() argument
888 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) in cfi_intel_get_factory_pr()
890 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); in cfi_intel_get_factory_pr()
892 cfi_write(sc, 0, CFI_INTEL_READ_ID); in cfi_intel_get_factory_pr()
893 *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(0)))<<48 | in cfi_intel_get_factory_pr()
894 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(1)))<<32 | in cfi_intel_get_factory_pr()
895 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(2)))<<16 | in cfi_intel_get_factory_pr()
896 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(3))); in cfi_intel_get_factory_pr()
897 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_intel_get_factory_pr()
905 cfi_intel_get_oem_pr(struct cfi_softc *sc, uint64_t *id) in cfi_intel_get_oem_pr() argument
907 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) in cfi_intel_get_oem_pr()
909 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); in cfi_intel_get_oem_pr()
911 cfi_write(sc, 0, CFI_INTEL_READ_ID); in cfi_intel_get_oem_pr()
912 *id = ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(4)))<<48 | in cfi_intel_get_oem_pr()
913 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(5)))<<32 | in cfi_intel_get_oem_pr()
914 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(6)))<<16 | in cfi_intel_get_oem_pr()
915 ((uint64_t)cfi_get16(sc, CFI_INTEL_PR(7))); in cfi_intel_get_oem_pr()
916 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_intel_get_oem_pr()
925 cfi_intel_set_oem_pr(struct cfi_softc *sc, uint64_t id) in cfi_intel_set_oem_pr() argument
933 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) in cfi_intel_set_oem_pr()
935 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); in cfi_intel_set_oem_pr()
941 cfi_write(sc, 0, CFI_INTEL_PP_SETUP); in cfi_intel_set_oem_pr()
942 cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff); in cfi_intel_set_oem_pr()
944 error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, in cfi_intel_set_oem_pr()
949 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_intel_set_oem_pr()
952 device_printf(sc->sc_dev, "%s: OEM PR not set, " in cfi_intel_set_oem_pr()
962 cfi_intel_get_plr(struct cfi_softc *sc, uint32_t *plr) in cfi_intel_get_plr() argument
964 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) in cfi_intel_get_plr()
966 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); in cfi_intel_get_plr()
968 cfi_write(sc, 0, CFI_INTEL_READ_ID); in cfi_intel_get_plr()
969 *plr = cfi_get16(sc, CFI_INTEL_PLR); in cfi_intel_get_plr()
970 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_intel_get_plr()
980 cfi_intel_set_plr(struct cfi_softc *sc) in cfi_intel_set_plr() argument
987 if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) in cfi_intel_set_plr()
989 KASSERT(sc->sc_width == 2, ("sc_width %d", sc->sc_width)); in cfi_intel_set_plr()
993 device_printf(sc->sc_dev, "set PLR\n"); in cfi_intel_set_plr()
996 cfi_write(sc, 0, CFI_INTEL_PP_SETUP); in cfi_intel_set_plr()
997 cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD); in cfi_intel_set_plr()
999 error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, in cfi_intel_set_plr()
1001 cfi_write(sc, 0, CFI_BCS_READ_ARRAY); in cfi_intel_set_plr()
1004 device_printf(sc->sc_dev, "%s: PLR not set, " in cfi_intel_set_plr()