Esempio n. 1
0
int __hw_clock_source_init(uint32_t start_t)
{
	/*
	 * 1. Use ITIM16-1 as internal time reading
	 * 2. Use ITIM16-2 for event handling
	 */

	/* Enable clock for ITIM peripheral */
	clock_enable_peripheral(CGC_OFFSET_TIMER, CGC_TIMER_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	/* init tick & event timer first */
	init_hw_timer(ITIM32,  ITIM_SOURCE_CLOCK_APB2);
	init_hw_timer(ITIM_EVENT_NO, ITIM_SOURCE_CLOCK_32K);

	/* Set initial prescaler */
	update_prescaler();

	/*
	 * Override the count with the start value now that counting has
	 * started.
	 */
	hw_clock_source_set_preload(start_t, 1);

	/* Enable interrupt of ITIM */
	task_enable_irq(NPCX_IRQ_ITIM32);

	return NPCX_IRQ_ITIM32;
}
Esempio n. 2
0
void gpio_set_alternate_function(uint32_t port, uint32_t mask, int func)
{
	int port_index = find_gpio_port_index(port);
	int cgmask;

	/* Ignore (do nothing for) invalid port values */
	if (port_index < 0)
		return;

	/* Enable the GPIO port in run and sleep. */
	cgmask = 1 << port_index;
	clock_enable_peripheral(CGC_OFFSET_GPIO, cgmask,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	if (func >= 0) {
		int pctlmask = 0;
		int i;
		/* Expand mask from bits to nibbles */
		for (i = 0; i < 8; i++) {
			if (mask & (1 << i))
				pctlmask |= 1 << (4 * i);
		}

		LM4_GPIO_PCTL(port) =
			(LM4_GPIO_PCTL(port) & ~(pctlmask * 0xf)) |
			(pctlmask * func);
		LM4_GPIO_AFSEL(port) |= mask;
	} else {
		LM4_GPIO_AFSEL(port) &= ~mask;
	}
}
Esempio n. 3
0
/**
 * SPI initial.
 *
 * @param none
 * @return none
 */
static void spi_init(void)
{
	int i;
	/* Enable clock for SPI peripheral */
	clock_enable_peripheral(CGC_OFFSET_SPI, CGC_SPI_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	/* Disabling spi module */
	for (i = 0; i < spi_devices_used; i++)
		spi_enable(spi_devices[i].port, 0);

	/* Disabling spi irq */
	CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_EIR);
	CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_EIW);

	/* Setting clocking mode to normal mode */
	CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SCM);
	/* Setting 8bit mode transfer */
	CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_MOD);
	/* Set core clock division factor in order to obtain the spi clock */
	spi_freq_changed();

	/* We emit zeros in idle (default behaivor) */
	CLEAR_BIT(NPCX_SPI_CTL1, NPCX_SPI_CTL1_SCIDL);

	CPRINTS("nSPI_COMP=%x", IS_BIT_SET(NPCX_STRPST, NPCX_STRPST_SPI_COMP));
	CPRINTS("SPI_SP_SEL=%x", IS_BIT_SET(NPCX_DEV_CTL4,
			NPCX_DEV_CTL4_SPI_SP_SEL));
	/* Cleaning junk data in the buffer */
	clear_databuf();
}
Esempio n. 4
0
static void sspi_init(void)
{
	int i;

	clock_enable_peripheral(CGC_OFFSET_SSPI, 0, 0);
	sspi_frequency(sspi_clk_8mhz);

	/*
	 * bit[5:3] Byte Width (BYTEWIDTH)
	 * 000b: 8-bit transmission
	 * 001b: 1-bit transmission
	 * 010b: 2-bit transmission
	 * 011b: 3-bit transmission
	 * 100b: 4-bit transmission
	 * 101b: 5-bit transmission
	 * 110b: 6-bit transmission
	 * 111b: 7-bit transmission
	 *
	 * bit[1] Blocking selection
	 */
	IT83XX_SSPI_SPICTRL2 |= 0x02;

	for (i = 0; i < spi_devices_used; i++)
		/* Disabling spi module */
		spi_enable(spi_devices[i].port, 0);
}
Esempio n. 5
0
File: pwm.c Progetto: thehobn/ec
/**
 * PWM initial.
 *
 * @param none
 * @return none
 */
