예제 #1
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
}
예제 #2
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
}