Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Power Manager FW #384

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ sw/linker/link.ld
sw/linker/link_flash_exec.ld
sw/linker/link_flash_load.ld
sw/device/lib/drivers/power_manager/power_manager_regs.h
sw/device/lib/drivers/power_manager/power_manager.h
sw/device/lib/drivers/pad_control/pad_control_regs.h
sw/device/lib/drivers/**/*_structs.h

Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ mcu-gen:
$(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/ip/power_manager/rtl --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv hw/ip/power_manager/data/power_manager.sv.tpl
$(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/ip/power_manager/data --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv hw/ip/power_manager/data/power_manager.hjson.tpl
bash -c "cd hw/ip/power_manager; source power_manager_gen.sh; cd ../../../"
$(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir sw/device/lib/drivers/power_manager --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv sw/device/lib/drivers/power_manager/data/power_manager.h.tpl
$(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/data --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/data/pad_control.hjson.tpl
$(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/rtl --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/rtl/pad_control.sv.tpl
bash -c "cd hw/system/pad_control; source pad_control_gen.sh; cd ../../../"
Expand Down
17 changes: 7 additions & 10 deletions sw/applications/example_clock_gating/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,36 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;
power_manager_init(NULL);

// Clock-gating the peripheral subsystem
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(POWER_MANAGER_PERIPH_CLK_GATE_REG_OFFSET), 0x1);
clock_gate_periph(kOff_e);

// Clock-gating ram-banks
// We probably should not clockgate the bank where our RAM resides
for(uint32_t i = 2; i < MEMORY_BANKS; ++i)
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(power_manager_ram_map[i].clk_gate), 0x1);
clock_gate_ram_block(i,kOff_e);

// Clock-gating external subsystems
for(uint32_t i = 0; i < EXTERNAL_DOMAINS; ++i)
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(power_manager_external_map[i].clk_gate), 0x1);
clock_gate_external(i,kOff_e);

// Wait some time
for (int i=0; i<100; i++) asm volatile("nop;");

// Enabling the peripheral subsystem
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(POWER_MANAGER_PERIPH_CLK_GATE_REG_OFFSET), 0x0);
clock_gate_periph(kOn_e);

// Enabling ram-banks
for(uint32_t i = 2; i < MEMORY_BANKS; ++i)
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(power_manager_ram_map[i].clk_gate), 0x0);
clock_gate_ram_block(i,kOn_e);

// Enabling external subsystems
for(uint32_t i = 0; i < EXTERNAL_DOMAINS; ++i)
mmio_region_write32(power_manager.base_addr, (ptrdiff_t)(power_manager_external_map[i].clk_gate), 0x0);
clock_gate_external(i,kOn_e);

/* write something to stdout */
PRINTF("Success.\n\r");
Expand Down
17 changes: 7 additions & 10 deletions sw/applications/example_power_gating_core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
static rv_timer_t timer_0_1;
static rv_timer_t timer_2_3;
static const uint64_t kTickFreqHz = 1000 * 1000; // 1 MHz
static power_manager_t power_manager;

