Пример #1
0
/* When the calibration overflows, it means the fine trim code
 * has reached 0x1F, but the clock is still too fast.  Thus,
 * software must increase the coarse trim code by 1 */
static void timer_sof_calibration_overflow_int(void)
{
	unsigned coarseTrimValue = GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM);
	unsigned max;

	CPRINTS("%s: 0x%02x", __func__, coarseTrimValue);

	if (GREAD_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, MAX_TRIM_SEL))
		max = 0x1f;
	else
		max = 0xff;

	if (coarseTrimValue < max)
		GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue + 1;

	GREG32(XO, DXO_INT_STATE) =
		GC_XO_DXO_INT_STATE_SLOW_CALIB_OVERFLOW_MASK;
}
Пример #2
0
/*
 * Push data to the SPS TX FIFO
 * @param data Pointer to 8-bit data
 * @param data_size Number of bytes to transmit
 * @return : actual number of bytes placed into tx fifo
 */
int sps_transmit(uint8_t *data, size_t data_size)
{
	volatile uint32_t *sps_tx_fifo;
	uint32_t rptr;
	uint32_t wptr;
	uint32_t fifo_room;
	int bytes_sent;
	int inst = 0;

	if (GREAD_FIELD_I(SPS, inst, ISTATE, TXFIFO_EMPTY))
		tx_empty_count++; /* Inside packet this means underrun. */

	sps_tx_fifo = (volatile uint32_t *)SPS_TX_FIFO_BASE_ADDR;

	wptr = GREG32_I(SPS, inst, TXFIFO_WPTR);
	rptr = GREG32_I(SPS, inst, TXFIFO_RPTR);
	fifo_room = (rptr - wptr - 1) & SPS_FIFO_MASK;

	if (fifo_room < data_size) {
		bytes_sent = fifo_room;
		data_size = fifo_room;
	} else {
		bytes_sent = data_size;
	}

	sps_tx_fifo += (wptr & SPS_FIFO_MASK) / sizeof(*sps_tx_fifo);

	while (data_size) {

		if ((wptr & 3) || (data_size < 4) || ((uintptr_t)data & 3)) {
			/*
			 * Either we have less then 4 bytes to send, or one of
			 * the pointers is not 4 byte aligned. Need to go byte
			 * by byte.
			 */
			uint32_t fifo_contents;
			int bit_shift;

			fifo_contents = *sps_tx_fifo;
			do {
				/*
				 * CR50 SPS controller does not allow byte
				 * accesses for writes into the FIFO, so read
				 * modify/write is requred. Tracked uder
				 * http://b/20894727
				 */
				bit_shift = 8 * (wptr & 3);
				fifo_contents &= ~(0xff << bit_shift);
				fifo_contents |=
					(((uint32_t)(*data++)) << bit_shift);
				data_size--;
				wptr++;

			} while (data_size && (wptr & 3));

			*sps_tx_fifo++ = fifo_contents;
		} else {
			/*
			 * Both fifo wptr and data are aligned and there is
			 * plenty to send.
			 */
			*sps_tx_fifo++ = *((uint32_t *)data);
			data += 4;
			data_size -= 4;
			wptr += 4;
		}
		GREG32_I(SPS, inst, TXFIFO_WPTR) = wptr & SPS_FIFO_PTR_MASK;

		/* Make sure FIFO pointer wraps along with the index. */
		if (!(wptr & SPS_FIFO_MASK))
			sps_tx_fifo = (volatile uint32_t *)
				SPS_TX_FIFO_BASE_ADDR;
	}

	/*
	 * Start TX if necessary. This happens after FIFO is primed, which
	 * helps aleviate TX underrun problems but introduces delay before
	 * data starts coming out.
	 */
	if (!GREAD_FIELD(SPS, FIFO_CTRL, TXFIFO_EN))
		GWRITE_FIELD(SPS, FIFO_CTRL, TXFIFO_EN, 1);

	sps_tx_count += bytes_sent;
	return bytes_sent;
}