static void pwm_init(void)
{
	int i;

#ifdef CONFIG_PWM_DSLEEP

	/* Enable the PWM module and delay a few clocks */
	clock_enable_peripheral(CGC_OFFSET_PWM, CGC_PWM_MASK, CGC_MODE_ALL);
#else
	/* Enable the PWM module and delay a few clocks */
	clock_enable_peripheral(CGC_OFFSET_PWM, CGC_PWM_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
#endif

	for (i = 0; i < PWM_CH_COUNT; i++)
		pwm_config(i);
}
Esempio n. 6
0
/**
 * PWM initial.
 *
 * @param none
 * @return none
 */
static void pwm_init(void)
{
	int i;

	/* Enable the PWM module and delay a few clocks */
	clock_enable_peripheral(CGC_OFFSET_PWM, CGC_PWM_MASK, CGC_MODE_ALL);

	for (i = 0; i < PWM_CH_COUNT; i++)
		pwm_config(i);
}
Esempio n. 7
0
static void adc_init(void)
{
	int i;

	/* Configure GPIOs */
	configure_gpio();

	/*
	 * Temporarily enable the PLL when turning on the clock to the ADC
	 * module, to work around chip errata (10.4).  No need to notify
	 * other modules; the PLL isn't enabled long enough to matter.
	 */
	clock_enable_pll(1, 0);

	/* Enable ADC0 module in run and sleep modes. */
	clock_enable_peripheral(CGC_OFFSET_ADC, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	/*
	 * Use external voltage references (VREFA+, VREFA-) instead of
	 * VDDA and GNDA.
	 */
	LM4_ADC_ADCCTL = 0x01;

	/* Use internal oscillator */
	LM4_ADC_ADCCC = 0x1;

	/* Disable the PLL now that the ADC is using the internal oscillator */
	clock_enable_pll(0, 0);

	/* No tasks waiting yet */
	for (i = 0; i < LM4_ADC_SEQ_COUNT; i++)
		task_waiting_on_ss[i] = TASK_ID_INVALID;

	/* Enable IRQs */
	task_enable_irq(LM4_IRQ_ADC0_SS0);
	task_enable_irq(LM4_IRQ_ADC0_SS1);
	task_enable_irq(LM4_IRQ_ADC0_SS2);
	task_enable_irq(LM4_IRQ_ADC0_SS3);

	/* 2**6 = 64x oversampling */
	LM4_ADC_ADCSAC = 6;

	/* Initialize ADC sequencer */
	for (i = 0; i < ADC_CH_COUNT; ++i)
		adc_configure(adc_channels + i);

	/* Disable ADC0 module until it is needed to conserve power. */
	clock_disable_peripheral(CGC_OFFSET_ADC, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
}
Esempio n. 8
0
static void peci_init(void)
{
	int i;

	/* Enable the PECI module in run and sleep modes. */
	clock_enable_peripheral(CGC_OFFSET_PECI, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	/* Configure GPIOs */
	gpio_config_module(MODULE_PECI, 1);

	/* Set initial clock frequency */
	peci_freq_changed();

	/* Initialize temperature reading buffer to a sane value. */
	for (i = 0; i < TEMP_AVG_LENGTH; ++i)
		temp_vals[i] = 300; /* 27 C */
}
Esempio n. 9
0
int adc_read_channel(enum adc_channel ch)
{
	const struct adc_t *adc = adc_channels + ch;
	static uint32_t ch_busy_mask;
	static struct mutex adc_clock;
	int rv;

	/*
	 * TODO(crbug.com/314121): Generalize ADC reads such that any task can
	 * trigger a read of any channel.
	 */

	/*
	 * Enable ADC clock and set a bit in ch_busy_mask to signify that this
	 * channel is busy. Note, this function may be called from multiple
	 * tasks, but each channel may be read by only one task. If assert
	 * fails, then it means multiple tasks are trying to read same channel.
	 */
	mutex_lock(&adc_clock);
	ASSERT(!(ch_busy_mask & (1UL << ch)));
	clock_enable_peripheral(CGC_OFFSET_ADC, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
	ch_busy_mask |= (1UL << ch);
	mutex_unlock(&adc_clock);

	rv = flush_and_read(adc->sequencer);

	/*
	 * If no ADC channels are busy, then disable ADC clock to conserve
	 * power.
	 */
	mutex_lock(&adc_clock);
	ch_busy_mask &= ~(1UL << ch);
	if (!ch_busy_mask)
		clock_disable_peripheral(CGC_OFFSET_ADC, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
	mutex_unlock(&adc_clock);

	if (rv == ADC_READ_ERROR)
		return ADC_READ_ERROR;

	return rv * adc->factor_mul / adc->factor_div + adc->shift;
}
Esempio n. 10
0
static void i2c_init(void)
{
	int i, p, p_ch;

	/* Configure GPIOs */
	gpio_config_module(MODULE_I2C, 1);

#ifdef CONFIG_IT83XX_SMCLK2_ON_GPC7
	/* bit7, 0: SMCLK2 is located on GPF6, 1: SMCLK2 is located on GPC7 */
	IT83XX_GPIO_GRC7 |= 0x80;
#endif

	/* Enable I2C function. */
	for (i = 0; i < i2c_ports_used; i++) {
		/* I2c port mapping. */
		p = i2c_ports[i].port;

		clock_enable_peripheral(i2c_ctrl_regs[p].clock_gate, 0, 0);

		if (p < I2C_STANDARD_PORT_COUNT) {
			/*
			 * bit0, The SMBus host interface is enabled.
			 * bit1, Enable to communicate with I2C device
			 *        and support I2C-compatible cycles.
			 * bit4, This bit controls the reset mechanism
			 *        of SMBus master to handle the SMDAT
			 *        line low if 25ms reg timeout.
			 */
			IT83XX_SMB_HOCTL2(p) = 0x11;
			/*
			 * bit1, Kill SMBus host transaction.
			 * bit0, Enable the interrupt for the master interface.
			 */
			IT83XX_SMB_HOCTL(p) = 0x03;
			IT83XX_SMB_HOCTL(p) = 0x01;
			/* W/C host status register */
			IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT;
			IT83XX_SMB_HOCTL2(p) = 0x00;
		} else {
			/* Shift register */
			p_ch = i2c_ch_reg_shift(p);
			switch (p) {
			case IT83XX_I2C_CH_D:
				#ifndef CONFIG_UART_HOST
				/* Enable SMBus D channel */
				IT83XX_GPIO_GRC2 |= 0x20;
				#endif
				break;
			case IT83XX_I2C_CH_E:
				/* Enable SMBus E channel */
				IT83XX_GCTRL_PMER1 |= 0x01;
				break;
			case IT83XX_I2C_CH_F:
				/* Enable SMBus F channel */
				IT83XX_GCTRL_PMER1 |= 0x02;
				break;
			}
			/* Software reset */
			IT83XX_I2C_DHTR(p_ch) |= 0x80;
			IT83XX_I2C_DHTR(p_ch) &= 0x7F;

			/* State reset and hardware reset */
			IT83XX_I2C_CTR(p_ch) = 0x11;
			IT83XX_I2C_CTR(p_ch) = 0x00;

			/* Set time out condition */
			IT83XX_I2C_TOR(p_ch) = 0xFF;
			IT83XX_I2C_T_BUF(p_ch) = 0x3F;

			/*
			* bit3, Acknowledge
			* bit5, Master mode
			* bit6, Interrupt enable
			*/
			IT83XX_I2C_CTR(p_ch) = 0x68;

			/*
			* bit1, Module enable
			* bit4-6 Support number of devices
			*/
			IT83XX_I2C_CTR1(p_ch) = 0x00;
		}
		pdata[i].task_waiting = TASK_ID_INVALID;
	}

	i2c_freq_changed();

	for (i = 0; i < I2C_PORT_COUNT; i++) {
		/* Use default timeout */
		i2c_set_timeout(i, 0);
	}
}
Esempio n. 11
0
static void lpc_init(void)
{
	/* Enable clock for LPC peripheral */
	clock_enable_peripheral(CGC_OFFSET_LPC, CGC_LPC_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
	/* Switching to LPC interface */
	NPCX_DEVCNT |= 0x04;
	/* Enable 4E/4F */
	if (!IS_BIT_SET(NPCX_MSWCTL1, 3)) {
		NPCX_HCBAL = 0x4E;
		NPCX_HCBAH = 0x0;
	}
	/* Clear Host Access Hold state */
	NPCX_SMC_CTL = 0xC0;

	/*
	 * Set alternative pin from GPIO to CLKRUN no matter SERIRQ is under
	 * continuous or quiet mode.
	 */
	SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_CLKRN_SL);

	/* Initialize Hardware for UART Host */
#if CONFIG_UART_HOST
	/* Init COMx LPC UART */
	/* FMCLK have to using 50MHz */
	NPCX_DEVALT(0xB) = 0xFF;
	/* Make sure Host Access unlock */
	CLEAR_BIT(NPCX_LKSIOHA, 2);
	/* Clear Host Access Lock Violation */
	SET_BIT(NPCX_SIOLV, 2);
#endif

	/* Don't stall SHM transactions */
	NPCX_SHM_CTL = NPCX_SHM_CTL & ~0x40;
	/* Semaphore and Indirect access disable */
	NPCX_SHCFG = 0xE0;
	/* Disable Protect Win1&2*/
	NPCX_WIN_WR_PROT(0) = 0;
	NPCX_WIN_WR_PROT(1) = 0;
	NPCX_WIN_RD_PROT(0) = 0;
	NPCX_WIN_RD_PROT(1) = 0;
	/* Open Win1 256 byte for Host CMD, Win2 256 for MEMMAP*/
	NPCX_WIN_SIZE = 0x88;
	NPCX_WIN_BASE(0) = (uint32_t)shm_mem_host_cmd;
	NPCX_WIN_BASE(1) = (uint32_t)shm_memmap;
	/* Write protect of Share memory */
	NPCX_WIN_WR_PROT(1) = 0xFF;

	/* Turn on PMC2 for Host Command usage */
	SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 0);
	SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 1);

	/*
	 * Set required control value (avoid setting HOSTWAIT bit at this stage)
	 */
	NPCX_SMC_CTL = NPCX_SMC_CTL&~0x7F;
	/* Clear status */
	NPCX_SMC_STS = NPCX_SMC_STS;
	/* Create mailbox */

	/*
	 * Init KBC
	 * Clear OBF status flag, PM1 IBF/OBE INT enable, IRQ11 enable,
	 * IBF(K&M) INT enable, OBE(K&M) empty INT enable ,
	 * OBF Mouse Full INT enable and OBF KB Full INT enable
	 */
	NPCX_HICTRL = 0xFF;

	/* Normally Polarity IRQ1,12,11 type (level + high) setting */
	NPCX_HIIRQC = 0x00;	/* Make sure to default */

	/*
	 * Init PORT80
	 * Enable Port80, Enable Port80 function & Interrupt & Read auto
	 */
	NPCX_DP80CTL = 0x29;
	SET_BIT(NPCX_GLUE_SDP_CTS, 3);
#if SUPPORT_P80_SEG
	SET_BIT(NPCX_GLUE_SDP_CTS, 0);
#endif

	lpc_task_enable_irq();

	/* Initialize host args and memory map to all zero */
	memset(lpc_host_args, 0, sizeof(*lpc_host_args));
	memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);

	/* We support LPC args and version 3 protocol */
	*(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) =
			EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
			EC_HOST_CMD_FLAG_VERSION_3;

	/* Restore event masks if needed */
	lpc_post_sysjump();

	/* Sufficiently initialized */
	init_done = 1;

	/* Update host events now that we can copy them to memmap */
	update_host_event_status();

	/*
	 * TODO: For testing LPC with Chromebox, please make sure LPC_CLK is
	 * generated before executing this function. EC needs LPC_CLK to access
	 * LPC register through SIB module. For Chromebook platform, this
	 * functionality should be done by BIOS or executed in hook function of
	 * HOOK_CHIPSET_STARTUP
	 */
#ifdef BOARD_NPCX_EVB
	/* initial IO port address via SIB-write modules */
	lpc_host_register_init();
#else
	/* Initialize LRESET# interrupt */
	/* Set detection mode to edge */
	CLEAR_BIT(NPCX_WKMOD(MIWU_TABLE_0, MIWU_GROUP_5), 7);
	/* Handle interrupting on rising edge */
	CLEAR_BIT(NPCX_WKAEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7);
	SET_BIT(NPCX_WKEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7);
	/* Enable wake-up input sources */
	SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7);
#endif
}
Esempio n. 12
0
static void i2c_init(void)
{
	int i;
	/* Configure pins from GPIOs to I2Cs */
	gpio_config_module(MODULE_I2C, 1);

	/* Enable clock for I2C peripheral */
	clock_enable_peripheral(CGC_OFFSET_I2C, CGC_I2C_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	/* Set I2C freq */
	i2c_freq_changed();
	/*
	 * initialize smb status and register
	 */
	for (i = 0; i < i2c_ports_used; i++) {
		int port = i2c_ports[i].port;
		int ctrl = i2c_port_to_controller(port);
		volatile struct i2c_status *p_status = i2c_stsobjs + ctrl;
		/* Configure pull-up for SMB interface pins */

		/* Enable 3.3V pull-up or turn to 1.8V support */
		if (port == NPCX_I2C_PORT0_0) {
#ifdef NPCX_I2C0_0_1P8V
			SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SC0_0_LV);
			SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SD0_0_LV);
#else
			SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
#endif
		} else if (port == NPCX_I2C_PORT0_1) {
#ifdef NPCX_I2C0_1_1P8V
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL0_SC0_1_LV);
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL0_SD0_1_LV);
#else
			SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 1));
