uint
si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_corereg(sih, coreidx, regoff, mask, val);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_corereg(sih, coreidx, regoff, mask, val);
	else {
		ASSERT(0);
		return 0;
	}
}
Exemplo n.º 2
0
uint
si_corerev(si_t *sih)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_corerev(sih);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_corerev(sih);
	else {
		ASSERT(0);
		return 0;
	}
}
bool
si_iscoreup(si_t *sih)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_iscoreup(sih);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_iscoreup(sih);
	else {
		ASSERT(0);
		return FALSE;
	}
}
uint32
si_core_sflags(si_t *sih, uint32 mask, uint32 val)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_core_sflags(sih, mask, val);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_core_sflags(sih, mask, val);
	else {
		ASSERT(0);
		return 0;
	}
}
uint32
si_addrspacesize(si_t *sih, uint asidx)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_addrspacesize(sih, asidx);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_addrspacesize(sih, asidx);
	else {
		ASSERT(0);
		return 0;
	}
}
int
si_numaddrspaces(si_t *sih)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_numaddrspaces(sih);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_numaddrspaces(sih);
	else {
		ASSERT(0);
		return 0;
	}
}
void *
si_setcoreidx(si_t *sih, uint coreidx)
{
	if(sih == NULL)
		return NULL;
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_setcoreidx(sih, coreidx);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_setcoreidx(sih, coreidx);
	else {
		ASSERT(0);
		return NULL;
	}
}
Exemplo n.º 8
0
uint
si_intflag(si_t *sih)
{
	si_info_t *sii = SI_INFO(sih);
	if (CHIPTYPE(sih->socitype) == SOCI_SB) {
		sbconfig_t *ccsbr = (sbconfig_t *)((uintptr)((ulong)
			    (sii->common_info->coresba[SI_CC_IDX]) + SBCONFIGOFF));
		return R_REG(sii->osh, &ccsbr->sbflagst);
	} else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return R_REG(sii->osh, ((uint32 *)(uintptr)
			    (sii->common_info->oob_router + OOB_STATUSA)));
	else {
		ASSERT(0);
		return 0;
	}
}
Exemplo n.º 9
0
/*
 * This function changes logical "focus" to the indicated core;
 * must be called with interrupts off.
 * Moreover, callers should keep interrupts off during switching out of and back to d11 core
 */
void *
si_setcore(si_t *sih, uint coreid, uint coreunit)
{
	uint idx;

	idx = si_findcoreidx(sih, coreid, coreunit);
	if (!GOODIDX(idx))
		return (NULL);

	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		return sb_setcoreidx(sih, idx);
	else if (CHIPTYPE(sih->socitype) == SOCI_AI)
		return ai_setcoreidx(sih, idx);
	else {
		ASSERT(0);
		return NULL;
	}
}
Exemplo n.º 10
0
void
si_write_wrapperreg(si_t *sih, uint32 offset, uint32 val)
{
	/* only for 4319, no requirement for SOCI_SB */
	if (CHIPTYPE(sih->socitype) == SOCI_AI) {
		ai_write_wrap_reg(sih, offset, val);
	}
	else
		return;

	return;
}
Exemplo n.º 11
0
int
si_bist_d11(si_t *sih, uint32 *biststatus1, uint32 *biststatus2)
{
	si_info_t *sii;
	uint origidx;
    uint intr_val = 0;
    void *regs;
    int error = 0;
    bool wasup;
    uint32 offset = SBCONFIGOFF + SBTMSTATELOW;
    uint32 max_res_mask;
    uint32 pmu_ctrl;

    *biststatus1 = 0;
    *biststatus2 = 0;

    SI_ERROR(("doing the bist on D11\n"));

    sii = SI_INFO(sih);

    if (CHIPTYPE(sih->socitype) != SOCI_SB) {
     return 0;
    }

    /* Block ints and save current core */
    INTR_OFF(sii, intr_val);
    origidx = si_coreidx(sih);

    /* Switch to D11 core */
    if (!(regs = si_setcore(sih, D11_CORE_ID, 0)))
	    goto done;

    /* Get info for determining size */
    /* coming out of reset device shoudl have clk enabled, bw set, etc */
    if (!(wasup = si_iscoreup(sih)))
        si_core_reset(sih, 0x4F, 0x4F);

    max_res_mask = si_corereg(sih, 0, OFFSETOF(chipcregs_t, max_res_mask), 0, 0);
    si_corereg(sih, 0, OFFSETOF(chipcregs_t, max_res_mask), ~0, 0x3fffff);

    if (si_corerev(&sii->pub) == 20) {
        uint32 phy_reset_val;
        uint32 bist_test_val, bist_status;

        /* XXX: enable the phy PLL */
        pmu_ctrl = si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, 0, 0);
        pmu_ctrl |= 0x000010000;
        si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, ~0, pmu_ctrl);
        SPINWAIT(((si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, 0, 0) & 0x01000000) == 0),
                1000000);
        pmu_ctrl = si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, 0, 0);

        /* take the phy out of reset */
        phy_reset_val = si_corereg(sih, si_coreidx(&sii->pub), offset, 0, 0);
        phy_reset_val &= ~(0x0008 << SBTML_SICF_SHIFT);
        si_corereg(sih, si_coreidx(&sii->pub), offset, ~0, phy_reset_val);
        phy_reset_val = si_corereg(sih, si_coreidx(&sii->pub), offset, 0, 0);

        /* enable bist first */
        bist_test_val = si_corereg(sih, si_coreidx(&sii->pub), offset, 0, 0);
        bist_test_val |= (SICF_BIST_EN << 16);
        si_corereg(sih, si_coreidx(&sii->pub), offset, ~0, bist_test_val);
        SPINWAIT(((si_core_sflags(sih, 0, 0) & SISF_BIST_DONE) == 0), 1000000);
        bist_status = si_core_sflags(sih, 0, 0);
        SI_ERROR(("status are 0x%08x\n", bist_status));
        if (bist_status & SISF_BIST_DONE) {
            if (bist_status & SISF_BIST_ERROR) {
                error = 1;
                *biststatus1 = si_corereg(sih,  si_coreidx(&sii->pub), 12, 0, 0);
                *biststatus2 = si_corereg(sih,  si_coreidx(&sii->pub), 16, 0, 0);
            }
        }
        /* stop the phy pll */
        pmu_ctrl = si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, 0, 0);
        pmu_ctrl &= ~0x10000;
        si_corereg(sih, si_coreidx(&sii->pub), 0x1e8, ~0, pmu_ctrl);
    }

    /* remove the resource mask */
    si_corereg(sih, 0, OFFSETOF(chipcregs_t, max_res_mask), ~0, max_res_mask);

    /* Return to previous state and core */
    if (!wasup)
        si_core_disable(sih, 0);

    /* Return to previous state and core */
    si_setcoreidx(sih, origidx);
