Example #1
0
static void connect_pinmux(uint32_t signal, uint32_t dio, uint16_t flags)
{
	if (FIELD_IS_FUNC(signal)) {
		/* Connect peripheral function to DIO */
		if (flags & DIO_OUTPUT) {
			/* drive DIO from peripheral */
			DIO_SEL_REG(dio) = PERIPH_FUNC(signal);
		}

		if (flags & DIO_INPUT) {
			/* drive peripheral from DIO */
			PERIPH_SEL_REG(signal) = DIO_FUNC(dio);
			/* enable digital input */
			REG_WRITE_MLV(DIO_CTL_REG(dio), DIO_CTL_IE_MASK,
				      DIO_CTL_IE_LSB, 1);
		}
	} else {
		/* Connect GPIO to DIO */
		const struct gpio_info *g = gpio_list + FIELD_GET_GPIO(signal);
		int bitnum = GPIO_MASK_TO_NUM(g->mask);

		if ((g->flags & GPIO_OUTPUT) || (flags & DIO_OUTPUT)) {
			/* drive DIO output from GPIO */
			DIO_SEL_REG(dio) = GET_GPIO_FUNC(g->port, bitnum);
		}

		if ((g->flags & GPIO_INPUT) || (flags & DIO_INPUT)) {
			/* drive GPIO input from DIO */
			GET_GPIO_SEL_REG(g->port, bitnum) = DIO_FUNC(dio);
			/* enable digital input */
			REG_WRITE_MLV(DIO_CTL_REG(dio), DIO_CTL_IE_MASK,
				      DIO_CTL_IE_LSB, 1);
		}
	}
}
Example #2
0
File: uart.c Project: thehobn/ec
void uart_tx_stop(void)
{
	/* Disable the TX interrupt */
	REG_WRITE_MLV(GR_UART_ICTRL(0), GC_UART_ICTRL_TX_MASK,
		      GC_UART_ICTRL_TX_LSB, 0);

	/* Re-allow deep sleep */
	enable_sleep(SLEEP_MASK_UART);
}
Example #3
0
static void update_prescaler(void)
{
	/*
	 * We want the timer to tick every microsecond, but we can only divide
	 * PCLK by 1, 16, or 256. We're targeting 30MHz, so we'll just let it
	 * run at 1:1.
	 */
	REG_WRITE_MLV(GR_TIMEHS_CONTROL(0, 1),
		      GC_TIMEHS_TIMER1CONTROL_PRE_MASK,
		      GC_TIMEHS_TIMER1CONTROL_PRE_LSB, 0);
	REG_WRITE_MLV(GR_TIMEHS_CONTROL(0, 2),
		      GC_TIMEHS_TIMER1CONTROL_PRE_MASK,
		      GC_TIMEHS_TIMER1CONTROL_PRE_LSB, 0);

	/*
	 * We're not yet doing anything to detect the current frequency, we're
	 * just hard-coding it. We're also assuming the clock rate is an
	 * integer multiple of MHz.
	 */
	clock_mul_factor = 30;			/* NOTE: prototype board */
	clock_div_factor = 0xffffffff / clock_mul_factor;
}
Example #4
0
void gpio_pre_init(void)
{
	const struct gpio_info *g = gpio_list;
	const struct gpio_alt_func *af = gpio_alt_funcs;

	int i;

	/* Enable clocks */
	REG_WRITE_MLV(GR_PMU_PERICLKSET0,
		      GC_PMU_PERICLKSET0_DGPIO0_CLK_MASK,
		      GC_PMU_PERICLKSET0_DGPIO0_CLK_LSB, 1);
	REG_WRITE_MLV(GR_PMU_PERICLKSET0,
		      GC_PMU_PERICLKSET0_DGPIO1_CLK_MASK,
		      GC_PMU_PERICLKSET0_DGPIO1_CLK_LSB, 1);

	/* Set up the pinmux */
	for (i = 0; i < gpio_alt_funcs_count; i++, af++)
		connect_pinmux(af->port, af->mask, af->flags);

	/* Set up ARM core GPIOs */
	for (i = 0; i < GPIO_COUNT; i++, g++)
		if (g->mask && !(g->flags & GPIO_DEFAULT))
			gpio_set_flags_by_mask(g->port, g->mask, g->flags);
}
Example #5
0
File: uart.c Project: thehobn/ec
void uart_tx_start(void)
{
	/* If interrupt is already enabled, nothing to do */
	if (GR_UART_ICTRL(0) & GC_UART_ICTRL_TX_MASK)
		return;

	/* Do not allow deep sleep while transmit in progress */
	disable_sleep(SLEEP_MASK_UART);

	/*
	 * Re-enable the transmit interrupt, then forcibly trigger the
	 * interrupt.  This works around a hardware problem with the
	 * UART where the FIFO only triggers the interrupt when its
	 * threshold is _crossed_, not just met.
	 */
	/* TODO(crosbug.com/p/33819): Do we need this hack here? Find out. */
	REG_WRITE_MLV(GR_UART_ICTRL(0), GC_UART_ICTRL_TX_MASK,
		      GC_UART_ICTRL_TX_LSB, 1);
	task_trigger_irq(GC_IRQNUM_UART0_TXINT);
}
Example #6
0
File: clock.c Project: longsleep/ec
static void switch_osc_to_rc_trim(void)
{
	unsigned trimmed;
	unsigned saved_trim, fuse_trim, default_trim;
	unsigned trim_code;

	/* check which clock we are running on */
	unsigned osc_sel = GR_PMU_OSC_SELECT_STAT;

	if (osc_sel == GC_PMU_OSC_SELECT_RC_TRIM) {
		/* already using the rc_trim so nothing to do here */
		/* make sure the hold signal is set for future power downs */
		GR_PMU_OSC_HOLD_SET = 0x1;
		return;
	}

	/* Turn on DXO clock so we can write in the trim code in */
	clock_on_xo0();

	/* disable the RC_TRIM Clock */
	REG_WRITE_MLV(GR_PMU_OSC_CTRL,
		      GC_PMU_OSC_CTRL_RC_TRIM_READYB_MASK,
		      GC_PMU_OSC_CTRL_RC_TRIM_READYB_LSB, 1);

	/* power up the clock if not already powered up */
	GR_PMU_CLRDIS = 1 << GC_PMU_SETDIS_RC_TRIM_LSB;

	/* Try to find the trim code */
	saved_trim = GR_XO_OSC_RC_STATUS;
	fuse_trim = GR_PMU_FUSE_RD_RC_OSC_26MHZ;
	default_trim = GR_XO_OSC_RC;

	/* Check for the trim code in the always-on domain before looking at
	 * the fuse */
	if (saved_trim & GC_XO_OSC_RC_STATUS_EN_MASK) {
		trim_code = (saved_trim & GC_XO_OSC_RC_STATUS_TRIM_MASK)
		    >> GC_XO_OSC_RC_STATUS_TRIM_LSB;
		trimmed = 1;
	} else if (fuse_trim & GC_PMU_FUSE_RD_RC_OSC_26MHZ_EN_MASK) {