#ifndef TARGET_PYNQ_Z2
#define GPIO_TB_OUT 30
Expand All @@ -51,9 +50,7 @@ int main(int argc, char *argv[])
{

// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;
power_manager_counters_t power_manager_cpu_counters;
power_manager_init(NULL);
//counters
uint32_t reset_off, reset_on, switch_off, switch_on, iso_off, iso_on;

Expand Down Expand Up @@ -94,7 +91,7 @@ int main(int argc, char *argv[])
reset_on = switch_on + 20; //give 20 cycles to emulate the turn on time, this number depends on technology and here it is just a random number
iso_on = reset_on + 5;

if (power_gate_counters_init(&power_manager_cpu_counters, reset_off, reset_on, switch_off, switch_on, iso_off, iso_on, 0, 0) != kPowerManagerOk_e)
if (power_gate_counters_init(reset_off, reset_on, switch_off, switch_on, iso_off, iso_on, 0, 0) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
Expand All @@ -107,7 +104,7 @@ int main(int argc, char *argv[])
rv_timer_counter_set_enabled(&timer_0_1, 0, kRvTimerEnabled);

CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if (power_gate_core(&power_manager, kTimer_0_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kTimer_0_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -121,7 +118,7 @@ int main(int argc, char *argv[])
rv_timer_counter_set_enabled(&timer_0_1, 1, kRvTimerEnabled);

CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if (power_gate_core(&power_manager, kTimer_1_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kTimer_1_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -135,7 +132,7 @@ int main(int argc, char *argv[])
rv_timer_counter_set_enabled(&timer_2_3, 0, kRvTimerEnabled);

CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if (power_gate_core(&power_manager, kTimer_2_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kTimer_2_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -149,7 +146,7 @@ int main(int argc, char *argv[])
rv_timer_counter_set_enabled(&timer_2_3, 1, kRvTimerEnabled);

CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if (power_gate_core(&power_manager, kTimer_3_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kTimer_3_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -171,7 +168,7 @@ int main(int argc, char *argv[])
gpio_write(GPIO_TB_OUT, true);

CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if (power_gate_core(&power_manager, kPlic_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kPlic_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
15 changes: 5 additions & 10 deletions sw/applications/example_power_gating_external/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,38 +23,33 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;

power_manager_counters_t power_manager_external_counters;
power_manager_init(NULL);

// Init ram block 2's counters
if (power_gate_counters_init(&power_manager_external_counters, 30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
if (power_gate_counters_init(30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
}

// Power off external domain
if (power_gate_external(&power_manager, 0, kOff_e, &power_manager_external_counters) != kPowerManagerOk_e)
if (power_gate_external(0, kOff_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
}

// Check that the external domain is actually OFF
while(!external_power_domain_is_off(&power_manager, 0));
while(!external_power_domain_is_off(0));

// Wait some time
for (int i=0; i<100; i++) asm volatile("nop");

// Power on external domain
if (power_gate_external(&power_manager, 0, kOn_e, &power_manager_external_counters) != kPowerManagerOk_e)
if (power_gate_external(0, kOn_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
15 changes: 5 additions & 10 deletions sw/applications/example_power_gating_periph/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,38 +23,33 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;

power_manager_counters_t power_manager_periph_counters;
power_manager_init(NULL);

// Init peripheral_subsystem's counters
if (power_gate_counters_init(&power_manager_periph_counters, 30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
if (power_gate_counters_init(30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
}

// Power off peripheral_subsystem domain
if (power_gate_periph(&power_manager, kOff_e, &power_manager_periph_counters) != kPowerManagerOk_e)
if (power_gate_periph(kOff_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
}

// Check that the peripheral_subsystem domain is actually OFF
while(!periph_power_domain_is_off(&power_manager));
while(!periph_power_domain_is_off());

// Wait some time
for (int i=0; i<100; i++) asm volatile("nop;");

// Power on peripheral_subsystem domain
if (power_gate_periph(&power_manager, kOn_e, &power_manager_periph_counters) != kPowerManagerOk_e)
if (power_gate_periph(kOn_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
15 changes: 5 additions & 10 deletions sw/applications/example_power_gating_ram_blocks/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,35 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{

#if MEMORY_BANKS > 2
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;

power_manager_counters_t power_manager_ram_blocks_counters;
power_manager_init(NULL);

// Init ram block 2's counters
if (power_gate_counters_init(&power_manager_ram_blocks_counters, 30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
if (power_gate_counters_init(30, 30, 30, 30, 30, 30, 0, 0) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
}

// Power off ram block 2 domain
if (power_gate_ram_block(&power_manager, 2, kOff_e, &power_manager_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_ram_block(2, kOff_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
}

// Check that the ram block 2 domain is actually OFF
while(!ram_block_power_domain_is_off(&power_manager, 2));
while(!ram_block_power_domain_is_off(2));

// Wait some time
for (int i=0; i<100; i++) asm volatile("nop");

// Power on ram block 2 domain
if (power_gate_ram_block(&power_manager, 2, kOn_e, &power_manager_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_ram_block(2, kOn_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
13 changes: 4 additions & 9 deletions sw/applications/example_set_retentive_ram_blocks/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,21 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{
#if MEMORY_BANKS > 2
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;

power_manager_counters_t power_manager_ram_blocks_counters;
power_manager_init(NULL);

// Init ram block 2's counters
if (power_gate_counters_init(&power_manager_ram_blocks_counters, 0, 0, 0, 0, 0, 0, 30, 30) != kPowerManagerOk_e)
if (power_gate_counters_init(0, 0, 0, 0, 0, 0, 30, 30) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
}

// Set retention mode on for ram block 2 domain
if (power_gate_ram_block(&power_manager, 2, kRetOn_e, &power_manager_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_ram_block(2, kRetOn_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -52,7 +47,7 @@ int main(int argc, char *argv[])
for (int i=0; i<100; i++) asm volatile("nop");

// Set retention mode off for ram block 2 domain
if (power_gate_ram_block(&power_manager, 2, kRetOff_e, &power_manager_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_ram_block(2, kRetOff_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
13 changes: 4 additions & 9 deletions sw/applications/example_set_retentive_ram_blocks_external/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,20 @@
#define PRINTF(...)
#endif

static power_manager_t power_manager;

int main(int argc, char *argv[])
{
// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;

power_manager_counters_t power_manager_external_ram_blocks_counters;
power_manager_init(NULL);

// Init external ram block 0's counters
if (power_gate_counters_init(&power_manager_external_ram_blocks_counters, 0, 0, 0, 0, 0, 0, 30, 30) != kPowerManagerOk_e)
if (power_gate_counters_init(0, 0, 0, 0, 0, 0, 30, 30) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
}

// Set retention mode on for external ram block 0
if (power_gate_external(&power_manager, 0, kRetOn_e, &power_manager_external_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_external(0, kRetOn_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand All @@ -51,7 +46,7 @@ int main(int argc, char *argv[])
for (int i=0; i<100; i++) asm volatile("nop");

// Set retention mode off for external ram block 0
if (power_gate_external(&power_manager, 0, kRetOff_e, &power_manager_external_ram_blocks_counters) != kPowerManagerOk_e)
if (power_gate_external(0, kRetOff_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
11 changes: 4 additions & 7 deletions sw/applications/example_spi_host_dma_power_gate/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ volatile int8_t dma_intr_flag;
int8_t core_sleep_flag;
spi_host_t spi_host;

static power_manager_t power_manager;

void dma_intr_handler_trans_done(void)
{
PRINTF("Non-weak implementation of a DMA interrupt\n\r");
Expand Down Expand Up @@ -102,11 +100,10 @@ int main(int argc, char *argv[])
#endif

// Setup power_manager
mmio_region_t power_manager_reg = mmio_region_from_addr(POWER_MANAGER_START_ADDRESS);
power_manager.base_addr = power_manager_reg;
power_manager_counters_t power_manager_cpu_counters;
power_manager_init(NULL);

// Init cpu_subsystem's counters
if (power_gate_counters_init(&power_manager_cpu_counters, 300, 300, 300, 300, 300, 300, 0, 0) != kPowerManagerOk_e)
if (power_gate_counters_init(300, 300, 300, 300, 300, 300, 0, 0) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail. Check the reset and powergate counters value\n\r");
return EXIT_FAILURE;
Expand Down Expand Up @@ -279,7 +276,7 @@ int main(int argc, char *argv[])
// Power gate core and wait for fast DMA interrupt
CSR_CLEAR_BITS(CSR_REG_MSTATUS, 0x8);
if(dma_intr_flag == 0) {
if (power_gate_core(&power_manager, kDma_pm_e, &power_manager_cpu_counters) != kPowerManagerOk_e)
if (power_gate_core(kDma_pm_e) != kPowerManagerOk_e)
{
PRINTF("Error: power manager fail.\n\r");
return EXIT_FAILURE;
Expand Down
Loading