Esempio n. 1
0
/* initialize PMU resources */
void si_pmu_res_init(struct si_pub *sih)
{
	chipcregs_t *cc;
	uint origidx;
	u32 min_mask = 0, max_mask = 0;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	/* Determine min/max rsrc masks */
	si_pmu_res_masks(sih, &min_mask, &max_mask);

	/* It is required to program max_mask first and then min_mask */

	/* Program max resource mask */

	if (max_mask)
		W_REG(&cc->max_res_mask, max_mask);

	/* Program min resource mask */

	if (min_mask)
		W_REG(&cc->min_res_mask, min_mask);

	/* Add some delay; allow resources to come up and settle. */
	mdelay(2);

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Esempio n. 2
0
void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
{
	chipcregs_t *cc;
	uint origidx;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Esempio n. 3
0
u32 si_pmu_measure_alpclk(struct si_pub *sih)
{
	chipcregs_t *cc;
	uint origidx;
	u32 alp_khz;

	if (sih->pmurev < 10)
		return 0;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
		u32 ilp_ctr, alp_hz;

		/*
		 * Enable the reg to measure the freq,
		 * in case it was disabled before
		 */
		W_REG(&cc->pmu_xtalfreq,
		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);

		/* Delay for well over 4 ILP clocks */
		udelay(1000);

		/* Read the latched number of ALP ticks per 4 ILP ticks */
		ilp_ctr =
		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;

		/*
		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
		 * bit to save power
		 */
		W_REG(&cc->pmu_xtalfreq, 0);

		/* Calculate ALP frequency */
		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;

		/*
		 * Round to nearest 100KHz, and at
		 * the same time convert to KHz
		 */
		alp_khz = (alp_hz + 50000) / 100000 * 100;
	} else
		alp_khz = 0;

	/* Return to original core */
	ai_setcoreidx(sih, origidx);

	return alp_khz;
}
Esempio n. 4
0
/* initialize PMU */
void si_pmu_init(struct si_pub *sih)
{
	chipcregs_t *cc;
	uint origidx;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	if (sih->pmurev == 1)
		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
	else if (sih->pmurev >= 2)
		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Esempio n. 5
0
void *
si_setcoreidx(si_t *sih, uint coreidx)
{
	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;
	}
}
Esempio n. 6
0
u32 si_pmu_ilp_clock(struct si_pub *sih)
{
	static u32 ilpcycles_per_sec;

	if (!PMUCTL_ENAB(sih))
		return ILP_CLOCK;

	if (ilpcycles_per_sec == 0) {
		u32 start, end, delta;
		u32 origidx = ai_coreidx(sih);
		chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
		start = R_REG(&cc->pmutimer);
		mdelay(ILP_CALC_DUR);
		end = R_REG(&cc->pmutimer);
		delta = end - start;
		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
		ai_setcoreidx(sih, origidx);
	}

	return ilpcycles_per_sec;
}
Esempio n. 7
0
/* initialize PLL */
void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
{
	chipcregs_t *cc;
	uint origidx;

	/* Remember original core before switch to chipc */
	origidx = ai_coreidx(sih);
	cc = ai_setcoreidx(sih, SI_CC_IDX);

	switch (sih->chip) {
	case BCM4313_CHIP_ID:
	case BCM43224_CHIP_ID:
	case BCM43225_CHIP_ID:
		/* ??? */
		break;
	default:
		break;
	}

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Esempio n. 8
0
/* initialize PMU chip controls and other chip level stuff */
void si_pmu_chip_init(struct si_pub *sih)
{
	uint origidx;

	/* Gate off SPROM clock and chip select signals */
	si_pmu_sprom_enable(sih, false);

	/* Remember original core */
	origidx = ai_coreidx(sih);

	/* Return to original core */
	ai_setcoreidx(sih, origidx);
}
Esempio 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;
	}
}