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