示例#1
0
文件: qe.c 项目: mobilipia/iods
/* Program the BRG to the given sampling rate and multiplier
 *
 * @brg: the BRG, QE_BRG1 - QE_BRG16
 * @rate: the desired sampling rate
 * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
 * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
 * then 'multiplier' should be 8.
 */
int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
{
	u32 divisor, tempval;
	u32 div16 = 0;

	if ((brg < QE_BRG1) || (brg > QE_BRG16))
		return -EINVAL;

	divisor = get_brg_clk() / (rate * multiplier);

	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
		div16 = QE_BRGC_DIV16;
		divisor /= 16;
	}

	/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
	   that the BRG divisor must be even if you're not using divide-by-16
	   mode. */
	if (!div16 && (divisor & 1))
		divisor++;

	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
		QE_BRGC_ENABLE | div16;

	out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);

	return 0;
}
示例#2
0
文件: qe.c 项目: 3sOx/asuswrt-merlin
/* This function is used by UARTS, or anything else that uses a 16x
 * oversampled clock.
 */
void qe_setbrg(u32 brg, u32 rate)
{
	volatile u32 *bp;
	u32 divisor, tempval;
	int div16 = 0;

	bp = &qe_immr->brg.brgc[brg];

	divisor = (get_brg_clk() / rate);
	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
		div16 = 1;
		divisor /= 16;
	}

	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE;
	if (div16)
		tempval |= QE_BRGC_DIV16;

	out_be32(bp, tempval);
}