Index: sys/dev/bhnd/bcma/bcma.c =================================================================== --- sys/dev/bhnd/bcma/bcma.c +++ sys/dev/bhnd/bcma/bcma.c @@ -43,6 +43,8 @@ #include "bcma_eromreg.h" #include "bcma_eromvar.h" +#include "bcma_dmp.h" +#include int bcma_probe(device_t dev) @@ -206,7 +208,9 @@ static int bcma_reset_core(device_t dev, device_t child, uint16_t flags) { - struct bcma_devinfo *dinfo; + struct bcma_devinfo *dinfo; + uint32_t tmp; + int tries; if (device_get_parent(child) != dev) BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags); @@ -217,9 +221,74 @@ if (dinfo->res_agent == NULL) return (ENODEV); - // TODO - perform reset + /* + * To ensure there are no pending operations prior to putting the core + * in reset, we should spin here for 300ms (in 10us intervals) + * waiting for resetstatus to clear. + */ + tries = BCMA_NUM_OF_RETRIES; + for(;;) { + tmp = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETSTATUS); + if (tmp == 0) + break; + if (--tries == 0) + return (ENXIO); + DELAY(10); + } - return (ENXIO); + /* Start reset */ + bhnd_bus_write_4(dinfo->res_agent, BCMA_DMP_RESETCTRL, BCMA_DMP_RC_RESET); + DELAY(10); + + /* + * After this 10us delay, we should spin waiting for resetstatus to + * clear + */ + tries = BCMA_NUM_OF_RETRIES; + for(;;) { + tmp = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETSTATUS); + if (tmp == 0) + break; + if (--tries == 0) + return (ENXIO); + DELAY(10); + } + + /* Enable clocks & force clock gating */ + bhnd_bus_write_4(dinfo->res_agent, BCMA_DMP_IOCTRL, BHND_CF_CLOCK_EN | + BHND_CF_FGC | flags); + bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_IOCTRL); + DELAY(10); + + /* Complete reset */ + bhnd_bus_write_4(dinfo->res_agent, BCMA_DMP_RESETCTRL, 0); + tries = BCMA_NUM_OF_RETRIES; + for(;;) { + tmp = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETCTRL); + if (tmp == 0) + break; + if (--tries == 0) + return (ENXIO); + DELAY(10); + } + + tries = BCMA_NUM_OF_RETRIES; + for(;;) { + tmp = bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_RESETSTATUS); + if (tmp == 0) + break; + if (--tries == 0) + return (ENXIO); + DELAY(10); + } + + /* Disable clock gating */ + bhnd_bus_write_4(dinfo->res_agent, BCMA_DMP_IOCTRL, BHND_CF_CLOCK_EN | + flags); + bhnd_bus_read_4(dinfo->res_agent, BCMA_DMP_IOCTRL); + DELAY(10); + + return (0); } static int Index: sys/dev/bhnd/bcma/bcma_dmp.h =================================================================== --- sys/dev/bhnd/bcma/bcma_dmp.h +++ sys/dev/bhnd/bcma/bcma_dmp.h @@ -180,7 +180,7 @@ #define BCMA_DMP_COMPONENTID3 0xffc /* resetctrl */ -#define BMCA_DMP_RC_RESET 1 +#define BCMA_DMP_RC_RESET 0x0001 /* config */ #define BCMA_DMP_CFG_OOB 0x00000020 Index: sys/dev/bhnd/bcma/bcmavar.h =================================================================== --- sys/dev/bhnd/bcma/bcmavar.h +++ sys/dev/bhnd/bcma/bcmavar.h @@ -45,6 +45,9 @@ * Internal definitions shared by bcma(4) driver implementations. */ +/* Timeout for reset / suspend operations */ +#define BCMA_NUM_OF_RETRIES 30 + /** BCMA port identifier. */ typedef u_int bcma_pid_t; #define BCMA_PID_MAX UINT_MAX /**< Maximum bcma_pid_t value */ @@ -147,4 +150,4 @@ device_t hostb_dev; /**< host bridge core, or NULL */ }; -#endif /* _BCMA_BCMAVAR_H_ */ \ No newline at end of file +#endif /* _BCMA_BCMAVAR_H_ */ Index: sys/dev/bhnd/bhnd_core.h =================================================================== --- sys/dev/bhnd/bhnd_core.h +++ sys/dev/bhnd/bhnd_core.h @@ -25,15 +25,15 @@ #define _BHND_BHND_CORE_H_ /* Common core control flags */ -#define BHND_CF_BIST_EN 0x8000 /**< ??? */ +#define BHND_CF_BIST_EN 0x8000 /**< built-in self test */ #define BHND_CF_PME_EN 0x4000 /**< ??? */ #define BHND_CF_CORE_BITS 0x3ffc /**< core specific flag mask */ #define BHND_CF_FGC 0x0002 /**< force clock gating */ #define BHND_CF_CLOCK_EN 0x0001 /**< enable clock */ /* Common core status flags */ -#define BHND_SF_BIST_DONE 0x8000 /**< ??? */ -#define BHND_SF_BIST_ERROR 0x4000 /**< ??? */ +#define BHND_SF_BIST_DONE 0x8000 /**< self test done */ +#define BHND_SF_BIST_ERROR 0x4000 /**< self test failed */ #define BHND_SF_GATED_CLK 0x2000 /**< clock gated */ #define BHND_SF_DMA64 0x1000 /**< supports 64-bit DMA */ #define BHND_SF_CORE_BITS 0x0fff /**< core-specific status mask */