#endif
		} else if (port == NPCX_I2C_PORT1) {
#ifdef NPCX_I2C1_1P8V
			SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SC1_0_LV);
			SET_BIT(NPCX_LV_GPIO_CTL0, NPCX_LV_GPIO_CTL0_SD1_0_LV);
#else
			SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
#endif
		} else if (port == NPCX_I2C_PORT2) {
#ifdef NPCX_I2C2_1P8V
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC2_0_LV);
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD2_0_LV);
#else
			SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
#endif
		} else if (port == NPCX_I2C_PORT3) {
#ifdef NPCX_I2C3_1P8V
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC3_0_LV);
			SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD3_0_LV);
#else
			SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(ctrl, 0));
#endif
		}

		/* Enable module - before configuring CTL1 */
		SET_BIT(NPCX_SMBCTL2(ctrl), NPCX_SMBCTL2_ENABLE);

		/* status init */
		p_status->oper_state = SMB_IDLE;

		/* Reset task ID */
		p_status->task_waiting = TASK_ID_INVALID;

		/* Enable event and error interrupts */
		task_enable_irq(i2c_irqs[ctrl]);

		/* Use default timeout. */
		i2c_set_timeout(port, 0);
	}
}
Esempio n. 13
0
static void lpc_init(void)
{
	/* Enable clock for LPC peripheral */
	clock_enable_peripheral(CGC_OFFSET_LPC, CGC_LPC_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
#ifdef CONFIG_ESPI
	/* Enable clock for eSPI peripheral */
	clock_enable_peripheral(CGC_OFFSET_ESPI, CGC_ESPI_MASK,
		CGC_MODE_RUN | CGC_MODE_SLEEP);
	/* Initialize eSPI IP */
	espi_init();
#else
	/* Switching to LPC interface */
	NPCX_DEVCNT |= 0x04;
#endif
	/* Enable 4E/4F */
	if (!IS_BIT_SET(NPCX_MSWCTL1, NPCX_MSWCTL1_VHCFGA)) {
		NPCX_HCBAL = 0x4E;
		NPCX_HCBAH = 0x0;
	}
	/* Clear Host Access Hold state */
	NPCX_SMC_CTL = 0xC0;

#ifndef CONFIG_ESPI
	/*
	 * Set alternative pin from GPIO to CLKRUN no matter SERIRQ is under
	 * continuous or quiet mode.
	 */
	SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_CLKRN_SL);
#endif

	/*
	 * Set pin-mux from GPIOs to SCL/SMI to make sure toggling SCIB/SMIB is
	 * valid if CONFIG_SCI_GPIO isn't defined. eSPI sends SMI/SCI through VW
	 * automatically by toggling them, too. It's unnecessary to set pin mux.
	 */
#if !defined(CONFIG_SCI_GPIO) && !defined(CONFIG_ESPI)
	SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_EC_SCI_SL);
	SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_SMI_SL);
