void lpc_set_host_event_state(uint32_t mask) { if (mask != host_events) { host_events = mask; update_host_event_status(); } }
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 }
void lpc_set_host_event_mask(enum lpc_host_event_type type, uint32_t mask) { event_mask[type] = mask; update_host_event_status(); }
static void lpc_init(void) { /* * DLM 52k~56k size select enable. * For mapping LPC I/O cycle 800h ~ 9FFh to DLM 8D800 ~ 8D9FF. */ IT83XX_GCTRL_MCCR2 |= 0x10; IT83XX_GPIO_GCR = 0x06; /* 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. */ IT83XX_KBC_KBHICR |= 0x0C; /* 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); 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); task_enable_irq(IT83XX_IRQ_PMC_IN); task_clear_pending_irq(IT83XX_IRQ_PMC2_IN); task_enable_irq(IT83XX_IRQ_PMC2_IN); task_clear_pending_irq(IT83XX_IRQ_PMC3_IN); task_enable_irq(IT83XX_IRQ_PMC3_IN); /* Sufficiently initialized */ init_done = 1; /* Update host events now that we can copy them to memmap */ update_host_event_status(); }
/* * Most registers in LPC module are reset when the host is off. We need to * set up LPC again when the host is starting up. */ static void setup_lpc(void) { gpio_config_module(MODULE_LPC, 1); /* Set up interrupt on LRESET# deassert */ MEC1322_INT_SOURCE(19) = 1 << 1; MEC1322_INT_ENABLE(19) |= 1 << 1; MEC1322_INT_BLK_EN |= 1 << 19; task_enable_irq(MEC1322_IRQ_GIRQ19); /* Set up ACPI0 for 0x62/0x66 */ MEC1322_LPC_ACPI_EC0_BAR = 0x00628304; MEC1322_INT_ENABLE(15) |= 1 << 6; MEC1322_INT_BLK_EN |= 1 << 15; /* Clear STATUS_PROCESSING bit in case it was set during sysjump */ MEC1322_ACPI_EC_STATUS(0) &= ~EC_LPC_STATUS_PROCESSING; task_enable_irq(MEC1322_IRQ_ACPIEC0_IBF); /* Set up ACPI1 for 0x200/0x204 */ MEC1322_LPC_ACPI_EC1_BAR = 0x02008407; MEC1322_INT_ENABLE(15) |= 1 << 8; MEC1322_INT_BLK_EN |= 1 << 15; MEC1322_ACPI_EC_STATUS(1) &= ~EC_LPC_STATUS_PROCESSING; task_enable_irq(MEC1322_IRQ_ACPIEC1_IBF); /* Set up 8042 interface at 0x60/0x64 */ MEC1322_LPC_8042_BAR = 0x00608104; /* Set up indication of Auxillary sts */ MEC1322_8042_KB_CTRL |= 1 << 7; MEC1322_8042_ACT |= 1; MEC1322_INT_ENABLE(15) |= ((1 << 13) | (1 << 14)); MEC1322_INT_BLK_EN |= 1 << 15; task_enable_irq(MEC1322_IRQ_8042EM_IBF); task_enable_irq(MEC1322_IRQ_8042EM_OBF); #ifndef CONFIG_KEYBOARD_IRQ_GPIO /* Set up SERIRQ for keyboard */ MEC1322_8042_KB_CTRL |= (1 << 5); MEC1322_LPC_SIRQ(1) = 0x01; #endif /* Set up EMI module for memory mapped region, base address 0x800 */ MEC1322_LPC_EMI_BAR = 0x0800800f; MEC1322_INT_ENABLE(15) |= 1 << 2; MEC1322_INT_BLK_EN |= 1 << 15; task_enable_irq(MEC1322_IRQ_EMI); /* Access data RAM through alias address */ MEC1322_EMI_MBA0 = (uint32_t)mem_mapped - 0x118000 + 0x20000000; /* * Limit EMI read / write range. First 256 bytes are RW for host * commands. Second 256 bytes are RO for mem-mapped data. */ MEC1322_EMI_MRL0 = 0x200; MEC1322_EMI_MWL0 = 0x100; /* Set up Mailbox for Port80 trapping */ MEC1322_MBX_INDEX = 0xff; MEC1322_LPC_MAILBOX_BAR = 0x00808901; /* 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; /* Sufficiently initialized */ init_done = 1; /* Update host events now that we can copy them to memmap */ update_host_event_status(); }
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 }
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(); }
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(); }
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(); }