diff --git a/bsp_sedi/soc/intel_ish/pm/ish_pm.c b/bsp_sedi/soc/intel_ish/pm/ish_pm.c index df7b2a5..dfa60e3 100644 --- a/bsp_sedi/soc/intel_ish/pm/ish_pm.c +++ b/bsp_sedi/soc/intel_ish/pm/ish_pm.c @@ -38,6 +38,43 @@ extern uint32_t _image_ram_end; static sedi_uart_config_t uart0_cfg, uart1_cfg, uart2_cfg; +struct { + sedi_devid_t id; + uint32_t reg; + uint32_t bits; +} static pm_cg_info[] = { + { + .id = SEDI_DEVID_UART0, + .reg = CCU_BCG_UART, + .bits = CCU_BCG_BIT_UART0, + }, + { + .id = SEDI_DEVID_UART1, + .reg = CCU_BCG_UART, + .bits = CCU_BCG_BIT_UART1, + }, + { + .id = SEDI_DEVID_UART2, + .reg = CCU_BCG_UART, + .bits = CCU_BCG_BIT_UART2, + }, + { + .id = SEDI_DEVID_I2C0, + .reg = CCU_BCG_I2C, + .bits = CCU_BCG_BIT_I2C0, + }, + { + .id = SEDI_DEVID_I2C1, + .reg = CCU_BCG_I2C, + .bits = CCU_BCG_BIT_I2C1, + }, + { + .id = SEDI_DEVID_I2C2, + .reg = CCU_BCG_I2C, + .bits = CCU_BCG_BIT_I2C2, + }, +}; + static void uart_to_idle(void) { sedi_uart_get_config(SEDI_UART_0, &uart0_cfg); @@ -751,3 +788,47 @@ void reset_pm_stats(void) { memset(&pm_stats, 0, sizeof(pm_stats)); } + +static int pm_get_cg_info(sedi_devid_t id, uint32_t *reg, uint32_t *reg_bits) +{ + *reg = 0x0; + *reg_bits = 0x0; + + for (int i = 0; i < ARRAY_SIZE(pm_cg_info); i++) { + if (pm_cg_info[i].id == id) { + *reg = pm_cg_info[i].reg; + *reg_bits = pm_cg_info[i].bits; + return SEDI_DRIVER_OK; + } + } + + return (*reg != 0x0) ? SEDI_DRIVER_OK : SEDI_DRIVER_ERROR; +} + +static void pm_change_cg_state(sedi_devid_t id, bool perform_cg) +{ + uint32_t bits, bcg_reg; + uint32_t old_val, new_val; + + if (pm_get_cg_info(id, &bcg_reg, &bits) != SEDI_DRIVER_OK) + return; + + while (1) { + old_val = read32(bcg_reg); + + if (perform_cg) + new_val = old_val | bits; + else + new_val = old_val & ~bits; + + if (atomic_cas((atomic_t *)bcg_reg, (atomic_val_t)old_val, (atomic_val_t)new_val)) + break; + } +} + +void sedi_pm_set_device_power(IN sedi_devid_t id, IN sedi_power_state_t state) +{ + if ((id >= SEDI_DEVID_FIRST) && (id < SEDI_DEVID_TOP)) { + pm_change_cg_state(id, (state != SEDI_POWER_FULL)); + } +} diff --git a/bsp_sedi/soc/intel_ish/pm/pm_regs.h b/bsp_sedi/soc/intel_ish/pm/pm_regs.h index e7d2ef2..2b1c31e 100644 --- a/bsp_sedi/soc/intel_ish/pm/pm_regs.h +++ b/bsp_sedi/soc/intel_ish/pm/pm_regs.h @@ -109,17 +109,13 @@ #define CCU_BCG_DMA (SEDI_CCU_BASE + 0x28) #define CCU_AONCG_EN (SEDI_CCU_BASE + 0xdc) #define CCU_BCG_BIT_MIA BIT(0) -#define CCU_BCG_BIT_DMA BIT(1) -#define CCU_BCG_BIT_I2C0 BIT(2) -#define CCU_BCG_BIT_I2C1 BIT(3) -#define CCU_BCG_BIT_SPI BIT(4) -#define CCU_BCG_BIT_SRAM BIT(5) -#define CCU_BCG_BIT_HPET BIT(6) -#define CCU_BCG_BIT_UART BIT(7) -#define CCU_BCG_BIT_GPIO BIT(8) -#define CCU_BCG_BIT_I2C2 BIT(9) -#define CCU_BCG_BIT_SPI2 BIT(10) -#define CCU_BCG_BIT_ALL (0x7ff) + +#define CCU_BCG_BIT_I2C0 BIT(0) +#define CCU_BCG_BIT_I2C1 BIT(1) +#define CCU_BCG_BIT_I2C2 BIT(2) +#define CCU_BCG_BIT_UART0 BIT(0) +#define CCU_BCG_BIT_UART1 BIT(1) +#define CCU_BCG_BIT_UART2 BIT(2) #define CCU_SW_RST BIT(0) #define CCU_WDT_RST BIT(1)