#endif

	/* Initialize Hardware for UART Host */
#if CONFIG_UART_HOST
	/* Init COMx LPC UART */
	/* FMCLK have to using 50MHz */
	NPCX_DEVALT(0xB) = 0xFF;
	/* Make sure Host Access unlock */
	CLEAR_BIT(NPCX_LKSIOHA, 2);
	/* Clear Host Access Lock Violation */
	SET_BIT(NPCX_SIOLV, 2);
#endif

	/* Don't stall SHM transactions */
	NPCX_SHM_CTL = NPCX_SHM_CTL & ~0x40;
	/* Semaphore and Indirect access disable */
	NPCX_SHCFG = 0xE0;
	/* Disable Protect Win1&2*/
	NPCX_WIN_WR_PROT(0) = 0;
	NPCX_WIN_WR_PROT(1) = 0;
	NPCX_WIN_RD_PROT(0) = 0;
	NPCX_WIN_RD_PROT(1) = 0;
	/* Open Win1 256 byte for Host CMD, Win2 256 for MEMMAP*/
	NPCX_WIN_SIZE = 0x88;
	NPCX_WIN_BASE(0) = (uint32_t)shm_mem_host_cmd;
	NPCX_WIN_BASE(1) = (uint32_t)shm_memmap;
	/* Write protect of Share memory */
	NPCX_WIN_WR_PROT(1) = 0xFF;

	/* We support LPC args and version 3 protocol */
	*(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) =
			EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
			EC_HOST_CMD_FLAG_VERSION_3;

	/* Turn on PMC2 for Host Command usage */
	SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 0);
	SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 1);

	/*
	 * Set required control value (avoid setting HOSTWAIT bit at this stage)
	 */
	NPCX_SMC_CTL = NPCX_SMC_CTL&~0x7F;
	/* Clear status */
	NPCX_SMC_STS = NPCX_SMC_STS;

	/* Restore event masks if needed */
	lpc_post_sysjump();

	/* Create mailbox */

	/*
	 * Init KBC
	 * Clear OBF status flag,
	 * IBF(K&M) INT enable, OBE(K&M) empty INT enable ,
	 * OBF Mouse Full INT enable and OBF KB Full INT enable
	 */
	NPCX_HICTRL = 0x8F;
	/*
	 * Turn on enhance mode on PM channel-1,
	 * enable OBE/IBF core interrupt
	 */
	NPCX_HIPMCTL(PMC_ACPI) |= 0x83;
	/* Normally Polarity IRQ1,12 type (level + high) setting */
	NPCX_HIIRQC = 0x00;

	/*
	 * Init PORT80
	 * Enable Port80, Enable Port80 function & Interrupt & Read auto
	 */
