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 = BHND_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, BHND_RESET_CF_ENABLE); + DELAY(10); + + /* + * After this 10us delay, we should spin waiting for resetstatus to + * clear + */ + tries = BHND_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 = BHND_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 = BHND_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/bhnd_core.h =================================================================== --- sys/dev/bhnd/bhnd_core.h +++ sys/dev/bhnd/bhnd_core.h @@ -24,8 +24,10 @@ #ifndef _BHND_BHND_CORE_H_ #define _BHND_BHND_CORE_H_ +#define BHND_NUM_OF_RETRIES 30 + /* 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 */ @@ -38,6 +40,9 @@ #define BHND_SF_DMA64 0x1000 /**< supports 64-bit DMA */ #define BHND_SF_CORE_BITS 0x0fff /**< core-specific status mask */ +/*Reset core control flags */ +#define BHND_RESET_CF_ENABLE 0x0001 + /* * A register that is common to all cores to * communicate w/PMU regarding clock control.