Index: sys/arch/arm/rockchip/rk_platform.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/rockchip/rk_platform.c,v retrieving revision 1.12 diff -p -u -r1.12 rk_platform.c --- sys/arch/arm/rockchip/rk_platform.c 24 Apr 2021 23:36:28 -0000 1.12 +++ sys/arch/arm/rockchip/rk_platform.c 22 Jun 2021 23:27:43 -0000 @@ -39,6 +39,8 @@ __KERNEL_RCSID(0, "$NetBSD: rk_platform. #include #include +#include + #include #include @@ -70,6 +72,17 @@ rk_platform_init_attach_args(struct fdt_ static void rk_platform_device_register(device_t self, void *aux) { + prop_dictionary_t dict = device_properties(self); + + if (device_is_a(self, "ahcisata")) { + /* + * Marvel 9230 AHCI SATA controllers take between 1213 and 1216 + * milliseconds to reset, exceeding the AHCI spec of 1000. + */ + if (!prop_dictionary_set_uint32(dict, "ahci-reset-ms", 2000)) + printf("%s: Failed to set \"ahci-reset-ms\" property" + " on ahcisata\n", __func__); + } } static void Index: sys/dev/ic/ahcisata_core.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ahcisata_core.c,v retrieving revision 1.98 diff -p -u -r1.98 ahcisata_core.c --- sys/dev/ic/ahcisata_core.c 24 Apr 2021 23:36:55 -0000 1.98 +++ sys/dev/ic/ahcisata_core.c 22 Jun 2021 23:27:43 -0000 @@ -144,19 +144,35 @@ static int ahci_reset(struct ahci_softc *sc) { int i; + uint32_t ctrl; + uint32_t timeout = 1000; + prop_dictionary_t dict; /* reset controller */ - AHCI_WRITE(sc, AHCI_GHC, AHCI_GHC_HR); + ctrl = AHCI_READ(sc, AHCI_GHC); + if ((ctrl & AHCI_GHC_HR) == 0) { + AHCI_WRITE(sc, AHCI_GHC, ctrl | AHCI_GHC_HR); + } + + /* some systems (rockchip rk3399) need extra reset time for ahcisata. */ + dict = device_properties(sc->sc_atac.atac_dev); + if (dict) + prop_dictionary_get_uint32(dict, "ahci-reset-ms", &timeout); + /* wait up to 1s for reset to complete */ - for (i = 0; i < 1000; i++) { + for (i = 0; i < timeout; i++) { delay(1000); if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR) == 0) break; } - if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR)) { - aprint_error("%s: reset failed\n", AHCINAME(sc)); + if ((AHCI_READ(sc, AHCI_GHC) & AHCI_GHC_HR) != 0) { + aprint_error_dev(sc->sc_atac.atac_dev, "reset failed\n"); return -1; } + if (i > 1000) { + aprint_normal_dev(sc->sc_atac.atac_dev, + "reset took %d milliseconds\n", i); + } /* enable ahci mode */ ahci_enable(sc);