#ifdef CONFIG_ESPI
	NPCX_DP80CTL = 0x2b;
#else
	NPCX_DP80CTL = 0x29;
#endif
	SET_BIT(NPCX_GLUE_SDP_CTS, 3);
#if SUPPORT_P80_SEG
	SET_BIT(NPCX_GLUE_SDP_CTS, 0);
#endif

	/*
	 * Use SMI/SCI postive polarity as default.
	 * Negative polarity must be enabled in the case that SMI/SCI is
	 * generated automatically by hardware. In current design,
	 * SMI/SCI is conntrolled by FW. Use postive polarity is more
	 * intuitive.
	 */
	CLEAR_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_SCIPOL);
	CLEAR_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIPOL);
	/* Set SMIB/SCIB to make sure SMI/SCI are high at init */
	NPCX_HIPMIC(PMC_ACPI) = NPCX_HIPMIC(PMC_ACPI)
			| (1 << NPCX_HIPMIC_SMIB) | (1 << NPCX_HIPMIC_SCIB);
#ifndef CONFIG_SCI_GPIO
	/*
	 * Allow SMI/SCI generated from PM module.
	 * Either hardware autimatically generates,
	 * or set SCIB/SMIB bit in HIPMIC register.
	 */
	SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SCIE);
	SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SMIE);
#endif
	lpc_task_enable_irq();

	/* Sufficiently initialized */
	init_done = 1;

	/* Update host events now that we can copy them to memmap */
	update_host_event_status();

	/*
	 * TODO: For testing LPC with Chromebox, please make sure LPC_CLK is
	 * generated before executing this function. EC needs LPC_CLK to access
	 * LPC register through SIB module. For Chromebook platform, this
	 * functionality should be done by BIOS or executed in hook function of
	 * HOOK_CHIPSET_STARTUP
	 */
#ifdef BOARD_NPCX_EVB
	/* initial IO port address via SIB-write modules */
	host_register_init();
