static void
brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
			struct chip_info *ci, u16 coreid)
{
	u32 regdata;
	u8 idx;

	idx = brcmf_sdio_chip_getinfidx(ci, coreid);

	/*
	 * Must do the disable sequence first to work for
	 * arbitrary current core state.
	 */
	brcmf_sdio_sb_coredisable(sdiodev, ci, coreid);

	/*
	 * Now do the initialization sequence.
	 * set reset while enabling the clock and
	 * forcing them on throughout the core
	 */
	brcmf_sdcard_reg_write(sdiodev,
			CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
			SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET);
	regdata = brcmf_sdcard_reg_read(sdiodev,
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
	udelay(1);

	/* clear any serror */
	regdata = brcmf_sdcard_reg_read(sdiodev,
				CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4);
	if (regdata & SSB_TMSHIGH_SERR)
		brcmf_sdcard_reg_write(sdiodev,
			CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0);

	regdata = brcmf_sdcard_reg_read(sdiodev,
				CORE_SB(ci->c_inf[idx].base, sbimstate), 4);
	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
		brcmf_sdcard_reg_write(sdiodev,
			CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
			regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO));

	/* clear reset and allow it to propagate throughout the core */
	brcmf_sdcard_reg_write(sdiodev,
		CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
		SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
	regdata = brcmf_sdcard_reg_read(sdiodev,
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
	udelay(1);

	/* leave clock enabled */
	brcmf_sdcard_reg_write(sdiodev,
			       CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
			       4, SSB_TMSLOW_CLOCK);
	regdata = brcmf_sdcard_reg_read(sdiodev,
				CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
	udelay(1);
}
Example #2
0
static void
brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
			struct brcmf_chip *ci, u16 coreid,  u32 pre_resetbits,
			u32 in_resetbits, u32 post_resetbits)
{
	u32 regdata;
	u8 idx;

	idx = brcmf_sdio_chip_getinfidx(ci, coreid);
	if (idx == BRCMF_MAX_CORENUM)
		return;

	/*
	 * Must do the disable sequence first to work for
	 * arbitrary current core state.
	 */
	brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits,
				  in_resetbits);

	/*
	 * Now do the initialization sequence.
	 * set reset while enabling the clock and
	 * forcing them on throughout the core
	 */
	brcmf_sdiod_regwl(sdiodev,
			  CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
			  SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
			  NULL);
	regdata = brcmf_sdiod_regrl(sdiodev,
				    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
				    NULL);
	udelay(1);

	/* clear any serror */
	regdata = brcmf_sdiod_regrl(sdiodev,
				    CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
				    NULL);
	if (regdata & SSB_TMSHIGH_SERR)
		brcmf_sdiod_regwl(sdiodev,
				  CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
				  0, NULL);

	regdata = brcmf_sdiod_regrl(sdiodev,
				    CORE_SB(ci->c_inf[idx].base, sbimstate),
				    NULL);
	if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
		brcmf_sdiod_regwl(sdiodev,
				  CORE_SB(ci->c_inf[idx].base, sbimstate),
				  regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
				  NULL);

	/* clear reset and allow it to propagate throughout the core */
	brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
			  SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
	regdata = brcmf_sdiod_regrl(sdiodev,
				    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
				    NULL);
	udelay(1);

	/* leave clock enabled */
	brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
			  SSB_TMSLOW_CLOCK, NULL);
	regdata = brcmf_sdiod_regrl(sdiodev,
				    CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
				    NULL);
	udelay(1);
}