done:
    INTR_RESTORE(sii, intr_val);
    return error;
}
Exemplo n.º 12
0
void
si_core_tofixup(si_t *sih)
{
	if (CHIPTYPE(sih->socitype) == SOCI_SB)
		sb_core_tofixup(sih);
}
Exemplo n.º 13
0
static si_info_t *
si_doattach(si_info_t *sii, uint devid, osl_t *osh, void *regs,
                       uint bustype, void *sdh, char **vars, uint *varsz)
{
	struct si_pub *sih = &sii->pub;
	uint32 w, savewin;
	chipcregs_t *cc;
	char *pvars = NULL;
	uint origidx;

	ASSERT(GOODREGS(regs));

	bzero((uchar*)sii, sizeof(si_info_t));


	{
		if (NULL == (common_info_alloced = (void *)MALLOC(osh, sizeof(si_common_info_t)))) {
			SI_ERROR(("si_doattach: malloc failed! malloced %dbytes\n", MALLOCED(osh)));
			return (NULL);
		}
		bzero((uchar*)(common_info_alloced), sizeof(si_common_info_t));
	}
	sii->common_info = (si_common_info_t *)common_info_alloced;
	sii->common_info->attach_count++;

	savewin = 0;

	sih->buscoreidx = BADIDX;

	sii->curmap = regs;
	sii->sdh = sdh;
	sii->osh = osh;


	/* find Chipcommon address */
	if (bustype == PCI_BUS) {
		savewin = OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(uint32));
		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
			savewin = SI_ENUM_BASE;
		OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE);
		cc = (chipcregs_t *)regs;
	} else
	if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
		cc = (chipcregs_t *)sii->curmap;
	} else {
		cc = (chipcregs_t *)REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
	}

	sih->bustype = bustype;
	if (bustype != BUSTYPE(bustype)) {
		SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n",
			bustype, BUSTYPE(bustype)));
		return NULL;
	}

	/* bus/core/clk setup for register access */
	if (!si_buscore_prep(sii, bustype, devid, sdh)) {
		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", bustype));
		return NULL;
	}

	/* ChipID recognition.
	 *   We assume we can read chipid at offset 0 from the regs arg.
	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
	 *   some way of recognizing them needs to be added here.
	 */
	w = R_REG(osh, &cc->chipid);
	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
	/* Might as wll fill in chip id rev & pkg */
	sih->chip = w & CID_ID_MASK;
	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
	if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chippkg != BCM4329_289PIN_PKG_ID))
		sih->chippkg = BCM4329_182PIN_PKG_ID;
	sih->issim = IS_SIM(sih->chippkg);

	/* scan for cores */
	if (CHIPTYPE(sii->pub.socitype) == SOCI_SB) {
		SI_MSG(("Found chip type SB (0x%08x)\n", w));
		sb_scan(&sii->pub, regs, devid);
	} else if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) {
		SI_MSG(("Found chip type AI (0x%08x)\n", w));
		/* pass chipc address instead of original core base */
		ai_scan(&sii->pub, (void *)cc, devid);
	} else {
		SI_ERROR(("Found chip of unkown type (0x%08x)\n", w));
		return NULL;
	}
	/* no cores found, bail out */
	if (sii->numcores == 0) {
		SI_ERROR(("si_doattach: could not find any cores\n"));
		return NULL;
	}
	/* bus/core/clk setup */
	origidx = SI_CC_IDX;
	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
		return NULL;
	}

	pvars = NULL;



		if (sii->pub.ccrev >= 20) {
			cc = (chipcregs_t *)si_setcore(sih, CC_CORE_ID, 0);
			W_REG(osh, &cc->gpiopullup, 0);
			W_REG(osh, &cc->gpiopulldown, 0);
			si_setcoreidx(sih, origidx);
		}

		/* Skip PMU initialization from the Dongle Host.
		 * Firmware will take care of it when it comes up.
		 */



	return (sii);
}