#else
	/* Initialize LRESET# interrupt */
	/* Set detection mode to edge */
	CLEAR_BIT(NPCX_WKMOD(MIWU_TABLE_0, MIWU_GROUP_5), 7);
	/* Handle interrupting on any edge */
	SET_BIT(NPCX_WKAEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7);
	/* Enable wake-up input sources */
	SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7);
#endif
}
Esempio n. 14
0
File: lpc.c Progetto: thehobn/ec
static void lpc_init(void)
{
	/* Enable clock for LPC peripheral */
	clock_enable_peripheral(CGC_OFFSET_LPC, CGC_LPC_MASK,
			CGC_MODE_RUN | CGC_MODE_SLEEP);
	/* Switching to LPC interface */
	NPCX_DEVCNT |= 0x04;
	/* Enable 4E/4F */
	if (!IS_BIT_SET(NPCX_MSWCTL1, 3)) {
		NPCX_HCBAL = 0x4E;
		NPCX_HCBAH = 0x0;
	}
	/* Clear Host Access Hold state */
	NPCX_SMC_CTL = 0xC0;

	/* Initialize Hardware for UART Host */
#if CONFIG_UART_HOST
	/* Init COMx LPC UART */
	/* FMCLK have to using 50MHz */
	NPCX_DEVALT(0xB) = 0xFF;
	/* Make sure Host Access unlock */
	CLEAR_BIT(NPCX_LKSIOHA, 2);
	/* Clear Host Access Lock Violation */
	SET_BIT(NPCX_SIOLV, 2);
#endif

	/* Don't stall SHM transactions */
	NPCX_SHM_CTL = NPCX_SHM_CTL & ~0x40;
	/* Semaphore and Indirect access disable */
	NPCX_SHCFG = 0xE0;
	/* Disable Protect Win1&2*/
	NPCX_WIN_WR_PROT(0) = 0;
	NPCX_WIN_WR_PROT(1) = 0;
	NPCX_WIN_RD_PROT(0) = 0;
	NPCX_WIN_RD_PROT(1) = 0;
	/* Open Win1 256 byte for Host CMD, Win2 256 for MEMMAP*/
	NPCX_WIN_SIZE = 0x88;
	NPCX_WIN_BASE(0) = (uint32_t)shm_mem_host_cmd;
	NPCX_WIN_BASE(1) = (uint32_t)shm_memmap;

	/* Turn on PMC2 for Host Command usage */
	SET_BIT(NPCX_HIPMCTL(PM_CHAN_2), 0);
	SET_BIT(NPCX_HIPMCTL(PM_CHAN_2), 1);
	/* enable PMC2 IRQ */
	SET_BIT(NPCX_HIPMIE(PM_CHAN_2), 0);
	/* IRQ control from HW */
	SET_BIT(NPCX_HIPMIE(PM_CHAN_2), 3);
	/*
	 * Set required control value (avoid setting HOSTWAIT bit at this stage)
	 */
	NPCX_SMC_CTL = NPCX_SMC_CTL&~0x7F;
	/* Clear status */
	NPCX_SMC_STS = NPCX_SMC_STS;
	/* Create mailbox */

	/*
	 * Init KBC
	 * Clear OBF status, PM1 IBF/OBF INT enable, IRQ11 enable,
	 * IBF(K&M) INT enable, OBF(K&M) empty INT enable ,
	 * OBF Mouse Full INT enable and OBF KB Full INT enable
	 */
	NPCX_HICTRL = 0xFF;
	/* Normally Polarity IRQ1,12,11 type (level + high) setting */
	NPCX_HIIRQC = 0x00;	/* Make sure to default */

	/*
	 * Init PORT80
	 * Enable Port80, Enable Port80 function & Interrupt & Read auto
	 */
	NPCX_DP80CTL = 0x29;
	SET_BIT(NPCX_GLUE_SDP_CTS, 3);
	SET_BIT(NPCX_GLUE_SDP_CTS, 0);
	/* Just turn on IRQE */
	NPCX_HIPMIE(PM_CHAN_1) = 0x01;
	lpc_task_enable_irq();

	/* Initialize host args and memory map to all zero */
	memset(lpc_host_args, 0, sizeof(*lpc_host_args));
	memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);

	/* We support LPC args and version 3 protocol */
	*(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) =
			EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
			EC_HOST_CMD_FLAG_VERSION_3;



	/* Restore event masks if needed */
	lpc_post_sysjump();

	/* Sufficiently initialized */
	init_done = 1;

	/* Update host events now that we can copy them to memmap */

	update_host_event_status();

	/* initial IO port address via SIB-write modules */
	system_lpc_host_register_init();
}
Esempio n. 15
0
static void lpc_init(void)
{
	/* Enable LPC clock in run and sleep modes. */
	clock_enable_peripheral(CGC_OFFSET_LPC, 0x1,
			CGC_MODE_RUN | CGC_MODE_SLEEP);

	LM4_LPC_LPCIM = 0;
	LM4_LPC_LPCCTL = 0;
	LM4_LPC_LPCIRQCTL = 0;

	/* Configure GPIOs */
	gpio_config_module(MODULE_LPC, 1);

	/*
	 * Set LPC channel 0 to I/O address 0x62 (data) / 0x66 (command),
	 * single endpoint, offset 0 for host command/writes and 1 for EC
	 * data writes, pool bytes 0(data)/1(cmd)
	 */
	LM4_LPC_ADR(LPC_CH_ACPI) = EC_LPC_ADDR_ACPI_DATA;
	LM4_LPC_CTL(LPC_CH_ACPI) = (LPC_POOL_OFFS_ACPI << (5 - 1));
	LM4_LPC_ST(LPC_CH_ACPI) = 0;
	/* Unmask interrupt for host command and data writes */
	LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_ACPI, 6);

	/*
	 * Set LPC channel 1 to I/O address 0x80 (data), single endpoint,
	 * pool bytes 4(data)/5(cmd).
	 */
	LM4_LPC_ADR(LPC_CH_PORT80) = 0x80;
	LM4_LPC_CTL(LPC_CH_PORT80) = (LPC_POOL_OFFS_PORT80 << (5 - 1));
	/* Unmask interrupt for host data writes */
	LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_PORT80, 2);

	/*
	 * Set LPC channel 2 to I/O address 0x880, range endpoint,
	 * arbitration disabled, pool bytes 512-639.  To access this from
	 * x86, use the following command to set GEN_LPC2:
	 *
	 *   pci_write32 0 0x1f 0 0x88 0x007c0801
	 */
	LM4_LPC_ADR(LPC_CH_CMD_DATA) = EC_LPC_ADDR_HOST_ARGS;
	LM4_LPC_CTL(LPC_CH_CMD_DATA) = 0x8019 |
		(LPC_POOL_OFFS_CMD_DATA << (5 - 1));

	/*
	 * Set LPC channel 3 to I/O address 0x60 (data) / 0x64 (command),
	 * single endpoint, offset 0 for host command/writes and 1 for EC
	 * data writes, pool bytes 0(data)/1(cmd)
	 */
	LM4_LPC_ADR(LPC_CH_KEYBOARD) = 0x60;
	LM4_LPC_CTL(LPC_CH_KEYBOARD) = (1 << 24/* IRQSEL1 */) |
		(0 << 18/* IRQEN1 */) | (LPC_POOL_OFFS_KEYBOARD << (5 - 1));
	LM4_LPC_ST(LPC_CH_KEYBOARD) = 0;
	/* Unmask interrupt for host command/data writes and data reads */
	LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_KEYBOARD, 7);

	/*
	 * Set LPC channel 4 to I/O address 0x200 (data) / 0x204 (command),
	 * single endpoint, offset 0 for host command/writes and 1 for EC
	 * data writes, pool bytes 0(data)/1(cmd)
	 */
	LM4_LPC_ADR(LPC_CH_CMD) = EC_LPC_ADDR_HOST_DATA;
	LM4_LPC_CTL(LPC_CH_CMD) = (LPC_POOL_OFFS_CMD << (5 - 1));
	/*
	 * Initialize status bits to 0.  We never set the ACPI burst status bit,
	 * so this guarantees that at least one status bit will always be 0.
	 * This is used by comm_lpc.c to detect that the EC is present on the
	 * LPC bus.  See crosbug.com/p/10963.
	 */
	LM4_LPC_ST(LPC_CH_CMD) = 0;
	/* Unmask interrupt for host command writes */
	LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_CMD, 4);

	/*
	 * Set LPC channel 5 to I/O address 0x900, range endpoint,
	 * arbitration enabled, pool bytes 768-1023.  To access this from
	 * x86, use the following command to set GEN_LPC3:
	 *
	 *   pci_write32 0 0x1f 0 0x8c 0x007c0901
	 */
	LM4_LPC_ADR(LPC_CH_MEMMAP) = EC_LPC_ADDR_MEMMAP;
	LM4_LPC_CTL(LPC_CH_MEMMAP) = 0x0019 | (LPC_POOL_OFFS_MEMMAP << (5 - 1));

