コード例 #1
0
static void lpc_init(void)
{
	/* Activate LPC interface */
	MEC1322_LPC_ACT |= 1;

	/* 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);

	setup_lpc();

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


}
コード例 #2
0
ファイル: lpc.c プロジェクト: fishbaoz/chrome-ec
static void lpc_init(void)
{
	/* Activate LPC interface */
	MEC1322_LPC_ACT |= 1;

	/*
	* Ring Oscillator not permitted to shut down
	* until LPC activate bit is cleared
	*/
	MEC1322_LPC_CLK_CTRL |= 3;

	/* 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);

	setup_lpc();

	/* Restore event masks if needed */
	lpc_post_sysjump();
}
コード例 #3
0
ファイル: lpc.c プロジェクト: latelee/chrome-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;

	/*
	 * 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
}
コード例 #4
0
ファイル: lpc.c プロジェクト: coreboot/chrome-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);
#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
}
コード例 #5
0
ファイル: lpc.c プロジェクト: 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();
}
コード例 #6
0
ファイル: lpc.c プロジェクト: alterapraxisptyltd/chromium-ec
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();
}
コード例 #7
0
ファイル: lpc.c プロジェクト: coreboot/chrome-ec
static void lpc_init(void)
{
	enum ec2i_message ec2i_r;

	/* SPI slave interface is disabled */
	IT83XX_GCTRL_SSCR = 0;
	/*
	 * DLM 52k~56k size select enable.
	 * For mapping LPC I/O cycle 800h ~ 9FFh to DLM 8D800 ~ 8D9FF.
	 */
	IT83XX_GCTRL_MCCR2 |= 0x10;

	/* The register pair to access PNPCFG is 004Eh and 004Fh */
	IT83XX_GCTRL_BADRSEL = 0x01;

	/* Disable KBC IRQ */
	IT83XX_KBC_KBIRQR = 0x00;

	/*
	 * bit2, Output Buffer Empty CPU Interrupt Enable.
	 * bit3, Input Buffer Full CPU Interrupt Enable.
	 * bit5, IBF/OBF EC clear mode.
	 *   0b: IBF cleared if EC read data register, EC reset, or host reset.
	 *       OBF cleared if host read data register, or EC reset.
	 *   1b: IBF cleared if EC write-1 to bit7 at related registers,
	 *       EC reset, or host reset.
	 *       OBF cleared if host read data register, EC write-1 to bit6 at
	 *       related registers, or EC reset.
	 */
	IT83XX_KBC_KBHICR |= 0x2C;

	/* PM1 Input Buffer Full Interrupt Enable for 62h/66 port */
	pm_set_ctrl(LPC_ACPI_CMD, PM_CTRL_IBFIE, 1);

	/* PM2 Input Buffer Full Interrupt Enable for 200h/204 port */
	pm_set_ctrl(LPC_HOST_CMD, PM_CTRL_IBFIE, 1);

	memset(lpc_get_memmap_range(), 0, EC_MEMMAP_SIZE);
	memset(lpc_host_args, 0, sizeof(*lpc_host_args));

	/* Host LPC I/O cycle mapping to RAM */
	/*
	 * bit[4], H2RAM through LPC IO cycle.
	 * bit[1], H2RAM window 1 enabled.
	 * bit[0], H2RAM window 0 enabled.
	 */
	IT83XX_SMFI_HRAMWC |= 0x13;

	/*
	 * bit[7:6]
	 * Host RAM Window[x] Read Protect Enable
	 * 00b: Disabled
	 * 01b: Lower half of RAM window protected
	 * 10b: Upper half of RAM window protected
	 * 11b: All protected
	 *
	 * bit[5:4]
	 * Host RAM Window[x] Write Protect Enable
	 * 00b: Disabled
	 * 01b: Lower half of RAM window protected
	 * 10b: Upper half of RAM window protected
	 * 11b: All protected
	 *
	 * bit[2:0]
	 * Host RAM Window 1 Size (HRAMW1S)
	 * 0h: 16 bytes
	 * 1h: 32 bytes
	 * 2h: 64 bytes
	 * 3h: 128 bytes
	 * 4h: 256 bytes
	 * 5h: 512 bytes
	 * 6h: 1024 bytes
	 * 7h: 2048 bytes
	 */

	/* H2RAM Win 0 Base Address 800h allow r/w for host_cmd_memmap */
	IT83XX_SMFI_HRAMW0BA = 0x80;
	IT83XX_SMFI_HRAMW0AAS = 0x04;

	/* H2RAM Win 1 Base Address 900h allow r for acpi_ec_memmap */
	IT83XX_SMFI_HRAMW1BA = 0x90;
	IT83XX_SMFI_HRAMW1AAS = 0x34;

	/* 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;

	/*
	 * bit[5], Dedicated interrupt
	 * INT3: PMC1 Output Buffer Empty Int
	 * INT25: PMC1 Input Buffer Full Int
	 * INT26: PMC2 Output Buffer Empty Int
	 * INT27: PMC2 Input Buffer Full Int
	 */
	IT83XX_PMC_MBXCTRL |= 0x20;

	/* PM3 Input Buffer Full Interrupt Enable for 80h port */
	pm_set_ctrl(LPC_HOST_PORT_80H, PM_CTRL_IBFIE, 1);

	p80l_index = P80L_P80LC;
	if (ec2i_write(HOST_INDEX_LDN, LDN_RTCT) == EC2I_WRITE_SUCCESS) {
		/* get P80L current index */
		ec2i_r = ec2i_read(HOST_INDEX_DSLDC6);
		/* read OK */
		if ((ec2i_r & 0xff00) == EC2I_READ_SUCCESS)
			p80l_index = ec2i_r & P80L_BRAM_BANK1_SIZE_MASK;
	}

	/*
	 * bit[7], enable P80L function.
	 * bit[6], accept port 80h cycle.
	 * bit[1-0], 10b: I2EC is read-only.
	 */
	IT83XX_GCTRL_SPCTRL1 |= 0xC2;

	gpio_enable_interrupt(GPIO_PCH_PLTRST_L);

	task_clear_pending_irq(IT83XX_IRQ_KBC_OUT);
	task_disable_irq(IT83XX_IRQ_KBC_OUT);

	task_clear_pending_irq(IT83XX_IRQ_KBC_IN);
	task_enable_irq(IT83XX_IRQ_KBC_IN);

	task_clear_pending_irq(IT83XX_IRQ_PMC_IN);
	pm_set_status(LPC_ACPI_CMD, EC_LPC_STATUS_PROCESSING, 0);
	task_enable_irq(IT83XX_IRQ_PMC_IN);

	task_clear_pending_irq(IT83XX_IRQ_PMC2_IN);
	pm_set_status(LPC_HOST_CMD, EC_LPC_STATUS_PROCESSING, 0);
	task_enable_irq(IT83XX_IRQ_PMC2_IN);

	task_clear_pending_irq(IT83XX_IRQ_PMC3_IN);
	task_enable_irq(IT83XX_IRQ_PMC3_IN);

	/* 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();
}