#ifdef CONFIG_UART_HOST
	/*
	 * Set LPC channel 7 to COM port I/O address.  Note that channel 7
	 * ignores the TYPE bit and is always an 8-byte range.
	 */
	LM4_LPC_ADR(LPC_CH_COMX) = LPC_COMX_ADDR;
	/*
	 * In theory we could configure IRQSELs and set IRQEN2/CX, and then the
	 * host could enable IRQs on its own.  So far that hasn't been
	 * necessary, and due to the issues with IRQs (see wait_irq_sent()
	 * above) it might not work anyway.
	 */
	LM4_LPC_CTL(LPC_CH_COMX) = 0x0004 | (LPC_POOL_OFFS_COMX << (5 - 1));
	/* Enable COMx emulation for reads and writes. */
	LM4_LPC_LPCDMACX = 0x00310000;
	/*
	 * Unmask interrupt for host data writes.  We don't need interrupts for
	 * reads, because there's no flow control in that direction; LPC is
	 * much faster than the UART, and the UART doesn't have anywhere
	 * sensible to buffer input anyway.
	 */
	LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_COMX, 2);
#endif /* CONFIG_UART_HOST */

	/*
	 * Unmaksk LPC bus reset interrupt.  This lets us monitor the PCH
	 * PLTRST# signal for debugging.
	 */
	LM4_LPC_LPCIM |= (1 << 31);

	/* Enable LPC channels */
	LM4_LPC_LPCCTL = LM4_LPC_SCI_CLK_1 |
		(1 << LPC_CH_ACPI) |
		(1 << LPC_CH_PORT80) |
		(1 << LPC_CH_CMD_DATA) |
		(1 << LPC_CH_KEYBOARD) |
		(1 << LPC_CH_CMD) |
		(1 << LPC_CH_MEMMAP);

#ifdef CONFIG_UART_HOST
	LM4_LPC_LPCCTL |= 1 << LPC_CH_COMX;
#endif

	/*
	 * Ensure the EC (slave) has control of the memory-mapped I/O space.
	 * Once the EC has won arbtration for the memory-mapped space, it will
	 * keep control of it until it writes the last byte in the space.
	 * (That never happens; we can't use the last byte in the space because
	 * ACPI can't see it anyway.)
	 */
	while (!(LM4_LPC_ST(LPC_CH_MEMMAP) & 0x10)) {
		/* Clear HW1ST */
		LM4_LPC_ST(LPC_CH_MEMMAP) &= ~0x40;
		/* Do a dummy slave write; this should cause SW1ST to be set */
		*LPC_POOL_MEMMAP = *LPC_POOL_MEMMAP;
	}

	/* Initialize host args and memory map to all zero */
	memset(lpc_host_args, 0, sizeof(*lpc_host_args));
	memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);

	/* We support LPC args and version 3 protocol */
	*(lpc_get_memmap_range() + EC_MEMMAP_HOST_CMD_FLAGS) =
		EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
		EC_HOST_CMD_FLAG_VERSION_3;

	/* Enable LPC interrupt */
	task_enable_irq(LM4_IRQ_LPC);

#ifdef CONFIG_UART_HOST
	/* Enable COMx UART */
	uart_comx_enable();
#endif

	/* Restore event masks if needed */
	lpc_post_sysjump();

	/* Sufficiently initialized */
	init_done = 1;

	/* Update host events now that we can copy them to memmap */
	update_host_event_status();
}
Esempio n. 16
0
void gpio_pre_init(void)
{
	const struct gpio_info *g = gpio_list;
	int is_warm = 0;
	int i;

	if (LM4_SYSTEM_RCGCGPIO == 0x7fff) {
		/* This is a warm reboot */
		is_warm = 1;
	} else {
		/*
		 * Enable clocks to all the GPIO blocks since we use all of
		 * them as GPIOs in run and sleep modes.
		 */
		clock_enable_peripheral(CGC_OFFSET_GPIO, 0x7fff,
				CGC_MODE_RUN | CGC_MODE_SLEEP);
	}

	/*
	 * Disable GPIO commit control for PD7 and PF0, since we don't use the
	 * NMI pin function.
	 */
	LM4_GPIO_LOCK(LM4_GPIO_D) = LM4_GPIO_LOCK_UNLOCK;
	LM4_GPIO_CR(LM4_GPIO_D) |= 0x80;
	LM4_GPIO_LOCK(LM4_GPIO_D) = 0;
	LM4_GPIO_LOCK(LM4_GPIO_F) = LM4_GPIO_LOCK_UNLOCK;
	LM4_GPIO_CR(LM4_GPIO_F) |= 0x01;
	LM4_GPIO_LOCK(LM4_GPIO_F) = 0;

	/* Clear SSI0 alternate function on PA2:5 */
	LM4_GPIO_AFSEL(LM4_GPIO_A) &= ~0x3c;

	/* Mask all GPIO interrupts */
	for (i = 0; gpio_bases[i]; i++)
		LM4_GPIO_IM(gpio_bases[i]) = 0;

	/* Set all GPIOs to defaults */
	for (i = 0; i < GPIO_COUNT; i++, g++) {
		int flags = g->flags;

		if (flags & GPIO_DEFAULT)
			continue;

#ifdef CONFIG_LOW_POWER_IDLE
		/*
		 * Enable board specific GPIO ports to interrupt deep sleep by
		 * providing a clock to that port in deep sleep mode.
		 */
		if (flags & GPIO_INT_DSLEEP) {
			clock_enable_peripheral(CGC_OFFSET_GPIO,
				gpio_port_to_clock_gate_mask(g->port),
				CGC_MODE_ALL);
		}
#endif

		/*
		 * If this is a warm reboot, don't set the output levels or
		 * we'll shut off the main chipset.
		 */
		if (is_warm)
			flags &= ~(GPIO_LOW | GPIO_HIGH);

		/* Set up GPIO based on flags */
		gpio_set_flags_by_mask(g->port, g->mask, flags);

		/* Use as GPIO, not alternate function */
		gpio_set_alternate_function(g->port, g->mask, -1);
	}

#ifdef CONFIG_LOW_POWER_IDLE
	/*
	 * Enable KB scan row to interrupt deep sleep by providing a clock
	 * signal to that port in deep sleep mode.
	 */
	clock_enable_peripheral(CGC_OFFSET_GPIO,
				gpio_port_to_clock_gate_mask(KB_SCAN_ROW_GPIO),
				CGC_MODE_ALL);
#endif
}