├── License.txt ├── Documentation ├── NotifyToA8.bmp ├── NotifyToA8.dia ├── A8_CM3_Sync.bmp ├── A8_CM3_Sync.dia ├── NotifyToCM3.bmp ├── NotifyToCM3.dia ├── Trace_vector.bmp ├── Trace_vector.dia ├── Init_sequence.bmp ├── Init_sequence.dia ├── SA_PM_Firmware.pdf ├── CM3_firmware_loading.bmp ├── CM3_firmware_loading.dia ├── CM3_A8_interaction_RTC_entry.bmp └── CM3_A8_interaction_RTC_entry.dia ├── bin ├── am335x-pm-firmware.bin └── am335x-pm-firmware.elf ├── AM335x_CM3_Firmware_Manifest.doc ├── AM335x_CM3_Firmware_Manifest.pdf ├── firmware.ld ├── .gitignore ├── src ├── foundation │ ├── rtc.c │ ├── exception_handlers.c │ ├── cm3.c │ ├── ext_intr_handlers.c │ └── startup.c ├── sys_exec │ ├── trace.c │ ├── system_am335.c │ ├── sync.c │ ├── sys_init.c │ └── msg.c ├── include │ ├── cm3.h │ ├── low_power.h │ ├── system_am335.h │ ├── prmam335x.h │ ├── device_am335x.h │ └── prcm.h └── pm_services │ ├── pm_handlers.c │ └── prcm_core.c ├── Makefile └── README /License.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/License.txt -------------------------------------------------------------------------------- /Documentation/NotifyToA8.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/NotifyToA8.bmp -------------------------------------------------------------------------------- /Documentation/NotifyToA8.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/NotifyToA8.dia -------------------------------------------------------------------------------- /bin/am335x-pm-firmware.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/bin/am335x-pm-firmware.bin -------------------------------------------------------------------------------- /bin/am335x-pm-firmware.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/bin/am335x-pm-firmware.elf -------------------------------------------------------------------------------- /Documentation/A8_CM3_Sync.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/A8_CM3_Sync.bmp -------------------------------------------------------------------------------- /Documentation/A8_CM3_Sync.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/A8_CM3_Sync.dia -------------------------------------------------------------------------------- /Documentation/NotifyToCM3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/NotifyToCM3.bmp -------------------------------------------------------------------------------- /Documentation/NotifyToCM3.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/NotifyToCM3.dia -------------------------------------------------------------------------------- /Documentation/Trace_vector.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/Trace_vector.bmp -------------------------------------------------------------------------------- /Documentation/Trace_vector.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/Trace_vector.dia -------------------------------------------------------------------------------- /AM335x_CM3_Firmware_Manifest.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/AM335x_CM3_Firmware_Manifest.doc -------------------------------------------------------------------------------- /AM335x_CM3_Firmware_Manifest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/AM335x_CM3_Firmware_Manifest.pdf -------------------------------------------------------------------------------- /Documentation/Init_sequence.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/Init_sequence.bmp -------------------------------------------------------------------------------- /Documentation/Init_sequence.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/Init_sequence.dia -------------------------------------------------------------------------------- /Documentation/SA_PM_Firmware.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/SA_PM_Firmware.pdf -------------------------------------------------------------------------------- /Documentation/CM3_firmware_loading.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/CM3_firmware_loading.bmp -------------------------------------------------------------------------------- /Documentation/CM3_firmware_loading.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/CM3_firmware_loading.dia -------------------------------------------------------------------------------- /Documentation/CM3_A8_interaction_RTC_entry.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/CM3_A8_interaction_RTC_entry.bmp -------------------------------------------------------------------------------- /Documentation/CM3_A8_interaction_RTC_entry.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beagleboard/am33x-cm3/HEAD/Documentation/CM3_A8_interaction_RTC_entry.dia -------------------------------------------------------------------------------- /firmware.ld: -------------------------------------------------------------------------------- 1 | /* Linker script for the firmware */ 2 | 3 | MEMORY 4 | { 5 | UMEM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00004000 6 | DMEM (rw) : ORIGIN = 0x00080000, LENGTH = 0x00002000 7 | } 8 | 9 | _end_stack = 0x00081000; 10 | 11 | SECTIONS 12 | { 13 | .text : 14 | { 15 | _start_text = .; 16 | KEEP(*(.vectors)) 17 | *(.text*) 18 | *(.rodata*) 19 | _end_text = .; 20 | } > UMEM 21 | .data : AT(ADDR(.text) + SIZEOF(.text)) 22 | { 23 | _start_data = .; 24 | *(vtable) 25 | *(.data*) 26 | _end_data = .; 27 | } > DMEM 28 | .bss : 29 | { 30 | _start_bss = .; 31 | *(.bss*) 32 | *(COMMON) 33 | _end_bss = .; 34 | } > DMEM 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # Based on the .gitignore file in the Linux kernel 3 | # 4 | # NOTE! Don't add files that are generated in specific 5 | # subdirectories here. Add them in the ".gitignore" file 6 | # in that subdirectory instead. 7 | # 8 | # NOTE! Please use 'git ls-files -i --exclude-standard' 9 | # command after changing this file, to see if there are 10 | # any tracked files which get ignored after the change. 11 | # 12 | # Normal rules 13 | # 14 | .* 15 | *.o 16 | *.o.* 17 | *.i 18 | *.patch 19 | 20 | # 21 | # git files that we don't want to ignore even it they are dot-files 22 | # 23 | !.gitignore 24 | !.mailmap 25 | 26 | # stgit generated dirs 27 | patches-* 28 | 29 | # quilt's files 30 | patches 31 | series 32 | 33 | # cscope files 34 | cscope.* 35 | ncscope.* 36 | 37 | *.orig 38 | *~ 39 | \#*# 40 | -------------------------------------------------------------------------------- /src/foundation/rtc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | int rtc_enable_check() 21 | { 22 | if (__raw_readl(AM335X_CM_RTC_CLKSTCTRL == 0x2)) 23 | return 0; 24 | else 25 | while(1) 26 | ; 27 | } 28 | 29 | void rtc_reg_write(int reg, int val) 30 | { 31 | __raw_writel(val, reg); 32 | } 33 | 34 | int rtc_reg_read(int reg) 35 | { 36 | return __raw_readl(reg); 37 | } 38 | -------------------------------------------------------------------------------- /src/sys_exec/trace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | /* TODO: ROM code ate up the trace location. Can we manage without this? */ 19 | void trace_init(void) 20 | { 21 | 22 | } 23 | 24 | void trace_update(void) 25 | { 26 | 27 | } 28 | 29 | /* Use bit-banding here */ 30 | void trace_get_current_pos(void) 31 | { 32 | 33 | } 34 | 35 | /* Intended to be called in case of errors/exceptions */ 36 | void trace_set_current_pos(void) 37 | { 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION = 1 2 | PATCHLEVEL = 0 3 | SUBLEVEL = 0 4 | NAME = "Bday Edition" 5 | 6 | CROSS_COMPILE = arm-arago-linux-gnueabi- 7 | 8 | CC = ${CROSS_COMPILE}gcc 9 | OBJCOPY = $(CROSS_COMPILE)objcopy 10 | OBJFMT = binary 11 | 12 | SRCDIR = src 13 | BINDIR = bin 14 | 15 | INCLUDES = $(SRCDIR)/include 16 | CFLAGS =-mcpu=cortex-m3 -mthumb -nostdlib -Wall -g -I$(INCLUDES) 17 | LDFLAGS =-nostartfiles -fno-exceptions -Tfirmware.ld 18 | 19 | EXECUTABLE=am335x-pm-firmware.elf 20 | 21 | .PHONY: all clean 22 | 23 | SOURCES = $(shell find $(SRCDIR) -name *.c) 24 | OBJECTS = $(SOURCES:.c=.o) 25 | 26 | $(EXECUTABLE): $(OBJECTS) 27 | @echo "Compiling..." 28 | @echo $(OBJECTS) 29 | $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $(BINDIR)/$@ 30 | 31 | all: $(EXECUTABLE) 32 | @echo "Linking..." 33 | $(OBJCOPY) -O$(OBJFMT) $(BINDIR)/$(EXECUTABLE) $(BINDIR)/$(EXECUTABLE:.elf=.bin) 34 | 35 | clean: 36 | @echo "Cleaning up..." 37 | -$(shell find . -name *.o -exec rm {} \;) 38 | -$(shell rm -f $(BINDIR)/$(EXECUTABLE)) 39 | -$(shell rm -f $(BINDIR)/$(EXECUTABLE:.elf=.bin)) 40 | @echo "Done!" 41 | -------------------------------------------------------------------------------- /src/foundation/exception_handlers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | /* Will be extended in the future as and when required */ 19 | void nmi_handler(void) 20 | { 21 | while(1) 22 | ; 23 | } 24 | 25 | void hardfault_handler(void) 26 | { 27 | while(1) 28 | ; 29 | } 30 | 31 | void memmanage_handler(void) 32 | { 33 | while(1) 34 | ; 35 | } 36 | 37 | void busfault_handler(void) 38 | { 39 | while(1) 40 | ; 41 | } 42 | 43 | void usagefault_handler(void) 44 | { 45 | while(1) 46 | ; 47 | } 48 | 49 | void svc_handler(void) 50 | { 51 | while(1) 52 | ; 53 | } 54 | 55 | void debugmon_handler(void) 56 | { 57 | while(1) 58 | ; 59 | } 60 | 61 | void pendsv_handler(void) 62 | { 63 | while(1) 64 | ; 65 | } 66 | 67 | #if 0 68 | void systick_handler(void) 69 | { 70 | while(1) 71 | ; 72 | } 73 | #endif 74 | -------------------------------------------------------------------------------- /src/include/cm3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #ifndef __CM3_H__ 14 | #define __CM3_H__ 15 | 16 | #define NVIC_BASE 0xE000E100 17 | 18 | #define NVIC_IRQ_SET_EN1 (NVIC_BASE + 0x0) 19 | #define NVIC_IRQ_SET_EN2 (NVIC_BASE + 0x4) 20 | #define NVIC_IRQ_SET_EN3 (NVIC_BASE + 0x8) 21 | 22 | #define NVIC_IRQ_CLR_EN1 (NVIC_BASE + 0x80) 23 | #define NVIC_IRQ_CLR_EN2 (NVIC_BASE + 0x84) 24 | #define NVIC_IRQ_CLR_EN3 (NVIC_BASE + 0x88) 25 | 26 | #define NVIC_IRQ_SET_PEND1 (NVIC_BASE + 0x100) 27 | #define NVIC_IRQ_SET_PEND2 (NVIC_BASE + 0x104) 28 | #define NVIC_IRQ_SET_PEND3 (NVIC_BASE + 0x108) 29 | 30 | #define NVIC_IRQ_CLR_PEND1 (NVIC_BASE + 0x180) 31 | #define NVIC_IRQ_CLR_PEND2 (NVIC_BASE + 0x184) 32 | #define NVIC_IRQ_CLR_PEND3 (NVIC_BASE + 0x188) 33 | 34 | #define SYS_CONTROL_BASE 0xE000ED00 35 | 36 | #define SYS_SCR (SYS_CONTROL_BASE + 0x10) 37 | #define SYS_SCR_SD_OFFSET 0x2 38 | #define SYS_SCR_SOE_OFFSET 0x1 39 | 40 | void nvic_enable_irq(int); 41 | void nvic_disable_irq(int); 42 | void nvic_clear_irq(int); 43 | void scr_enable_sleepdeep(void); 44 | void scr_enable_sleeponexit(void); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/sys_exec/system_am335.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | /* uint32_t system_core_clock; */ 19 | 20 | void system_init(void) 21 | { 22 | /* Disable SysTick */ 23 | 24 | /* 25 | * Note: AM335 has the calibration value 26 | * and hence that is a better option (if used) 27 | * SysTick->CTRL = 0; 28 | */ 29 | } 30 | 31 | /* Update the clock source/frequency if we know what to do based on OPP */ 32 | void system_core_clock_update(void) 33 | { 34 | 35 | } 36 | 37 | /* systick interrupt handler */ 38 | void systick_handler(void) 39 | { 40 | /* 41 | * We don't necessarily need timer based delays in the firmware 42 | * If needed in the future, the way we could do this is 43 | * 1. Initialise a global timer_count variable 44 | * 2. Switch to the 10ms mode in SysTick module and use calibration value 45 | * as the reload value on timer expiry 46 | * 3. Enable timer interrupts 47 | * 4. In the IRQ handler we just increment timer_count 48 | * Note: Will need to take care of wraparound condition 49 | */ 50 | } 51 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Source: http://arago-project.org/git/projects/?p=am33x-cm3.git;a=summary 2 | 3 | This is the README for the Cortex-M3 (CM3) firmware for power management 4 | on Texas Instruments' AM33XX series of SoCs. 5 | 6 | AM33XX integrates a Cortex-M3 core to manage the entry/exit of various 7 | standy-by and deep-sleep mode. More info on this is present in the 8 | AM335X Techinal Reference Manual (TRM) available @ www.ti.com 9 | 10 | DOCUMENTATION: 11 | 12 | - The CM3 firmware design document can be found under the 13 | Documentation/ folder. SA_PM_Firmware.pdf is the best place to start. 14 | 15 | - Most of the diagrams used in the pdf were created using 16 | Dia, a GTK+ based digram creation program. The original 17 | *.dia files are also available under Documentation/ 18 | 19 | - For more technical detailis refer to the TRM on the TI website. 20 | 21 | COMPILING the firmare: 22 | 23 | - Refer to the AM335x PSP User-guide for the toolchain to be used for 24 | the Linux kernel compilation and how to get it. The same toolchain 25 | needs to be used for compiling the CM3 firmware. 26 | 27 | - With the toolchain installed and PATH setup to point to it, do a 28 | "make" to create the CM3 firmware. The binary and ELF files are 29 | by default put in the bin/ folder. 30 | 31 | - The binary file needs to be loaded to CM3 from the Cortex-A8 core 32 | before all the PM features are available. 33 | 34 | - For using the CM3 firmware with the Linux kernel refer to the 35 | the PSP User Guide 36 | 37 | PREBUILT binary: 38 | 39 | - Prebuilt binaries are available under the bin/ folder 40 | -------------------------------------------------------------------------------- /src/foundation/cm3.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | void nvic_enable_irq(int irq_no) 20 | { 21 | int reg_offset = irq_no/32; 22 | 23 | int irq_reg; 24 | 25 | irq_reg = __raw_readl(NVIC_IRQ_SET_EN1 + (reg_offset*0x4)); 26 | irq_reg |= (1 << (irq_no%32)); 27 | 28 | __raw_writel(irq_reg, (NVIC_IRQ_SET_EN1 + (reg_offset*0x4))); 29 | 30 | } 31 | 32 | void nvic_disable_irq(int irq_no) 33 | { 34 | int reg_offset = irq_no/32; 35 | 36 | int irq_reg; 37 | 38 | irq_reg = __raw_readl(NVIC_IRQ_CLR_EN1 + (reg_offset*0x4)); 39 | irq_reg |= (1 << (irq_no%32)); 40 | 41 | __raw_writel(irq_reg, (NVIC_IRQ_CLR_EN1 + (reg_offset*0x4))); 42 | 43 | } 44 | 45 | void nvic_clear_irq(int irq_no) 46 | { 47 | int reg_offset = irq_no/32; 48 | 49 | int irq_reg; 50 | 51 | irq_reg = __raw_readl(NVIC_IRQ_CLR_PEND1 + (reg_offset*0x4)); 52 | irq_reg |= (1 << (irq_no%32)); 53 | 54 | __raw_writel(irq_reg, (NVIC_IRQ_CLR_PEND1 + (reg_offset*0x4))); 55 | 56 | } 57 | 58 | void scr_enable_sleepdeep() 59 | { 60 | int scr_reg; 61 | 62 | scr_reg = __raw_readl(SYS_SCR); 63 | scr_reg |= (1< 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | void a8_notify(int cmd_stat_value) 21 | { 22 | msg_cmd_stat_update(cmd_stat_value); 23 | __asm("sev"); 24 | } 25 | 26 | /* If only notification is needed, use the a8_notify() API */ 27 | void a8_m3_low_power_sync(int cmd_stat_value) 28 | { 29 | /* Disable this part for now */ 30 | /* for CPU idle request only update STAT registers */ 31 | if (cmd_id == 0x10) 32 | msg_cmd_stat_update(cmd_stat_value); 33 | else 34 | a8_notify(cmd_stat_value); 35 | 36 | /* Enable the PRCM interrupt for MPU gated state */ 37 | nvic_enable_irq(AM335X_IRQ_PRCM_M3_IRQ2); 38 | } 39 | 40 | void init_m3_state_machine(void) 41 | { 42 | int i = 0; 43 | 44 | /* Flush out NVIC interrupts */ 45 | for (i=0; i 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | int am335_init(void) 20 | { 21 | int i; 22 | 23 | /* 24 | * Each interrupt has a priority register associated with it 25 | * 8 bits... only 7:6:5:4 are available for SA 26 | * out of the 16 levels here... using a priority grouping 27 | * these 4 bits can be further split into preempt priority 28 | * and subpriority fields 29 | */ 30 | scr_enable_sleepdeep(); 31 | scr_enable_sleeponexit(); 32 | 33 | /* Disable all the external interrupts */ 34 | for (i=0; i 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | /* 21 | * PRCM_M3_IRQ1: Triggered for events like PLL needs recalibration, 22 | * domain transition completed 23 | */ 24 | void extint16_handler() 25 | { 26 | while(1) 27 | ; 28 | } 29 | 30 | /* MBINT0: Triggered on a dummy write to Mailbox module */ 31 | void extint31_handler() 32 | { 33 | nvic_disable_irq(AM335X_IRQ_MBINT0); 34 | 35 | /* 36 | * If command is not valid, need to update the status to FAIL 37 | * and enable the mailbox interrupt back 38 | */ 39 | if (!msg_cmd_is_valid()) { 40 | msg_cmd_stat_update(CMD_STAT_FAIL); 41 | nvic_enable_irq(AM335X_IRQ_MBINT0); 42 | return; 43 | } 44 | 45 | /* cmd was valid */ 46 | if (msg_cmd_needs_trigger()) { 47 | a8_m3_low_power_sync(CMD_STAT_WAIT4OK); 48 | nvic_enable_irq(AM335X_IRQ_MBINT0); 49 | return; 50 | } else { 51 | /* For Rev and S/M reset */ 52 | msg_cmd_dispatcher(); 53 | /* XXX: Analysis of why this is needed is TBD */ 54 | nvic_enable_irq(AM335X_IRQ_MBINT0); 55 | return; 56 | } 57 | } 58 | 59 | /* USBWAKEUP */ 60 | void extint33_handler() 61 | { 62 | nvic_disable_irq(AM335X_IRQ_USBWAKEUP); 63 | generic_wake_handler(AM335X_IRQ_USBWAKEUP); 64 | } 65 | 66 | /* PRCM_M3_IRQ2: Triggered when A8 executes WFI */ 67 | void extint34_handler() 68 | { 69 | int i = 0; 70 | 71 | /* Flush out ALL the NVIC interrupts */ 72 | for (i=0; i 17 | 18 | #define CM3_VERSION 0x181 19 | 20 | #define MOSC_OFF 0x0 21 | #define MOSC_ON 0x1 22 | 23 | #define DS_COUNT_DEFAULT 0x6A75 24 | #define DS_COUNT_SHIFT 0 25 | #define DS_COUNT_MASK (0xffff << DS_COUNT_SHIFT) 26 | #define DS_ENABLE_SHIFT 17 27 | #define DS_ENABLE_MASK (1 << DS_ENABLE_SHIFT) 28 | 29 | 30 | #define PD_ON 0x3 31 | #define PD_RET 0x1 32 | #define PD_OFF 0x0 33 | 34 | #define MEM_BANK_RET_ST_RET 0x1 35 | #define MEM_BANK_RET_ST_OFF 0x0 36 | 37 | #define MEM_BANK_ON_ST_ON 0x3 38 | #define MEM_BANK_ON_ST_RET 0x1 39 | #define MEM_BANK_ON_ST_OFF 0x0 40 | 41 | #define WAKE_ALL 0x1fff 42 | 43 | #define RTC_TIMEOUT_DEFAULT 0x2 44 | #define RTC_TIMEOUT_MAX 0xf 45 | 46 | struct rtc_data { 47 | int rtc_timeout_val :4; /* Delay for RTC alarm timeout. Default = 2secs */ 48 | }; 49 | 50 | struct deep_sleep_data { 51 | int mosc_state :1; /* MOSC to be kept on (1) or off (0) */ 52 | int deepsleep_count :16; /* Count of how many OSC clocks needs to be seen \ 53 | before exiting deep sleep mode */ 54 | 55 | int vdd_mpu_val :15; /* If vdd_mpu is to be lowered, vdd_mpu in mV */ 56 | 57 | int pd_mpu_state :2; /* Powerstate of PD_MPU */ 58 | int pd_mpu_ram_ret_state :1; /* Sabertooth RAM in retention state */ 59 | int pd_mpu_l1_ret_state :1; /* L1 memory in retention state */ 60 | int pd_mpu_l2_ret_state :1; /* L2 memory in retention state */ 61 | int pd_mpu_ram_on_state :2; /* Sabertooth RAM in ON state */ 62 | 63 | int pd_per_state :2; /* Powerstate of PD_PER */ 64 | int pd_per_icss_mem_ret_state :1; /* ICSS memory in retention state */ 65 | int pd_per_mem_ret_state :1; /* Other memories in retention state */ 66 | int pd_per_ocmc_ret_state :1; /* OCMC memory in retention state */ 67 | int pd_per_icss_mem_on_state :2; /* ICSS memory in ON state */ 68 | int pd_per_mem_on_state :2; /* Other memories in ON state */ 69 | int pd_per_ocmc_on_state :2; /* OCMC memory in ON state */ 70 | 71 | int wake_sources :13; /* Wake sources */ 72 | /* USB, I2C0, RTC_ALARM, TIMER1 \ 73 | UART0, GPIO0_WAKE0, GPIO0_WAKE1, \ 74 | WDT1, ADTSC, RTC_TIMER, USBWOUT0, \ 75 | MPU, USBWOUT1 */ 76 | int reserved :1; /* Internal use */ 77 | }; 78 | 79 | int reg_mod(int, int, int); 80 | int debugss_keep_enabled(void); 81 | 82 | int module_state_change(int, int); 83 | int clkdm_state_change(int state, int reg); 84 | int interconnect_modules_enable(void); 85 | int interconnect_modules_disable(void); 86 | int essential_modules_disable(void); 87 | int essential_modules_enable(void); 88 | void mpu_disable(void); 89 | void mpu_enable(void); 90 | void clkdm_sleep(void); 91 | void clkdm_wake(void); 92 | void mpu_clkdm_sleep(void); 93 | void mpu_clkdm_wake(void); 94 | void wkup_clkdm_sleep(void); 95 | void wkup_clkdm_wake(void); 96 | int pd_state_change(int, int); 97 | void pd_state_restore(void); 98 | 99 | int mpu_ram_ret_state_change(int, int); 100 | int mpu_l1_ret_state_change(int, int); 101 | int mpu_l2_ret_state_change(int, int); 102 | int icss_mem_ret_state_change(int, int); 103 | int per_mem_ret_state_change(int, int); 104 | int ocmc_mem_ret_state_change(int, int); 105 | 106 | int mpu_ram_on_state_change(int, int); 107 | int icss_mem_on_state_change(int, int); 108 | int per_mem_on_state_change(int, int); 109 | int ocmc_mem_on_state_change(int, int); 110 | 111 | int per_powerst_change(int, int); 112 | int mpu_powerst_change(int, int); 113 | 114 | int get_pd_per_stctrl_val(int); 115 | int get_pd_mpu_stctrl_val(int); 116 | 117 | int verify_pd_transitions(void); 118 | 119 | int disable_master_oscillator(void); 120 | int enable_master_oscillator(void); 121 | 122 | void configure_deepsleep_count(int ds_count); 123 | void configure_wake_sources(int wake_sources,int mod_check); 124 | void configure_standby_wake_sources(int wake_sources, int mod_check); 125 | void clear_wake_sources(void); 126 | void enable_wake_sources_for_ds2(void); 127 | 128 | void dpll_power_down(unsigned int dpll); 129 | void dpll_power_up(unsigned int dpll); 130 | 131 | void core_ldo_power_down(void); 132 | void core_ldo_power_up(void); 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /src/include/system_am335.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #ifndef __SYSTEM_AM335_H__ 14 | #define __SYSTEM_AM335_H__ 15 | 16 | #include 17 | 18 | struct ipc_data { 19 | int reg1; 20 | int reg2; 21 | int reg3; 22 | int reg4; 23 | int reg5; 24 | int reg6; 25 | int reg7; 26 | int reg8; 27 | }; 28 | 29 | struct ds_data { 30 | int reg1; 31 | int reg2; 32 | }; 33 | 34 | 35 | struct cmd_data { 36 | short cmd_id; 37 | void *data; 38 | }; 39 | 40 | struct cmd_data cmd_global_data; 41 | struct ipc_data a8_m3_data_r; 42 | struct ipc_data a8_m3_data_w; 43 | struct ds_data a8_m3_ds_data; 44 | 45 | int ipc_reg_r; 46 | int ipc_reg_w; 47 | 48 | short cmd_id; 49 | short cmd_stat; 50 | 51 | int cmd_wake_sources; 52 | int pd_mpu_stctrl_next_val; 53 | int pd_mpu_stctrl_prev_val; 54 | int pd_per_stctrl_next_val; 55 | int pd_per_stctrl_prev_val; 56 | int pd_mpu_pwrstst_next_val; 57 | int pd_mpu_pwrstst_prev_val; 58 | int pd_per_pwrstst_next_val; 59 | int pd_per_pwrstst_prev_val; 60 | 61 | unsigned int am335x_soc_rev; 62 | 63 | void pm_init(void); 64 | 65 | void system_init(void); 66 | void system_core_clock_update(void); 67 | 68 | void msg_init(void); 69 | void msg_read(char); 70 | void msg_read_all(void); 71 | void msg_write(char); 72 | void msg_write_all(void); 73 | 74 | int msg_cmd_is_valid(void); 75 | int msg_cmd_needs_trigger(void); 76 | void msg_cmd_dispatcher(void); 77 | void msg_cmd_stat_update(int); 78 | 79 | void a8_notify(int); 80 | void a8_m3_low_power_sync(int); 81 | 82 | void a8_lp_cmd1_handler(struct cmd_data *, char); 83 | void a8_lp_cmd2_handler(struct cmd_data *, char); 84 | void a8_lp_cmd3_handler(struct cmd_data *, char); 85 | void a8_lp_cmd5_handler(struct cmd_data *, char); 86 | void a8_lp_cmd7_handler(struct cmd_data *, char); 87 | void a8_standalone_handler(struct cmd_data *); 88 | void a8_standby_handler(struct cmd_data *, char); 89 | void a8_cpuidle_handler(struct cmd_data *, char); 90 | 91 | void generic_wake_handler(int); 92 | void a8_wake_cmd1_handler(void); 93 | void a8_wake_cmd2_handler(void); 94 | void a8_wake_cmd3_handler(void); 95 | void a8_wake_cmd5_handler(void); 96 | void a8_wake_cmd7_handler(void); 97 | void a8_wake_cmdb_handler(void); 98 | void a8_wake_cmd10_handler(void); 99 | 100 | void m3_firmware_version(void); 101 | void init_m3_state_machine(void); 102 | 103 | void trace_init(void); 104 | void trace_update(void); 105 | void trace_get_current_pos(void); 106 | void trace_set_current_pos(void); 107 | 108 | int rtc_enable_check(void); 109 | int rtc_reg_read(int); 110 | void rtc_reg_write(int, int); 111 | 112 | void setup_am335x_soc_revision(void); 113 | unsigned int get_am335x_soc_rev(void); 114 | 115 | #define BITBAND_SRAM_REF UMEM_ALIAS 116 | #define BITBAND_SRAM_BASE 0x22000000 117 | #define BITBAND_SRAM(a,b) ((BITBAND_SRAM_BASE + ((int)(a))*32 + (b*4))) 118 | 119 | #define BITBAND_PERI_REF DMEM_ALIAS 120 | #define BITBAND_PERI_BASE 0x42000000 121 | #define BITBAND_PERI(a,b) ((BITBAND_PERI_BASE + (*(a) - BITBAND_PERI_REF)*32 + (b*4))) 122 | 123 | #define BB_USB_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 0))) 124 | #define BB_I2C0_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 1))) 125 | #define BB_RTC_ALARM_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 2))) 126 | #define BB_TIMER1_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 3))) 127 | #define BB_UART0_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 4))) 128 | #define BB_GPIO0_WAKE0 *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 5))) 129 | #define BB_GPIO0_WAKE1 *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 6))) 130 | #define BB_WDT1_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 7))) 131 | #define BB_ADTSC_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 8))) 132 | /* Not used currently */ 133 | #define BB_RTC_TIMER_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 9))) 134 | #define BB_USBWOUT0 *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 10))) 135 | #define BB_MPU_WAKE *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 11))) 136 | #define BB_USBWOUT1 *((volatile int *)(BITBAND_SRAM(&cmd_wake_sources, 12))) 137 | 138 | #define PD_MPU 0x1 139 | #define PD_PER 0x2 140 | 141 | #define MODULE_DISABLE 0x0 142 | #define MODULE_ENABLE 0x2 143 | 144 | #define CD_DISABLE 0x0 145 | #define CD_ENABLE 0x2 146 | 147 | #define PD_DISABLE 0x0 148 | #define PD_ENABLE 0x2 149 | 150 | #define TRACE_REG 0x0 151 | #define STAT_ID_REG 0x1 152 | #define PARAM1_REG 0x2 153 | #define PARAM2_REG 0x3 154 | #define RES1_REG 0x4 155 | #define RES2_REG 0x5 156 | #define RES3_REG 0x6 157 | #define CUST_REG 0x7 158 | 159 | #define CMD_STAT_PASS 0x0 160 | #define CMD_STAT_FAIL 0x1 161 | #define CMD_STAT_WAIT4OK 0x2 162 | 163 | #define SET_BIT(x) (1< 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | short valid_cmd_id[] = { 20 | 0x1, /* RTC */ 21 | 0x2, /* RTC_FAST */ 22 | 0x3, /* DS0 */ 23 | 0x5, /* DS1 */ 24 | 0x7, /* DS2 */ 25 | 0x9, /* Standalone app */ 26 | 0xb, /* Standby */ 27 | 0xe, /* Reset State Machine */ 28 | 0xf, /* Version */ 29 | 0x10, /* CPUIdle MPU Clock gating*/ 30 | }; 31 | 32 | /* Clear out the IPC regs */ 33 | void msg_init(void) 34 | { 35 | /* TODO: Global data related to msg also? */ 36 | a8_m3_data_r.reg1 = 0; 37 | a8_m3_data_r.reg2 = 0; 38 | a8_m3_data_r.reg3 = 0; 39 | a8_m3_data_r.reg4 = 0; 40 | a8_m3_data_r.reg5 = 0; 41 | a8_m3_data_r.reg6 = 0; 42 | a8_m3_data_r.reg7 = 0; 43 | a8_m3_data_r.reg8 = 0; 44 | 45 | a8_m3_data_w.reg1 = 0; 46 | a8_m3_data_w.reg2 = 0; 47 | a8_m3_data_w.reg3 = 0; 48 | a8_m3_data_w.reg4 = 0; 49 | a8_m3_data_w.reg5 = 0; 50 | a8_m3_data_w.reg6 = 0; 51 | a8_m3_data_w.reg7 = 0; 52 | a8_m3_data_w.reg8 = 0; 53 | 54 | ipc_reg_r = 0; 55 | ipc_reg_w = 0; 56 | } 57 | 58 | /* Read all the IPC registers in one-shot */ 59 | void msg_read_all(void) 60 | { 61 | a8_m3_data_r.reg1 = __raw_readl(IPC_MSG_REG1); 62 | a8_m3_data_r.reg2 = __raw_readl(IPC_MSG_REG2); 63 | a8_m3_data_r.reg3 = __raw_readl(IPC_MSG_REG3); 64 | a8_m3_data_r.reg4 = __raw_readl(IPC_MSG_REG4); 65 | a8_m3_data_r.reg5 = __raw_readl(IPC_MSG_REG5); 66 | a8_m3_data_r.reg6 = __raw_readl(IPC_MSG_REG6); 67 | a8_m3_data_r.reg7 = __raw_readl(IPC_MSG_REG7); 68 | a8_m3_data_r.reg8 = __raw_readl(IPC_MSG_REG8); 69 | } 70 | 71 | /* Read one specific IPC register */ 72 | void msg_read(char reg) 73 | { 74 | ipc_reg_r = __raw_readl(IPC_MSG_REG1 + (0x4*reg)); 75 | __raw_writel(ipc_reg_r, (int)(&a8_m3_data_r) + (0x4*reg)); 76 | } 77 | 78 | /* Write all the IPC registers in one-shot */ 79 | void msg_write_all(void) 80 | { 81 | __raw_writel(a8_m3_data_w.reg1, IPC_MSG_REG1); 82 | __raw_writel(a8_m3_data_w.reg2, IPC_MSG_REG2); 83 | __raw_writel(a8_m3_data_w.reg3, IPC_MSG_REG3); 84 | __raw_writel(a8_m3_data_w.reg4, IPC_MSG_REG4); 85 | __raw_writel(a8_m3_data_w.reg5, IPC_MSG_REG5); 86 | __raw_writel(a8_m3_data_w.reg6, IPC_MSG_REG6); 87 | __raw_writel(a8_m3_data_w.reg7, IPC_MSG_REG7); 88 | /* TODO: Has to the removed since this is reserved */ 89 | __raw_writel(a8_m3_data_w.reg8, IPC_MSG_REG8); 90 | } 91 | 92 | /* 93 | * Write to one specific IPC register 94 | * Before calling this fn, make sure ipc_reg_w has the correct val 95 | * TODO: Should check for the reg no. as some are reserved? 96 | */ 97 | void msg_write(char reg) 98 | { 99 | __raw_writel(ipc_reg_w, IPC_MSG_REG1 + (0x4*reg)); 100 | __raw_writel(ipc_reg_w, (int)(&a8_m3_data_w) + (0x4*reg)); 101 | } 102 | 103 | /* 104 | * Check if the cmd_id is valid or not 105 | * return 1 on success, 0 on failure 106 | */ 107 | int msg_cmd_is_valid(void) 108 | { 109 | int cmd_cnt = 0; 110 | 111 | msg_read(STAT_ID_REG); 112 | 113 | /* Extract the CMD_ID field of 16 bits */ 114 | cmd_id = ipc_reg_r & 0xffff; 115 | 116 | for(; cmd_cnt < sizeof(valid_cmd_id)/sizeof(short); cmd_cnt++) { 117 | if(valid_cmd_id[cmd_cnt] == cmd_id) 118 | return 1; 119 | } 120 | 121 | return 0; 122 | } 123 | 124 | /* Read all the IPC regs and pass it along to the appropriate handler */ 125 | void msg_cmd_dispatcher() 126 | { 127 | char use_default_val = 0; 128 | 129 | msg_read_all(); 130 | 131 | if ((a8_m3_data_r.reg3 == 0xffffffff) && 132 | (a8_m3_data_r.reg4 == 0xffffffff)) 133 | use_default_val = 1; 134 | 135 | a8_m3_ds_data.reg1 = a8_m3_data_r.reg3; 136 | a8_m3_ds_data.reg2 = a8_m3_data_r.reg4; 137 | 138 | cmd_global_data.data = &a8_m3_ds_data; 139 | cmd_global_data.cmd_id = cmd_id; 140 | 141 | switch(cmd_id) { 142 | case 0x1: 143 | a8_lp_cmd1_handler(&cmd_global_data, use_default_val); /* RTC */ 144 | break; 145 | case 0x2: 146 | a8_lp_cmd2_handler(&cmd_global_data, use_default_val); /* RTC_fast */ 147 | break; 148 | case 0x3: 149 | a8_lp_cmd3_handler(&cmd_global_data, use_default_val); /* DS0 */ 150 | break; 151 | case 0x5: 152 | a8_lp_cmd5_handler(&cmd_global_data, use_default_val); /* DS1 */ 153 | break; 154 | case 0x7: 155 | a8_lp_cmd7_handler(&cmd_global_data, use_default_val); /* DS2 */ 156 | break; 157 | case 0x9: 158 | a8_standalone_handler(&cmd_global_data); 159 | break; 160 | case 0xb: 161 | a8_standby_handler(&cmd_global_data, use_default_val); /* Standby */ 162 | break; 163 | case 0xe: 164 | init_m3_state_machine(); /* Reset M3 state machine */ 165 | break; 166 | case 0x10: 167 | a8_cpuidle_handler(&cmd_global_data, use_default_val); /* cpuidle MPU Clock gating */ 168 | break; 169 | case 0xf: 170 | default: 171 | m3_firmware_version(); 172 | } 173 | } 174 | 175 | void m3_firmware_version(void) 176 | { 177 | msg_read(PARAM1_REG); 178 | ipc_reg_r &= 0xffff0000; 179 | ipc_reg_w = ipc_reg_r | CM3_VERSION; 180 | msg_write(PARAM1_REG); 181 | } 182 | 183 | void msg_cmd_stat_update(int cmd_stat_value) 184 | { 185 | msg_read(STAT_ID_REG); 186 | ipc_reg_r &= 0x0000ffff; 187 | ipc_reg_w = ipc_reg_r | (cmd_stat_value << 16); 188 | msg_write(STAT_ID_REG); 189 | } 190 | 191 | /* 192 | * Check whether command needs a trigger or not 193 | * returns 1 if trigger is needed 194 | * returns 0 if trigger is not needed (eg: checking the version) 195 | */ 196 | int msg_cmd_needs_trigger(void) 197 | { 198 | msg_read(STAT_ID_REG); 199 | 200 | /* Version and state machine reset commands do not need a trigger */ 201 | if ((cmd_id == 0xf || cmd_id == 0xe)) 202 | return 0; 203 | else 204 | return 1; 205 | } 206 | -------------------------------------------------------------------------------- /src/include/prmam335x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #ifndef __PRMAM335X_H 14 | #define __PRMAM335X_H 15 | 16 | #define AM335X_PRM_BASE 0x44E00000 17 | 18 | #define AM335X_PRM_REGADDR(inst, reg) \ 19 | (AM335X_PRM_BASE + (inst) + (reg)) 20 | 21 | /* PRM instances */ 22 | #define AM335X_PRM_OCP_SOCKET_MOD 0x0B00 23 | #define AM335X_PRM_PER_MOD 0x0C00 24 | #define AM335X_PRM_WKUP_MOD 0x0D00 25 | #define AM335X_PRM_MPU_MOD 0x0E00 26 | #define AM335X_PRM_DEVICE_MOD 0x0F00 27 | #define AM335X_PRM_RTC_MOD 0x1000 28 | #define AM335X_PRM_GFX_MOD 0x1100 29 | #define AM335X_PRM_CEFUSE_MOD 0x1200 30 | 31 | /* OMAP4 specific register offsets */ 32 | #define AM335X_PM_PWSTCTRL 0x0000 33 | #define AM335X_PM_PWSTST 0x0004 34 | 35 | 36 | /* PRM */ 37 | 38 | /* PRM.OCP_SOCKET_PRM register offsets */ 39 | #define AM335X_REVISION_PRM_OFFSET 0x0000 40 | #define AM335X_REVISION_PRM AM335X_PRM_REGADDR(AM335X_PRM_OCP_SOCKET_MOD, 0x0000) 41 | #define AM335X_PRM_IRQSTATUS_MPU_OFFSET 0x0004 42 | #define AM335X_PRM_IRQSTATUS_MPU AM335X_PRM_REGADDR(AM335X_PRM_OCP_SOCKET_MOD, 0x0004) 43 | #define AM335X_PRM_IRQENABLE_MPU_OFFSET 0x0008 44 | #define AM335X_PRM_IRQENABLE_MPU AM335X_PRM_REGADDR(AM335X_PRM_OCP_SOCKET_MOD, 0x0008) 45 | #define AM335X_PRM_IRQSTATUS_M3_OFFSET 0x000c 46 | #define AM335X_PRM_IRQSTATUS_M3 AM335X_PRM_REGADDR(AM335X_PRM_OCP_SOCKET_MOD, 0x000c) 47 | #define AM335X_PRM_IRQENABLE_M3_OFFSET 0x0010 48 | #define AM335X_PRM_IRQENABLE_M3 AM335X_PRM_REGADDR(AM335X_PRM_OCP_SOCKET_MOD, 0x0010) 49 | 50 | /* PRM.PER_PRM register offsets */ 51 | #define AM335X_RM_PER_RSTCTRL_OFFSET 0x0000 52 | #define AM335X_RM_PER_RSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_PER_MOD, 0x0000) 53 | #define AM335X_RM_PER_RSTST_OFFSET 0x0004 54 | #define AM335X_RM_PER_RSTST AM335X_PRM_REGADDR(AM335X_PRM_PER_MOD, 0x0004) 55 | #define AM335X_PM_PER_PWRSTST_OFFSET 0x0008 56 | #define AM335X_PM_PER_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_PER_MOD, 0x0008) 57 | #define AM335X_PM_PER_PWRSTCTRL_OFFSET 0x000c 58 | #define AM335X_PM_PER_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_PER_MOD, 0x000c) 59 | 60 | /* PRM.WKUP_PRM register offsets */ 61 | #define AM335X_RM_WKUP_RSTCTRL_OFFSET 0x0000 62 | #define AM335X_RM_WKUP_RSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_WKUP_MOD, 0x0000) 63 | #define AM335X_PM_WKUP_PWRSTCTRL_OFFSET 0x0004 64 | #define AM335X_PM_WKUP_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_WKUP_MOD, 0x0004) 65 | #define AM335X_PM_WKUP_PWRSTST_OFFSET 0x0008 66 | #define AM335X_PM_WKUP_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_WKUP_MOD, 0x0008) 67 | #define AM335X_RM_WKUP_RSTST_OFFSET 0x000c 68 | #define AM335X_RM_WKUP_RSTST AM335X_PRM_REGADDR(AM335X_PRM_WKUP_MOD, 0x000c) 69 | 70 | /* PRM.MPU_PRM register offsets */ 71 | #define AM335X_PM_MPU_PWRSTCTRL_OFFSET 0x0000 72 | #define AM335X_PM_MPU_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_MPU_MOD, 0x0000) 73 | #define AM335X_PM_MPU_PWRSTST_OFFSET 0x0004 74 | #define AM335X_PM_MPU_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_MPU_MOD, 0x0004) 75 | #define AM335X_RM_MPU_RSTST_OFFSET 0x0008 76 | #define AM335X_RM_MPU_RSTST AM335X_PRM_REGADDR(AM335X_PRM_MPU_MOD, 0x0008) 77 | 78 | /* PRM.DEVICE_PRM register offsets */ 79 | #define AM335X_PRM_RSTCTRL_OFFSET 0x0000 80 | #define AM335X_PRM_RSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0000) 81 | #define AM335X_PRM_RSTTIME_OFFSET 0x0004 82 | #define AM335X_PRM_RSTTIME AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0004) 83 | #define AM335X_PRM_RSTST_OFFSET 0x0008 84 | #define AM335X_PRM_RSTST AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0008) 85 | #define AM335X_PRM_SRAM_COUNT_OFFSET 0x000c 86 | #define AM335X_PRM_SRAM_COUNT AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x000c) 87 | #define AM335X_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x0010 88 | #define AM335X_PRM_LDO_SRAM_CORE_SETUP AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0010) 89 | #define AM335X_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x0014 90 | #define AM335X_PRM_LDO_SRAM_CORE_CTRL AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0014) 91 | #define AM335X_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x0018 92 | #define AM335X_PRM_LDO_SRAM_MPU_SETUP AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x0018) 93 | #define AM335X_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x001c 94 | #define AM335X_PRM_LDO_SRAM_MPU_CTRL AM335X_PRM_REGADDR(AM335X_PRM_DEVICE_MOD, 0x001c) 95 | 96 | /* PRM.RTC_PRM register offsets */ 97 | #define AM335X_PM_RTC_PWRSTCTRL_OFFSET 0x0000 98 | #define AM335X_PM_RTC_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_RTC_MOD, 0x0000) 99 | #define AM335X_PM_RTC_PWRSTST_OFFSET 0x0004 100 | #define AM335X_PM_RTC_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_RTC_MOD, 0x0004) 101 | 102 | /* PRM.GFX_PRM register offsets */ 103 | #define AM335X_PM_GFX_PWRSTCTRL_OFFSET 0x0000 104 | #define AM335X_PM_GFX_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_GFX_MOD, 0x0000) 105 | #define AM335X_RM_GFX_RSTCTRL_OFFSET 0x0004 106 | #define AM335X_RM_GFX_RSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_GFX_MOD, 0x0004) 107 | #define AM335X_PM_GFX_PWRSTST_OFFSET 0x0010 108 | #define AM335X_PM_GFX_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_GFX_MOD, 0x0010) 109 | #define AM335X_RM_GFX_RSTST_OFFSET 0x0014 110 | #define AM335X_RM_GFX_RSTST AM335X_PRM_REGADDR(AM335X_PRM_GFX_MOD, 0x0014) 111 | 112 | /* PRM.CEFUSE_PRM register offsets */ 113 | #define AM335X_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000 114 | #define AM335X_PM_CEFUSE_PWRSTCTRL AM335X_PRM_REGADDR(AM335X_PRM_CEFUSE_MOD, 0x0000) 115 | #define AM335X_PM_CEFUSE_PWRSTST_OFFSET 0x0004 116 | #define AM335X_PM_CEFUSE_PWRSTST AM335X_PRM_REGADDR(AM335X_PRM_CEFUSE_MOD, 0x0004) 117 | 118 | /* AM335X_PRM_LDO_SRAM_CORE_CTRL register bit-fields */ 119 | #define SRAM_IN_TRANSITION (1 << 9) 120 | #define SRAMLDO_STATUS (1 << 8) 121 | #define RETMODE_ENABLE (1 << 0) 122 | 123 | /* AM335X_PM_PER_PWRSTST register bit-fields */ 124 | #define PWR_STATE_STS_MASK (3 << 0) 125 | #define POWER_STATE_STS_RET (1 << 0) 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /src/include/device_am335x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #ifndef __DEVICE_AM335X_H__ 14 | #define __DEVICE_AM335X_H__ 15 | 16 | #define AM335X_IRQ_PRCM_M3_IRQ1 16 17 | #define AM335X_IRQ_UART0INT 17 18 | #define AM335X_IRQ_TINT0 18 19 | #define AM335X_IRQ_TINT1_1MS 19 20 | #define AM335X_IRQ_WDT0INT 20 21 | #define AM335X_IRQ_WDT1INT 21 22 | #define AM335X_IRQ_I2C0INT 22 23 | #define AM335X_IRQ_GPIOINTA 23 24 | #define AM335X_IRQ_GPIOINTB 24 25 | #define AM335X_IRQ_ADC_TSC_INT1 26 26 | #define AM335X_IRQ_RTCINT1 27 27 | #define AM335X_IRQ_RTCALARMINT 28 28 | #define AM335X_IRQ_SMRFLX_MPU 29 29 | #define AM335X_IRQ_SMRFLX_CORE 30 30 | #define AM335X_IRQ_MBINT0 31 31 | #define AM335X_IRQ_USBWAKEUP 33 32 | #define AM335X_IRQ_PRCM_M3_IRQ2 34 33 | #define AM335X_IRQ_USB0WOUT 35 34 | #define AM335X_IRQ_USB1WOUT 36 35 | #define AM335X_IRQ_DMA_INTR_PIN1 37 36 | #define AM335X_IRQ_DMA_INTR_PIN2 38 37 | #define AM335X_IRQ_I2C0_WAKE 40 38 | #define AM335X_IRQ_RTC_TIMER_WAKE 41 39 | #define AM335X_IRQ_RTC_ALARM_WAKE 42 40 | #define AM335X_IRQ_TIMER0_WAKE 43 41 | #define AM335X_IRQ_TIMER1_WAKE 44 42 | #define AM335X_IRQ_UART0_WAKE 45 43 | #define AM335X_IRQ_GPIO0_WAKE0 46 44 | #define AM335X_IRQ_GPIO0_WAKE1 47 45 | #define AM335X_IRQ_MPU_WAKE 48 46 | #define AM335X_IRQ_WDT0_WAKE 49 47 | #define AM335X_IRQ_WDT1_WAKE 50 48 | #define AM335X_IRQ_ADC_TSC_WAKE 51 49 | 50 | #define AM335X_NUM_EXT_INTERRUPTS 52 51 | 52 | #define UMEM_BASE 0x00000000 53 | #define DMEM_BASE 0x00080000 54 | #define UMEM_BASE_ALIAS 0x20000000 55 | #define DMEM_BASE_ALIAS 0x20080000 56 | #define L4_WKUP_BASE 0x44C00000 57 | 58 | #define UMEM_START 0x0 59 | #define UMEM_ALIAS 0x20000000 60 | #define UMEM_SIZE 0x3FFF /* 16 KB */ 61 | 62 | #define DMEM_START 0x80000 63 | #define DMEM_ALIAS 0x20080000 64 | #define DMEM_SIZE 0x1FFF /* 8 KB */ 65 | 66 | #define CM3_STACK_SIZE (0xC00) /* 3KB */ 67 | #define CM3_SP (DMEM_START + CM3_STACK_SIZE) 68 | 69 | #define PRCM_BASE 0x44E00000 70 | #define DMTIMER_BASE 0x44E05000 71 | #define GPIO_BASE 0x44E07000 72 | #define UART0_BASE 0x44E09000 73 | #define I2C0_BASE 0x44E0B000 74 | #define ADC_TSC_BASE 0x44E0D000 75 | #define CONTROL_BASE 0x44E10000 76 | #define DMTIMER1_BASE 0x44E31000 77 | #define WDT0_BASE 0x44E33000 78 | #define WDT1_BASE 0x44E35000 79 | #define SR0_BASE 0x44E37000 80 | #define SR1_BASE 0x44E39000 81 | #define RTCSS_BASE 0x44E3E000 82 | 83 | /* RTC module */ 84 | 85 | #define RTC_SECONDS_REG (RTCSS_BASE + 0x00) 86 | #define RTC_MINUTES_REG (RTCSS_BASE + 0x04) 87 | #define RTC_HOURS_REG (RTCSS_BASE + 0x08) 88 | #define RTC_DAYS_REG (RTCSS_BASE + 0x0C) 89 | #define RTC_MONTHS_REG (RTCSS_BASE + 0x10) 90 | #define RTC_YEARS_REG (RTCSS_BASE + 0x14) 91 | #define RTC_WEEKS_REG (RTCSS_BASE + 0x18) 92 | 93 | #define RTC_ALARM_SECONDS_REG (RTCSS_BASE + 0x20) 94 | #define RTC_ALARM_MINUTES_REG (RTCSS_BASE + 0x24) 95 | #define RTC_ALARM_HOURS_REG (RTCSS_BASE + 0x28) 96 | #define RTC_ALARM_DAYS_REG (RTCSS_BASE + 0x2c) 97 | #define RTC_ALARM_MONTHS_REG (RTCSS_BASE + 0x30) 98 | #define RTC_ALARM_YEARS_REG (RTCSS_BASE + 0x34) 99 | 100 | #define RTC_CTRL_REG (RTCSS_BASE + 0x40) 101 | #define RTC_STATUS_REG (RTCSS_BASE + 0x44) 102 | #define RTC_INTERRUPTS_REG (RTCSS_BASE + 0x48) 103 | #define RTC_COMP_LSB_REG (RTCSS_BASE + 0x4c) 104 | #define RTC_COMP_MSB_REG (RTCSS_BASE + 0x50) 105 | #define RTC_OSC_REG (RTCSS_BASE + 0x54) 106 | 107 | #define RTC_KICK0 (RTCSS_BASE + 0x6c) 108 | #define RTC_KICK1 (RTCSS_BASE + 0x70) 109 | #define RTC_SYSCONFIG (RTCSS_BASE + 0x78) 110 | #define RTC_IRQWAKEEN_0 (RTCSS_BASE + 0x7c) 111 | 112 | #define RTC_ALARM2_SECONDS_REG (RTCSS_BASE + 0x80) 113 | #define RTC_ALARM2_MINUTES_REG (RTCSS_BASE + 0x84) 114 | #define RTC_ALARM2_HOURS_REG (RTCSS_BASE + 0x88) 115 | #define RTC_ALARM2_DAYS_REG (RTCSS_BASE + 0x8c) 116 | #define RTC_ALARM2_MONTHS_REG (RTCSS_BASE + 0x90) 117 | #define RTC_ALARM2_YEARS_REG (RTCSS_BASE + 0x94) 118 | 119 | #define RTC_PMIC_REG (RTCSS_BASE + 0x98) 120 | #define RTC_DEBOUNCE_REG (RTCSS_BASE + 0x9c) 121 | 122 | /* RTC_CTRL_REG bit fields: */ 123 | #define RTC_CTRL_DISABLE (1<<6) 124 | #define RTC_CTRL_STOP (1<<0) 125 | 126 | /* RTC_STATUS_REG bit fields: */ 127 | #define RTC_STATUS_POWER_UP (1<<7) 128 | #define RTC_STATUS_ALARM (1<<6) 129 | #define RTC_STATUS_1D_EVENT (1<<5) 130 | #define RTC_STATUS_1H_EVENT (1<<4) 131 | #define RTC_STATUS_1M_EVENT (1<<3) 132 | #define RTC_STATUS_1S_EVENT (1<<2) 133 | #define RTC_STATUS_RUN (1<<1) 134 | #define RTC_STATUS_BUSY (1<<0) 135 | 136 | /* RTC_INTERRUPTS_REG bit fields: */ 137 | #define RTC_INTERRUPTS_IT_ALARM (1<<3) 138 | #define RTC_INTERRUPTS_IT_TIMER (1<<2) 139 | 140 | #define IPC_MSG_REG1 (CONTROL_BASE + 0x1328) 141 | #define IPC_MSG_REG2 (CONTROL_BASE + 0x132c) 142 | #define IPC_MSG_REG3 (CONTROL_BASE + 0x1330) 143 | #define IPC_MSG_REG4 (CONTROL_BASE + 0x1334) 144 | #define IPC_MSG_REG5 (CONTROL_BASE + 0x1338) 145 | #define IPC_MSG_REG6 (CONTROL_BASE + 0x133c) 146 | #define IPC_MSG_REG7 (CONTROL_BASE + 0x1340) 147 | #define IPC_MSG_REG8 (CONTROL_BASE + 0x1344) 148 | 149 | #define DEEPSLEEP_CTRL (CONTROL_BASE + 0x0470) 150 | 151 | #define DEVICE_ID (CONTROL_BASE + 0x0600) 152 | 153 | #define DPLL_PWR_SW_STATUS (CONTROL_BASE + 0x050C) 154 | #define DPLL_PWR_SW_CTRL (CONTROL_BASE + 0x1318) 155 | #define SMA2_SPARE_REG (CONTROL_BASE + 0x1320) 156 | 157 | /* DPLL */ 158 | #define DPLL_PER 0 159 | #define DPLL_DISP 1 160 | #define DPLL_DDR 2 161 | 162 | /* DPLL_PWR_SW_STATUS bit fields: */ 163 | #define PGOODOUT_DDR_STATUS (1 << 25) 164 | #define PONOUT_DDR_STATUS (1 << 24) 165 | #define PGOODOUT_DISP_STATUS (1 << 17) 166 | #define PONOUT_DISP_STATUS (1 << 16) 167 | #define PGOODOUT_PER_STATUS (1 << 9) 168 | #define PONOUT_PER_STATUS (1 << 8) 169 | 170 | /* DPLL_PWR_SW_CTRL bit fields: */ 171 | #define SW_CTRL_DDR_DPLL (1 << 31) 172 | #define ISOSCAN_DDR (1 << 29) 173 | #define RET_DDR (1 << 28) 174 | #define RESET_DDR (1 << 27) 175 | #define ISO_DDR (1 << 26) 176 | #define PGOODIN_DDR (1 << 25) 177 | #define PONIN_DDR (1 << 24) 178 | #define SW_CTRL_DISP_DPLL (1 << 23) 179 | #define ISOSCAN_DISP (1 << 21) 180 | #define RET_DISP (1 << 20) 181 | #define RESET_DISP (1 << 19) 182 | #define ISO_DISP (1 << 18) 183 | #define PGOODIN_DISP (1 << 17) 184 | #define PONIN_DISP (1 << 16) 185 | #define SW_CTRL_PER_DPLL (1 << 15) 186 | #define ISOSCAN_PER (1 << 13) 187 | #define RET_PER (1 << 12) 188 | #define RESET_PER (1 << 11) 189 | #define ISO_PER (1 << 10) 190 | #define PGOODIN_PER (1 << 9) 191 | #define PONIN_PER (1 << 8) 192 | 193 | /* SMA2_SPARE_REG bit fields: */ 194 | #define VSLDO_CORE_AUTO_RAMP_EN (1 << 1) 195 | 196 | #define __raw_readl(a) (*(volatile int *)(a)) 197 | #define __raw_writel(v, a) (*(volatile int *)(a) = v) 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /src/foundation/startup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | extern unsigned int _end_stack; 16 | extern unsigned int _end_text; 17 | extern unsigned int _start_data; 18 | extern unsigned int _end_data; 19 | extern unsigned int _start_bss; 20 | extern unsigned int _end_bss; 21 | 22 | extern int main(void); 23 | 24 | #define DUMMY_ATTRIB __atrribute__ ((weak, alias ("dummy_handler"))); 25 | 26 | void reset_handler(void); 27 | void nmi_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 28 | void hardfault_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 29 | void memmanage_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 30 | void busfault_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 31 | void usagefault_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 32 | void svc_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 33 | void debugmon_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 34 | void pendsv_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 35 | void systick_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 36 | void extint0_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 37 | void extint1_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 38 | void extint2_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 39 | void extint3_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 40 | void extint4_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 41 | void extint5_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 42 | void extint6_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 43 | void extint7_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 44 | void extint8_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 45 | void extint9_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 46 | void extint10_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 47 | void extint11_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 48 | void extint12_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 49 | void extint13_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 50 | void extint14_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 51 | void extint15_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 52 | void extint16_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 53 | void extint17_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 54 | void extint18_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 55 | void extint19_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 56 | void extint20_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 57 | void extint21_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 58 | void extint22_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 59 | void extint23_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 60 | void extint24_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 61 | void extint25_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 62 | void extint26_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 63 | void extint27_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 64 | void extint28_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 65 | void extint29_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 66 | void extint30_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 67 | void extint31_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 68 | void extint32_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 69 | void extint33_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 70 | void extint34_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 71 | void extint35_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 72 | void extint36_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 73 | void extint37_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 74 | void extint38_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 75 | void extint39_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 76 | void extint40_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 77 | void extint41_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 78 | void extint42_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 79 | void extint43_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 80 | void extint44_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 81 | void extint45_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 82 | void extint46_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 83 | void extint47_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 84 | void extint48_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 85 | void extint49_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 86 | void extint50_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 87 | void extint51_handler(void) __attribute__ ((weak, alias("dummy_handler"))); 88 | 89 | void dummy_handler(void); 90 | 91 | /* the vector table */ 92 | void *vector_table[] __attribute__ ((section(".vectors"))) = { 93 | &_end_stack, 94 | reset_handler, 95 | nmi_handler, 96 | hardfault_handler, 97 | memmanage_handler, 98 | busfault_handler, 99 | usagefault_handler, 100 | 0, 101 | 0, 102 | 0, 103 | 0, 104 | svc_handler, 105 | debugmon_handler, 106 | 0, 107 | pendsv_handler, 108 | systick_handler, 109 | 110 | extint0_handler, 111 | extint1_handler, 112 | extint2_handler, 113 | extint3_handler, 114 | extint4_handler, 115 | extint5_handler, 116 | extint6_handler, 117 | extint7_handler, 118 | extint8_handler, 119 | extint9_handler, 120 | extint10_handler, 121 | extint11_handler, 122 | extint12_handler, 123 | extint13_handler, 124 | extint14_handler, 125 | extint15_handler, 126 | extint16_handler, 127 | extint17_handler, 128 | extint18_handler, 129 | extint19_handler, 130 | extint20_handler, 131 | extint21_handler, 132 | extint22_handler, 133 | extint23_handler, 134 | extint24_handler, 135 | extint25_handler, 136 | extint26_handler, 137 | extint27_handler, 138 | extint28_handler, 139 | extint29_handler, 140 | extint30_handler, 141 | extint31_handler, 142 | extint32_handler, 143 | extint33_handler, 144 | extint34_handler, 145 | extint35_handler, 146 | extint36_handler, 147 | extint37_handler, 148 | extint38_handler, 149 | extint39_handler, 150 | extint40_handler, 151 | extint41_handler, 152 | extint42_handler, 153 | extint43_handler, 154 | extint44_handler, 155 | extint45_handler, 156 | extint46_handler, 157 | extint47_handler, 158 | extint48_handler, 159 | extint49_handler, 160 | extint50_handler, 161 | extint51_handler, 162 | }; 163 | 164 | /* so it begins... */ 165 | void reset_handler(void) 166 | { 167 | unsigned int *pulsrc, *puldest; 168 | 169 | /* 170 | * copy the data segment initializers from flash to sram. 171 | */ 172 | pulsrc = &_end_text; 173 | for(puldest = &_start_data; puldest < &_end_data; ) 174 | { 175 | *puldest++ = *pulsrc++; 176 | } 177 | 178 | /* 179 | * zero fill the bss segment. this is done with inline assembly since this 180 | * will clear the value of puldest if it is not kept in a register. 181 | */ 182 | __asm(" ldr r0, =_start_bss\n" 183 | " ldr r1, =_end_bss\n" 184 | " mov r2, #0\n" 185 | " .thumb_func\n" 186 | "zero_loop:\n" 187 | " cmp r0, r1\n" 188 | " it lt\n" 189 | " strlt r2, [r0], #4\n" 190 | " blt zero_loop"); 191 | 192 | /* 193 | * call the application's entry point. 194 | */ 195 | main(); 196 | } 197 | 198 | void dummy_handler(void) 199 | { 200 | while(1) 201 | ; 202 | } 203 | -------------------------------------------------------------------------------- /src/pm_services/pm_handlers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | /* Enter RTC mode */ 22 | void a8_lp_cmd1_handler(struct cmd_data *data, char use_default_val) 23 | { 24 | struct rtc_data *local_cmd = (struct rtc_data *)data->data; 25 | int timeout = 0; 26 | 27 | /* If RTC module if not already configured... cannot continue */ 28 | rtc_enable_check(); 29 | 30 | if (local_cmd->rtc_timeout_val != 0 && 31 | local_cmd->rtc_timeout_val <= RTC_TIMEOUT_MAX) 32 | timeout = local_cmd->rtc_timeout_val; 33 | else 34 | timeout = RTC_TIMEOUT_DEFAULT; 35 | 36 | /* Program the RTC_PMIC register for deasseting pmic_pwr_enable */ 37 | rtc_reg_write(RTC_PMIC_REG, 0x00010000); 38 | 39 | timeout += rtc_reg_read(RTC_ALARM2_SECONDS_REG); 40 | 41 | rtc_reg_write(RTC_ALARM2_SECONDS_REG, timeout); 42 | 43 | /* Turn off interconnect */ 44 | interconnect_modules_disable(); 45 | 46 | /* Disable the clock domains except MPU */ 47 | clkdm_sleep(); 48 | 49 | /* Disable MPU clock domain */ 50 | mpu_clkdm_sleep(); 51 | 52 | wkup_clkdm_sleep(); 53 | 54 | /* TODO: wait for power domain state change interrupt from PRCM */ 55 | } 56 | 57 | /* Enter RTC_fast mode */ 58 | void a8_lp_cmd2_handler(struct cmd_data *data, char use_default_val) 59 | { 60 | struct rtc_data *rtc_data = (struct rtc_data *)data->data; 61 | int timeout = 0; 62 | 63 | if (!rtc_data->rtc_timeout_val && 64 | (rtc_data->rtc_timeout_val < RTC_TIMEOUT_MAX)) 65 | timeout = rtc_data->rtc_timeout_val; 66 | else 67 | timeout = RTC_TIMEOUT_DEFAULT; 68 | 69 | /* If RTC module if not already configured... cannot continue */ 70 | rtc_enable_check(); 71 | 72 | /* Program the RTC_PMIC register for deasseting pmic_pwr_enable */ 73 | __raw_writel(0x00010000, RTC_PMIC_REG); 74 | 75 | /* Read the RTC_ALARM2_SECS */ 76 | timeout += __raw_readl(RTC_ALARM2_SECONDS_REG); 77 | 78 | /* Write val + timeout to RTC_ALARM */ 79 | __raw_writel(timeout, RTC_ALARM2_SECONDS_REG); 80 | } 81 | 82 | /* 83 | * Enter DeepSleep0 mode 84 | * MOSC = OFF 85 | * PD_PER = RET 86 | * PD_MPU = RET 87 | */ 88 | void a8_lp_cmd3_handler(struct cmd_data *data, char use_default_val) 89 | { 90 | struct deep_sleep_data *local_cmd = (struct deep_sleep_data *)data->data; 91 | 92 | int per_st = 0; 93 | int mpu_st = 0; 94 | int temp; 95 | 96 | configure_wake_sources(local_cmd->wake_sources, use_default_val); 97 | 98 | /* TODO: Check for valid range */ 99 | if (!(use_default_val) && (local_cmd->deepsleep_count)) 100 | configure_deepsleep_count(local_cmd->deepsleep_count); 101 | else 102 | configure_deepsleep_count(DS_COUNT_DEFAULT); 103 | 104 | per_st = get_pd_per_stctrl_val(0); 105 | mpu_st = get_pd_mpu_stctrl_val(0); 106 | 107 | /* VDD MPU lowering does not make sense here so ignore that field */ 108 | 109 | if (!use_default_val) { 110 | mpu_st = mpu_powerst_change 111 | (local_cmd->pd_mpu_state, mpu_st); 112 | mpu_st = mpu_ram_ret_state_change 113 | (local_cmd->pd_mpu_ram_ret_state, mpu_st); 114 | mpu_st = mpu_l1_ret_state_change 115 | (local_cmd->pd_mpu_l1_ret_state, mpu_st); 116 | mpu_st = mpu_l2_ret_state_change 117 | (local_cmd->pd_mpu_l2_ret_state, mpu_st); 118 | per_st = per_powerst_change 119 | (local_cmd->pd_per_state, per_st); 120 | per_st = icss_mem_ret_state_change 121 | (local_cmd->pd_per_icss_mem_ret_state, per_st); 122 | per_st = per_mem_ret_state_change 123 | (local_cmd->pd_per_mem_ret_state, per_st); 124 | per_st = ocmc_mem_ret_state_change 125 | (local_cmd->pd_per_ocmc_ret_state, per_st); 126 | } 127 | 128 | /* MPU power domain state change */ 129 | pd_state_change(mpu_st, PD_MPU); 130 | 131 | /* PER power domain state change */ 132 | pd_state_change(per_st, PD_PER); 133 | 134 | /* XXX: New addition to resolve any issues that A8 might have */ 135 | essential_modules_disable(); 136 | 137 | interconnect_modules_disable(); 138 | 139 | /* DPLL retention update for PG 2.0 */ 140 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 141 | dpll_power_down(DPLL_DDR); 142 | dpll_power_down(DPLL_DISP); 143 | dpll_power_down(DPLL_PER); 144 | } 145 | 146 | mpu_clkdm_sleep(); 147 | 148 | clkdm_sleep(); 149 | 150 | /* Disable MOSC if defaults are required or if user asked for it */ 151 | if (use_default_val || !(local_cmd->mosc_state)) { 152 | disable_master_oscillator(); 153 | /* Core LDO retention for PG 2.0 if PD_PER is in RET */ 154 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 155 | if ((__raw_readl(AM335X_PM_PER_PWRSTST) & 156 | PWR_STATE_STS_MASK) == POWER_STATE_STS_RET) { 157 | /* set Auto_RAMP_EN in SMA2 Spare Register (SMA2). */ 158 | temp = __raw_readl(SMA2_SPARE_REG); 159 | temp |= VSLDO_CORE_AUTO_RAMP_EN; 160 | __raw_writel(temp, SMA2_SPARE_REG); 161 | core_ldo_power_down(); 162 | } 163 | } 164 | } 165 | 166 | /* TODO: wait for power domain state change interrupt from PRCM */ 167 | wkup_clkdm_sleep(); 168 | } 169 | 170 | /* 171 | * Enter DeepSleep1 mode 172 | * MOSC = OFF 173 | * PD_PER = ON 174 | * PD_MPU = RET 175 | */ 176 | void a8_lp_cmd5_handler(struct cmd_data *data, char use_default_val) 177 | { 178 | struct deep_sleep_data *local_cmd = (struct deep_sleep_data *)data->data; 179 | 180 | int per_st = 0; 181 | int mpu_st = 0; 182 | 183 | /* Disable MOSC if possible */ 184 | if (use_default_val || !(local_cmd->mosc_state)) 185 | disable_master_oscillator(); 186 | 187 | configure_wake_sources(local_cmd->wake_sources, use_default_val); 188 | 189 | /* TODO: Check for valid range */ 190 | if (!(use_default_val) && (local_cmd->deepsleep_count)) 191 | configure_deepsleep_count(local_cmd->deepsleep_count); 192 | else 193 | configure_deepsleep_count(DS_COUNT_DEFAULT); 194 | 195 | per_st = get_pd_per_stctrl_val(1); 196 | mpu_st = get_pd_mpu_stctrl_val(1); 197 | 198 | if (!use_default_val) { 199 | mpu_st = mpu_powerst_change 200 | (local_cmd->pd_mpu_state, mpu_st); 201 | mpu_st = mpu_ram_ret_state_change 202 | (local_cmd->pd_mpu_ram_ret_state, mpu_st); 203 | mpu_st = mpu_l1_ret_state_change 204 | (local_cmd->pd_mpu_l1_ret_state, mpu_st); 205 | mpu_st = mpu_l2_ret_state_change 206 | (local_cmd->pd_mpu_l2_ret_state, mpu_st); 207 | per_st = per_powerst_change 208 | (local_cmd->pd_per_state, per_st); 209 | per_st = icss_mem_on_state_change 210 | (local_cmd->pd_per_icss_mem_on_state, per_st); 211 | per_st = per_mem_on_state_change 212 | (local_cmd->pd_per_mem_on_state, per_st); 213 | per_st = ocmc_mem_on_state_change 214 | (local_cmd->pd_per_ocmc_on_state, per_st); 215 | } 216 | 217 | /* MPU power domain state change */ 218 | pd_state_change(mpu_st, PD_MPU); 219 | 220 | /* PER power domain state change */ 221 | pd_state_change(per_st, PD_PER); 222 | 223 | /* DPLL retention update for PG 2.0 */ 224 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 225 | dpll_power_down(DPLL_DDR); 226 | dpll_power_down(DPLL_DISP); 227 | dpll_power_down(DPLL_PER); 228 | } 229 | 230 | mpu_clkdm_sleep(); 231 | 232 | wkup_clkdm_sleep(); 233 | 234 | /* TODO: wait for power domain state change interrupt from PRCM */ 235 | } 236 | 237 | /* 238 | * Enter DeepSleep2 mode 239 | * MOSC = OFF 240 | * PD_PER = ON 241 | * PD_MPU = ON 242 | */ 243 | void a8_lp_cmd7_handler(struct cmd_data *data, char use_default_val) 244 | { 245 | struct deep_sleep_data *local_cmd = (struct deep_sleep_data *)data->data; 246 | 247 | int per_st = 0; 248 | int mpu_st = 0; 249 | 250 | /* Disable MOSC if possible */ 251 | if (use_default_val || !(local_cmd->mosc_state)) 252 | disable_master_oscillator(); 253 | 254 | configure_wake_sources(local_cmd->wake_sources, use_default_val); 255 | 256 | /* TODO: Check for valid range */ 257 | if (!(use_default_val) && (local_cmd->deepsleep_count)) 258 | configure_deepsleep_count(local_cmd->deepsleep_count); 259 | else 260 | configure_deepsleep_count(DS_COUNT_DEFAULT); 261 | 262 | per_st = get_pd_per_stctrl_val(2); 263 | mpu_st = get_pd_mpu_stctrl_val(2); 264 | 265 | if (!use_default_val) { 266 | mpu_st = mpu_powerst_change 267 | (local_cmd->pd_mpu_state, mpu_st); 268 | mpu_st = mpu_ram_on_state_change 269 | (local_cmd->pd_mpu_ram_on_state, mpu_st); 270 | per_st = per_powerst_change 271 | (local_cmd->pd_per_state, per_st); 272 | per_st = icss_mem_on_state_change 273 | (local_cmd->pd_per_icss_mem_on_state, per_st); 274 | per_st = per_mem_on_state_change 275 | (local_cmd->pd_per_mem_on_state, per_st); 276 | per_st = ocmc_mem_on_state_change 277 | (local_cmd->pd_per_ocmc_on_state, per_st); 278 | } 279 | 280 | /* MPU power domain state change */ 281 | pd_state_change(mpu_st, PD_MPU); 282 | 283 | /* PER power domain state change */ 284 | pd_state_change(per_st, PD_PER); 285 | 286 | /* DPLL retention update for PG 2.0 */ 287 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 288 | dpll_power_down(DPLL_DDR); 289 | dpll_power_down(DPLL_DISP); 290 | dpll_power_down(DPLL_PER); 291 | } 292 | 293 | wkup_clkdm_sleep(); 294 | 295 | /*TODO: wait for power domain state change interrupt from PRCM */ 296 | } 297 | 298 | void a8_standby_handler(struct cmd_data *data, char use_default_val) 299 | { 300 | struct deep_sleep_data *local_cmd = 301 | (struct deep_sleep_data *)data->data; 302 | int mpu_st = 0; 303 | int per_st = 0; 304 | 305 | configure_standby_wake_sources(local_cmd->wake_sources, 306 | use_default_val); 307 | 308 | /* TODO: Check for valid range */ 309 | if (!(use_default_val) && (local_cmd->deepsleep_count)) 310 | configure_deepsleep_count(local_cmd->deepsleep_count); 311 | else 312 | configure_deepsleep_count(DS_COUNT_DEFAULT); 313 | 314 | /* TODO: In standby ,the only variation that makes sense 315 | * is MPU ON/OFF. So all the code for PER domain manipulation 316 | * can effectively be dropped. 317 | * However, on doing so,the below error messages were seen 318 | * during resume 319 | * [ 30.295013] Could not enter low power state 320 | * [ 30.295043] Please check for active clocks in PER domain 321 | * Needs further debug. 322 | * Retaining PER domain state manipulations for now. 323 | */ 324 | per_st = get_pd_per_stctrl_val(3); 325 | mpu_st = get_pd_mpu_stctrl_val(3); 326 | 327 | if (!use_default_val) { 328 | mpu_st = mpu_powerst_change 329 | (local_cmd->pd_mpu_state, mpu_st); 330 | mpu_st = mpu_ram_ret_state_change 331 | (local_cmd->pd_mpu_ram_ret_state, mpu_st); 332 | mpu_st = mpu_l1_ret_state_change 333 | (local_cmd->pd_mpu_l1_ret_state, mpu_st); 334 | mpu_st = mpu_l2_ret_state_change 335 | (local_cmd->pd_mpu_l2_ret_state, mpu_st); 336 | } 337 | 338 | /* MPU power domain state change */ 339 | pd_state_change(mpu_st, PD_MPU); 340 | 341 | /* PER power domain state change */ 342 | pd_state_change(per_st, PD_PER); 343 | 344 | mpu_clkdm_sleep(); 345 | } 346 | 347 | void a8_cpuidle_handler(struct cmd_data *data, char use_default_val) 348 | { 349 | struct deep_sleep_data *local_cmd = (struct deep_sleep_data *)data->data; 350 | 351 | configure_standby_wake_sources(local_cmd->wake_sources, use_default_val); 352 | 353 | mpu_clkdm_sleep(); 354 | } 355 | 356 | /* Standalone application handler */ 357 | void a8_standalone_handler(struct cmd_data *data) 358 | { 359 | /* TBD */ 360 | } 361 | 362 | /* All wake interrupts invoke this function */ 363 | void generic_wake_handler(int wakeup_reason) 364 | { 365 | int i = 0; 366 | 367 | /* 368 | * Assuming that cmd_id is a valid reflection of what we did 369 | */ 370 | switch(cmd_global_data.cmd_id) { 371 | case 0x1: 372 | a8_wake_cmd1_handler(); /* RTC */ 373 | break; 374 | case 0x2: 375 | a8_wake_cmd2_handler(); /* RTC_fast */ 376 | break; 377 | case 0x3: 378 | a8_wake_cmd3_handler(); /* DS0 */ 379 | break; 380 | case 0x5: 381 | a8_wake_cmd5_handler(); /* DS1 */ 382 | break; 383 | case 0x7: 384 | a8_wake_cmd7_handler(); /* DS2 */ 385 | break; 386 | case 0xb: 387 | a8_wake_cmdb_handler(); /* Standby */ 388 | break; 389 | case 0x10: 390 | a8_wake_cmd10_handler(); /* cpuidle wake up */ 391 | break; 392 | case 0xff: 393 | default: 394 | while(1) 395 | ; 396 | } 397 | 398 | enable_master_oscillator(); 399 | 400 | /* If everything is done, we init things again */ 401 | /* Flush out NVIC interrupts */ 402 | for (i=0; i= AM335X_REV_ES2_0) 443 | core_ldo_power_up(); 444 | 445 | result = verify_pd_transitions(); 446 | 447 | pd_state_restore(); 448 | 449 | wkup_clkdm_wake(); 450 | 451 | clkdm_wake(); 452 | 453 | /* DPLL retention update for PG 2.0 */ 454 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 455 | dpll_power_up(DPLL_DDR); 456 | dpll_power_up(DPLL_DISP); 457 | dpll_power_up(DPLL_PER); 458 | } 459 | 460 | interconnect_modules_enable(); 461 | 462 | essential_modules_enable(); 463 | 464 | msg_cmd_stat_update(result); 465 | 466 | clear_wake_sources(); 467 | 468 | mpu_clkdm_wake(); 469 | } 470 | 471 | /* 472 | * Exit DeepSleep1 mode 473 | * MOSC = OFF 474 | * PD_PER = ON 475 | * PD_MPU = RET 476 | */ 477 | void a8_wake_cmd5_handler(void) 478 | { 479 | int result = 0; 480 | 481 | result = verify_pd_transitions(); 482 | 483 | pd_state_restore(); 484 | 485 | wkup_clkdm_wake(); 486 | 487 | /* DPLL retention update for PG 2.0 */ 488 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 489 | dpll_power_up(DPLL_DDR); 490 | dpll_power_up(DPLL_DISP); 491 | dpll_power_up(DPLL_PER); 492 | } 493 | 494 | essential_modules_enable(); 495 | 496 | msg_cmd_stat_update(result); 497 | 498 | clear_wake_sources(); 499 | 500 | mpu_clkdm_wake(); 501 | } 502 | 503 | /* 504 | * Exit DeepSleep2 mode 505 | * MOSC = OFF 506 | * PD_PER = ON 507 | * PD_MPU = ON 508 | */ 509 | void a8_wake_cmd7_handler(void) 510 | { 511 | int result = 0; 512 | 513 | result = verify_pd_transitions(); 514 | 515 | pd_state_restore(); 516 | 517 | wkup_clkdm_wake(); 518 | 519 | /* DPLL retention update for PG 2.0 */ 520 | if (get_am335x_soc_rev() >= AM335X_REV_ES2_0) { 521 | dpll_power_up(DPLL_DDR); 522 | dpll_power_up(DPLL_DISP); 523 | dpll_power_up(DPLL_PER); 524 | } 525 | 526 | msg_cmd_stat_update(result); 527 | 528 | /* Interrupt MPU now */ 529 | __asm("sev"); 530 | 531 | clear_wake_sources(); 532 | } 533 | 534 | /* Exit Standby mode 535 | * MOSC = ON 536 | * PD_PER = ON 537 | * PD_MPU = OFF 538 | */ 539 | void a8_wake_cmdb_handler() 540 | { 541 | int result = 0; 542 | 543 | result = verify_pd_transitions(); 544 | 545 | pd_state_restore(); 546 | 547 | essential_modules_enable(); 548 | 549 | msg_cmd_stat_update(result); 550 | 551 | clear_wake_sources(); 552 | 553 | mpu_clkdm_wake(); 554 | } 555 | 556 | /* Exit cpuidle 557 | * MPU_MPU_CLKCTRL = OFF 558 | */ 559 | void a8_wake_cmd10_handler() 560 | { 561 | clear_wake_sources(); 562 | 563 | mpu_clkdm_wake(); 564 | 565 | return; 566 | } 567 | -------------------------------------------------------------------------------- /src/include/prcm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #ifndef __CM_AM335X_H 14 | #define __CM_AM335X_H 15 | 16 | /* CM base address */ 17 | #define AM335X_CM_BASE 0x44E00000 18 | 19 | #define AM335X_CM_REGADDR(inst, reg) \ 20 | (AM335X_CM_BASE + (inst) + (reg)) 21 | 22 | /* CM instances */ 23 | 24 | #define AM335X_CM_PER_MOD 0x0000 25 | #define AM335X_CM_WKUP_MOD 0x0400 26 | #define AM335X_CM_DPLL_MOD 0x0500 27 | #define AM335X_CM_MPU_MOD 0x0600 28 | #define AM335X_CM_DEVICE_MOD 0x0700 29 | #define AM335X_CM_RTC_MOD 0x0800 30 | #define AM335X_CM_GFX_MOD 0x0900 31 | #define AM335X_CM_CEFUSE_MOD 0x0A00 32 | 33 | 34 | /* CM */ 35 | 36 | /* CM.PER_CM register offsets */ 37 | #define AM335X_CM_PER_L4LS_CLKSTCTRL_OFFSET 0x0000 38 | #define AM335X_CM_PER_L4LS_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0000) 39 | #define AM335X_CM_PER_L3S_CLKSTCTRL_OFFSET 0x0004 40 | #define AM335X_CM_PER_L3S_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0004) 41 | #define AM335X_CM_PER_L4FW_CLKSTCTRL_OFFSET 0x0008 42 | #define AM335X_CM_PER_L4FW_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0008) 43 | #define AM335X_CM_PER_L3_CLKSTCTRL_OFFSET 0x000c 44 | #define AM335X_CM_PER_L3_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x000c) 45 | #define AM335X_CM_PER_CPGMAC0_CLKCTRL_OFFSET 0x0014 46 | #define AM335X_CM_PER_CPGMAC0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0014) 47 | #define AM335X_CM_PER_LCDC_CLKCTRL_OFFSET 0x0018 48 | #define AM335X_CM_PER_LCDC_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0018) 49 | #define AM335X_CM_PER_USB0_CLKCTRL_OFFSET 0x001c 50 | #define AM335X_CM_PER_USB0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x001c) 51 | #define AM335X_CM_PER_TPTC0_CLKCTRL_OFFSET 0x0024 52 | #define AM335X_CM_PER_TPTC0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0024) 53 | #define AM335X_CM_PER_EMIF_CLKCTRL_OFFSET 0x0028 54 | #define AM335X_CM_PER_EMIF_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0028) 55 | #define AM335X_CM_PER_OCMCRAM_CLKCTRL_OFFSET 0x002c 56 | #define AM335X_CM_PER_OCMCRAM_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x002c) 57 | #define AM335X_CM_PER_GPMC_CLKCTRL_OFFSET 0x0030 58 | #define AM335X_CM_PER_GPMC_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0030) 59 | #define AM335X_CM_PER_MCASP0_CLKCTRL_OFFSET 0x0034 60 | #define AM335X_CM_PER_MCASP0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0034) 61 | #define AM335X_CM_PER_UART5_CLKCTRL_OFFSET 0x0038 62 | #define AM335X_CM_PER_UART5_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0038) 63 | #define AM335X_CM_PER_MMC0_CLKCTRL_OFFSET 0x003c 64 | #define AM335X_CM_PER_MMC0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x003c) 65 | #define AM335X_CM_PER_ELM_CLKCTRL_OFFSET 0x0040 66 | #define AM335X_CM_PER_ELM_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0040) 67 | #define AM335X_CM_PER_I2C2_CLKCTRL_OFFSET 0x0044 68 | #define AM335X_CM_PER_I2C2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0044) 69 | #define AM335X_CM_PER_I2C1_CLKCTRL_OFFSET 0x0048 70 | #define AM335X_CM_PER_I2C1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0048) 71 | #define AM335X_CM_PER_SPI0_CLKCTRL_OFFSET 0x004c 72 | #define AM335X_CM_PER_SPI0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x004c) 73 | #define AM335X_CM_PER_SPI1_CLKCTRL_OFFSET 0x0050 74 | #define AM335X_CM_PER_SPI1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0050) 75 | #define AM335X_CM_PER_L4LS_CLKCTRL_OFFSET 0x0060 76 | #define AM335X_CM_PER_L4LS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0060) 77 | #define AM335X_CM_PER_L4FW_CLKCTRL_OFFSET 0x0064 78 | #define AM335X_CM_PER_L4FW_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0064) 79 | #define AM335X_CM_PER_MCASP1_CLKCTRL_OFFSET 0x0068 80 | #define AM335X_CM_PER_MCASP1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0068) 81 | #define AM335X_CM_PER_UART1_CLKCTRL_OFFSET 0x006c 82 | #define AM335X_CM_PER_UART1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x006c) 83 | #define AM335X_CM_PER_UART2_CLKCTRL_OFFSET 0x0070 84 | #define AM335X_CM_PER_UART2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0070) 85 | #define AM335X_CM_PER_UART3_CLKCTRL_OFFSET 0x0074 86 | #define AM335X_CM_PER_UART3_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0074) 87 | #define AM335X_CM_PER_UART4_CLKCTRL_OFFSET 0x0078 88 | #define AM335X_CM_PER_UART4_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0078) 89 | #define AM335X_CM_PER_TIMER7_CLKCTRL_OFFSET 0x007c 90 | #define AM335X_CM_PER_TIMER7_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x007c) 91 | #define AM335X_CM_PER_TIMER2_CLKCTRL_OFFSET 0x0080 92 | #define AM335X_CM_PER_TIMER2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0080) 93 | #define AM335X_CM_PER_TIMER3_CLKCTRL_OFFSET 0x0084 94 | #define AM335X_CM_PER_TIMER3_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0084) 95 | #define AM335X_CM_PER_TIMER4_CLKCTRL_OFFSET 0x0088 96 | #define AM335X_CM_PER_TIMER4_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0088) 97 | #define AM335X_CM_PER_RNG_CLKCTRL_OFFSET 0x0090 98 | #define AM335X_CM_PER_RNG_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0090) 99 | #define AM335X_CM_PER_AES0_CLKCTRL_OFFSET 0x0094 100 | #define AM335X_CM_PER_AES0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0094) 101 | #define AM335X_CM_PER_SHA0_CLKCTRL_OFFSET 0x00a0 102 | #define AM335X_CM_PER_SHA0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00a0) 103 | #define AM335X_CM_PER_PKA_CLKCTRL_OFFSET 0x00a4 104 | #define AM335X_CM_PER_PKA_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00a4) 105 | #define AM335X_CM_PER_GPIO1_CLKCTRL_OFFSET 0x00ac 106 | #define AM335X_CM_PER_GPIO1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00ac) 107 | #define AM335X_CM_PER_GPIO2_CLKCTRL_OFFSET 0x00b0 108 | #define AM335X_CM_PER_GPIO2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00b0) 109 | #define AM335X_CM_PER_GPIO3_CLKCTRL_OFFSET 0x00b4 110 | #define AM335X_CM_PER_GPIO3_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00b4) 111 | #define AM335X_CM_PER_TPCC_CLKCTRL_OFFSET 0x00bc 112 | #define AM335X_CM_PER_TPCC_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00bc) 113 | #define AM335X_CM_PER_DCAN0_CLKCTRL_OFFSET 0x00c0 114 | #define AM335X_CM_PER_DCAN0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00c0) 115 | #define AM335X_CM_PER_DCAN1_CLKCTRL_OFFSET 0x00c4 116 | #define AM335X_CM_PER_DCAN1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00c4) 117 | #define AM335X_CM_PER_EPWMSS1_CLKCTRL_OFFSET 0x00cc 118 | #define AM335X_CM_PER_EPWMSS1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00cc) 119 | #define AM335X_CM_PER_EMIF_FW_CLKCTRL_OFFSET 0x00d0 120 | #define AM335X_CM_PER_EMIF_FW_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00d0) 121 | #define AM335X_CM_PER_EPWMSS0_CLKCTRL_OFFSET 0x00d4 122 | #define AM335X_CM_PER_EPWMSS0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00d4) 123 | #define AM335X_CM_PER_EPWMSS2_CLKCTRL_OFFSET 0x00d8 124 | #define AM335X_CM_PER_EPWMSS2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00d8) 125 | #define AM335X_CM_PER_L3_INSTR_CLKCTRL_OFFSET 0x00dc 126 | #define AM335X_CM_PER_L3_INSTR_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00dc) 127 | #define AM335X_CM_PER_L3_CLKCTRL_OFFSET 0x00e0 128 | #define AM335X_CM_PER_L3_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00e0) 129 | #define AM335X_CM_PER_IEEE5000_CLKCTRL_OFFSET 0x00e4 130 | #define AM335X_CM_PER_IEEE5000_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00e4) 131 | #define AM335X_CM_PER_ICSS_CLKCTRL_OFFSET 0x00e8 132 | #define AM335X_CM_PER_ICSS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00e8) 133 | #define AM335X_CM_PER_TIMER5_CLKCTRL_OFFSET 0x00ec 134 | #define AM335X_CM_PER_TIMER5_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00ec) 135 | #define AM335X_CM_PER_TIMER6_CLKCTRL_OFFSET 0x00f0 136 | #define AM335X_CM_PER_TIMER6_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00f0) 137 | #define AM335X_CM_PER_MMC1_CLKCTRL_OFFSET 0x00f4 138 | #define AM335X_CM_PER_MMC1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00f4) 139 | #define AM335X_CM_PER_MMC2_CLKCTRL_OFFSET 0x00f8 140 | #define AM335X_CM_PER_MMC2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00f8) 141 | #define AM335X_CM_PER_TPTC1_CLKCTRL_OFFSET 0x00fc 142 | #define AM335X_CM_PER_TPTC1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x00fc) 143 | #define AM335X_CM_PER_TPTC2_CLKCTRL_OFFSET 0x0100 144 | #define AM335X_CM_PER_TPTC2_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0100) 145 | #define AM335X_CM_PER_SPINLOCK_CLKCTRL_OFFSET 0x010c 146 | #define AM335X_CM_PER_SPINLOCK_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x010c) 147 | #define AM335X_CM_PER_MAILBOX0_CLKCTRL_OFFSET 0x0110 148 | #define AM335X_CM_PER_MAILBOX0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0110) 149 | #define AM335X_CM_PER_L4HS_CLKSTCTRL_OFFSET 0x011c 150 | #define AM335X_CM_PER_L4HS_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x011c) 151 | #define AM335X_CM_PER_L4HS_CLKCTRL_OFFSET 0x0120 152 | #define AM335X_CM_PER_L4HS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0120) 153 | #define AM335X_CM_PER_MSTR_EXPS_CLKCTRL_OFFSET 0x0124 154 | #define AM335X_CM_PER_MSTR_EXPS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0124) 155 | #define AM335X_CM_PER_SLV_EXPS_CLKCTRL_OFFSET 0x0128 156 | #define AM335X_CM_PER_SLV_EXPS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0128) 157 | #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_OFFSET 0x012c 158 | #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x012c) 159 | #define AM335X_CM_PER_OCPWP_CLKCTRL_OFFSET 0x0130 160 | #define AM335X_CM_PER_OCPWP_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0130) 161 | #define AM335X_CM_PER_ICSS_CLKSTCTRL_OFFSET 0x0140 162 | #define AM335X_CM_PER_ICSS_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0140) 163 | #define AM335X_CM_PER_CPSW_CLKSTCTRL_OFFSET 0x0144 164 | #define AM335X_CM_PER_CPSW_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0144) 165 | #define AM335X_CM_PER_LCDC_CLKSTCTRL_OFFSET 0x0148 166 | #define AM335X_CM_PER_LCDC_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0148) 167 | #define AM335X_CM_PER_CLKDIV32K_CLKCTRL_OFFSET 0x014c 168 | #define AM335X_CM_PER_CLKDIV32K_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x014c) 169 | #define AM335X_CM_PER_CLK_24MHZ_CLKSTCTRL_OFFSET 0x0150 170 | #define AM335X_CM_PER_CLK_24MHZ_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_PER_MOD, 0x0150) 171 | 172 | /* CM.WKUP_CM register offsets */ 173 | #define AM335X_CM_WKUP_CLKSTCTRL_OFFSET 0x0000 174 | #define AM335X_CM_WKUP_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0000) 175 | #define AM335X_CM_WKUP_CONTROL_CLKCTRL_OFFSET 0x0004 176 | #define AM335X_CM_WKUP_CONTROL_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0004) 177 | #define AM335X_CM_WKUP_GPIO0_CLKCTRL_OFFSET 0x0008 178 | #define AM335X_CM_WKUP_GPIO0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0008) 179 | #define AM335X_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x000c 180 | #define AM335X_CM_WKUP_L4WKUP_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x000c) 181 | #define AM335X_CM_WKUP_TIMER0_CLKCTRL_OFFSET 0x0010 182 | #define AM335X_CM_WKUP_TIMER0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0010) 183 | #define AM335X_CM_WKUP_DEBUGSS_CLKCTRL_OFFSET 0x0014 184 | #define AM335X_CM_WKUP_DEBUGSS_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0014) 185 | #define AM335X_CM_L3_AON_CLKSTCTRL_OFFSET 0x0018 186 | #define AM335X_CM_L3_AON_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0018) 187 | #define AM335X_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x001c 188 | #define AM335X_CM_AUTOIDLE_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x001c) 189 | #define AM335X_CM_IDLEST_DPLL_MPU_OFFSET 0x0020 190 | #define AM335X_CM_IDLEST_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0020) 191 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0024 192 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0024) 193 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_MPU_OFFSET 0x0028 194 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0028) 195 | #define AM335X_CM_CLKSEL_DPLL_MPU_OFFSET 0x002c 196 | #define AM335X_CM_CLKSEL_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x002c) 197 | #define AM335X_CM_AUTOIDLE_DPLL_DDR_OFFSET 0x0030 198 | #define AM335X_CM_AUTOIDLE_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0030) 199 | #define AM335X_CM_IDLEST_DPLL_DDR_OFFSET 0x0034 200 | #define AM335X_CM_IDLEST_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0034) 201 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_DDR_OFFSET 0x0038 202 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0038) 203 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_DDR_OFFSET 0x003c 204 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x003c) 205 | #define AM335X_CM_CLKSEL_DPLL_DDR_OFFSET 0x0040 206 | #define AM335X_CM_CLKSEL_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0040) 207 | #define AM335X_CM_AUTOIDLE_DPLL_DISP_OFFSET 0x0044 208 | #define AM335X_CM_AUTOIDLE_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0044) 209 | #define AM335X_CM_IDLEST_DPLL_DISP_OFFSET 0x0048 210 | #define AM335X_CM_IDLEST_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0048) 211 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_DISP_OFFSET 0x004c 212 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x004c) 213 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_DISP_OFFSET 0x0050 214 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0050) 215 | #define AM335X_CM_CLKSEL_DPLL_DISP_OFFSET 0x0054 216 | #define AM335X_CM_CLKSEL_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0054) 217 | #define AM335X_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0058 218 | #define AM335X_CM_AUTOIDLE_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0058) 219 | #define AM335X_CM_IDLEST_DPLL_CORE_OFFSET 0x005c 220 | #define AM335X_CM_IDLEST_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x005c) 221 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0060 222 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0060) 223 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_CORE_OFFSET 0x0064 224 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0064) 225 | #define AM335X_CM_CLKSEL_DPLL_CORE_OFFSET 0x0068 226 | #define AM335X_CM_CLKSEL_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0068) 227 | #define AM335X_CM_AUTOIDLE_DPLL_PER_OFFSET 0x006c 228 | #define AM335X_CM_AUTOIDLE_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x006c) 229 | #define AM335X_CM_IDLEST_DPLL_PER_OFFSET 0x0070 230 | #define AM335X_CM_IDLEST_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0070) 231 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0074 232 | #define AM335X_CM_SSC_DELTAMSTEP_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0074) 233 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_PER_OFFSET 0x0078 234 | #define AM335X_CM_SSC_MODFREQDIV_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0078) 235 | #define AM335X_CM_CLKDCOLDO_DPLL_PER_OFFSET 0x007c 236 | #define AM335X_CM_CLKDCOLDO_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x007c) 237 | #define AM335X_CM_DIV_M4_DPLL_CORE_OFFSET 0x0080 238 | #define AM335X_CM_DIV_M4_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0080) 239 | #define AM335X_CM_DIV_M5_DPLL_CORE_OFFSET 0x0084 240 | #define AM335X_CM_DIV_M5_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0084) 241 | #define AM335X_CM_CLKMODE_DPLL_MPU_OFFSET 0x0088 242 | #define AM335X_CM_CLKMODE_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0088) 243 | #define AM335X_CM_CLKMODE_DPLL_PER_OFFSET 0x008c 244 | #define AM335X_CM_CLKMODE_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x008c) 245 | #define AM335X_CM_CLKMODE_DPLL_CORE_OFFSET 0x0090 246 | #define AM335X_CM_CLKMODE_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0090) 247 | #define AM335X_CM_CLKMODE_DPLL_DDR_OFFSET 0x0094 248 | #define AM335X_CM_CLKMODE_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0094) 249 | #define AM335X_CM_CLKMODE_DPLL_DISP_OFFSET 0x0098 250 | #define AM335X_CM_CLKMODE_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x0098) 251 | #define AM335X_CM_CLKSEL_DPLL_PERIPH_OFFSET 0x009c 252 | #define AM335X_CM_CLKSEL_DPLL_PERIPH AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x009c) 253 | #define AM335X_CM_DIV_M2_DPLL_DDR_OFFSET 0x00a0 254 | #define AM335X_CM_DIV_M2_DPLL_DDR AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00a0) 255 | #define AM335X_CM_DIV_M2_DPLL_DISP_OFFSET 0x00a4 256 | #define AM335X_CM_DIV_M2_DPLL_DISP AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00a4) 257 | #define AM335X_CM_DIV_M2_DPLL_MPU_OFFSET 0x00a8 258 | #define AM335X_CM_DIV_M2_DPLL_MPU AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00a8) 259 | #define AM335X_CM_DIV_M2_DPLL_PER_OFFSET 0x00ac 260 | #define AM335X_CM_DIV_M2_DPLL_PER AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00ac) 261 | #define AM335X_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET 0x00b0 262 | #define AM335X_CM_WKUP_WKUP_M3_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00b0) 263 | #define AM335X_CM_WKUP_UART0_CLKCTRL_OFFSET 0x00b4 264 | #define AM335X_CM_WKUP_UART0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00b4) 265 | #define AM335X_CM_WKUP_I2C0_CLKCTRL_OFFSET 0x00b8 266 | #define AM335X_CM_WKUP_I2C0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00b8) 267 | #define AM335X_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET 0x00bc 268 | #define AM335X_CM_WKUP_ADC_TSC_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00bc) 269 | #define AM335X_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET 0x00c0 270 | #define AM335X_CM_WKUP_SMARTREFLEX0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00c0) 271 | #define AM335X_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x00c4 272 | #define AM335X_CM_WKUP_TIMER1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00c4) 273 | #define AM335X_CM_WKUP_SMARTREFLEX1_CLKCTRL_OFFSET 0x00c8 274 | #define AM335X_CM_WKUP_SMARTREFLEX1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00c8) 275 | #define AM335X_CM_L4_WKUP_AON_CLKSTCTRL_OFFSET 0x00cc 276 | #define AM335X_CM_L4_WKUP_AON_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00cc) 277 | #define AM335X_CM_WKUP_WDT0_CLKCTRL_OFFSET 0x00d0 278 | #define AM335X_CM_WKUP_WDT0_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00d0) 279 | #define AM335X_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x00d4 280 | #define AM335X_CM_WKUP_WDT1_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00d4) 281 | #define AM335X_CM_DIV_M6_DPLL_CORE_OFFSET 0x00d8 282 | #define AM335X_CM_DIV_M6_DPLL_CORE AM335X_CM_REGADDR(AM335X_CM_WKUP_MOD, 0x00d8) 283 | 284 | /* CM.DPLL_CM register offsets */ 285 | #define AM335X_CLKSEL_TIMER7_CLK_OFFSET 0x0004 286 | #define AM335X_CLKSEL_TIMER7_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0004) 287 | #define AM335X_CLKSEL_TIMER2_CLK_OFFSET 0x0008 288 | #define AM335X_CLKSEL_TIMER2_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0008) 289 | #define AM335X_CLKSEL_TIMER3_CLK_OFFSET 0x000c 290 | #define AM335X_CLKSEL_TIMER3_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x000c) 291 | #define AM335X_CLKSEL_TIMER4_CLK_OFFSET 0x0010 292 | #define AM335X_CLKSEL_TIMER4_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0010) 293 | #define AM335X_CM_MAC_CLKSEL_OFFSET 0x0014 294 | #define AM335X_CM_MAC_CLKSEL AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0014) 295 | #define AM335X_CLKSEL_TIMER5_CLK_OFFSET 0x0018 296 | #define AM335X_CLKSEL_TIMER5_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0018) 297 | #define AM335X_CLKSEL_TIMER6_CLK_OFFSET 0x001c 298 | #define AM335X_CLKSEL_TIMER6_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x001c) 299 | #define AM335X_CM_CPTS_RFT_CLKSEL_OFFSET 0x0020 300 | #define AM335X_CM_CPTS_RFT_CLKSEL AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0020) 301 | #define AM335X_CLKSEL_TIMER1MS_CLK_OFFSET 0x0028 302 | #define AM335X_CLKSEL_TIMER1MS_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0028) 303 | #define AM335X_CLKSEL_GFX_FCLK_OFFSET 0x002c 304 | #define AM335X_CLKSEL_GFX_FCLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x002c) 305 | #define AM335X_CLKSEL_ICSS_OCP_CLK_OFFSET 0x0030 306 | #define AM335X_CLKSEL_ICSS_OCP_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0030) 307 | #define AM335X_CLKSEL_LCDC_PIXEL_CLK_OFFSET 0x0034 308 | #define AM335X_CLKSEL_LCDC_PIXEL_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0034) 309 | #define AM335X_CLKSEL_WDT1_CLK_OFFSET 0x0038 310 | #define AM335X_CLKSEL_WDT1_CLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x0038) 311 | #define AM335X_CLKSEL_GPIO0_DBCLK_OFFSET 0x003c 312 | #define AM335X_CLKSEL_GPIO0_DBCLK AM335X_CM_REGADDR(AM335X_CM_DPLL_MOD, 0x003c) 313 | 314 | /* CM.MPU_CM register offsets */ 315 | #define AM335X_CM_MPU_CLKSTCTRL_OFFSET 0x0000 316 | #define AM335X_CM_MPU_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_MPU_MOD, 0x0000) 317 | #define AM335X_CM_MPU_MPU_CLKCTRL_OFFSET 0x0004 318 | #define AM335X_CM_MPU_MPU_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_MPU_MOD, 0x0004) 319 | 320 | /* CM.DEVICE_CM register offsets */ 321 | #define AM335X_CM_CLKOUT_CTRL_OFFSET 0x0000 322 | #define AM335X_CM_CLKOUT_CTRL AM335X_CM_REGADDR(AM335X_CM_DEVICE_MOD, 0x0000) 323 | 324 | /* CM.RTC_CM register offsets */ 325 | #define AM335X_CM_RTC_RTC_CLKCTRL_OFFSET 0x0000 326 | #define AM335X_CM_RTC_RTC_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_RTC_MOD, 0x0000) 327 | #define AM335X_CM_RTC_CLKSTCTRL_OFFSET 0x0004 328 | #define AM335X_CM_RTC_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_RTC_MOD, 0x0004) 329 | 330 | /* CM.GFX_CM register offsets */ 331 | #define AM335X_CM_GFX_L3_CLKSTCTRL_OFFSET 0x0000 332 | #define AM335X_CM_GFX_L3_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x0000) 333 | #define AM335X_CM_GFX_GFX_CLKCTRL_OFFSET 0x0004 334 | #define AM335X_CM_GFX_GFX_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x0004) 335 | #define AM335X_CM_GFX_BITBLT_CLKCTRL_OFFSET 0x0008 336 | #define AM335X_CM_GFX_BITBLT_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x0008) 337 | #define AM335X_CM_GFX_L4LS_GFX_CLKSTCTRL__1_OFFSET 0x000c 338 | #define AM335X_CM_GFX_L4LS_GFX_CLKSTCTRL__1 AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x000c) 339 | #define AM335X_CM_GFX_MMUCFG_CLKCTRL_OFFSET 0x0010 340 | #define AM335X_CM_GFX_MMUCFG_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x0010) 341 | #define AM335X_CM_GFX_MMUDATA_CLKCTRL_OFFSET 0x0014 342 | #define AM335X_CM_GFX_MMUDATA_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_GFX_MOD, 0x0014) 343 | 344 | /* CM.CEFUSE_CM register offsets */ 345 | #define AM335X_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000 346 | #define AM335X_CM_CEFUSE_CLKSTCTRL AM335X_CM_REGADDR(AM335X_CM_CEFUSE_MOD, 0x0000) 347 | #define AM335X_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020 348 | #define AM335X_CM_CEFUSE_CEFUSE_CLKCTRL AM335X_CM_REGADDR(AM335X_CM_CEFUSE_MOD, 0x0020) 349 | 350 | /* PRCM RMW helper macros */ 351 | /* MPU PWR DOMAIN */ 352 | #define MPU_RAM_RETSTATE_MASK (1 << 24) 353 | #define MPU_RAM_RETSTATE_SHIFT (24) 354 | 355 | #define MPU_L2_RETSTATE_MASK (1 << 23) 356 | #define MPU_L2_RETSTATE_SHIFT (23) 357 | 358 | #define MPU_L1_RETSTATE_MASK (1 << 22) 359 | #define MPU_L1_RETSTATE_SHIFT (22) 360 | 361 | #define MPU_RAM_ONSTATE_MASK (0x3 << 15) 362 | #define MPU_RAM_OMSTATE_SHIFT (15) 363 | 364 | #define MPU_LOWPOWERSTATECHANGE_MASK (1 << 4) 365 | #define MPU_LOWPOWERSTATECHANGE_SHIFT (4) 366 | 367 | #define MPU_LOGICRETSTATE_MASK (1 << 2) 368 | #define MPU_LOGICRETSTATE_SHIFT (2) 369 | 370 | #define MPU_POWERSTATE_MASK (0x3 << 0) 371 | #define MPU_POWERSTATE_SHIFT (0) 372 | 373 | #define MPU_PWRSTCTRL(pd, ram_on, l1_ret, l2_ret, ram_ret) \ 374 | ((pd << MPU_POWERSTATE_SHIFT) | \ 375 | (ram_on << MPU_RAM_ONSTATE_SHIFT) | \ 376 | (l1_ret << MPU_L1_RETSTATE_SHIFT) | \ 377 | (l2_ret << MPU_L2_RETSTATE_SHIFT) | \ 378 | (ram_ret << MPU_RAM_RETSTATE_SHIFT)) 379 | 380 | /* PER PWR DOMAIN */ 381 | 382 | #define PER_MEM_RETSTATE_MASK (1 << 29) 383 | #define PER_MEM_RETSTATE_SHIFT (29) 384 | 385 | #define PER_RAM_MEM_ONSTATE_MASK (0x3 << 30) 386 | #define PER_RAM_MEM_ONSTATE_SHIFT (30) 387 | 388 | #define PER_RAM_MEM_RETSTATE_MASK (1 << 27) 389 | #define PER_RAM_MEM_RETSTATE_SHIFT (27) 390 | 391 | #define PER_MEM_ONSTATE_MASK (0x3 << 25) 392 | #define PER_MEM_ONSTATE_SHIFT (25) 393 | 394 | #define PER_ICSS_MEM_RETSTATE_MASK (1 << 7) 395 | #define PER_ICSS_MEM_RETSTATE_SHIFT (7) 396 | 397 | #define PER_ICSS_MEM_ONSTATE_MASK (0x3 << 5) 398 | #define PER_ICSS_MEM_ONSTATE_SHIFT (5) 399 | 400 | #define PER_LOWPOWERSTATECHANGE_MASK (1 << 4) 401 | #define PER_LOWPOWERSTATECHANGE_SHIFT (4) 402 | 403 | #define PER_LOGICRETSTATE_MASK (1 << 2) 404 | #define PER_LOGICRETSTATE_SHIFT (2) 405 | 406 | #define PER_POWERSTATE_MASK (0x3 << 0) 407 | #define PER_POWERSTATE_SHIFT (0) 408 | 409 | 410 | #endif 411 | -------------------------------------------------------------------------------- /src/pm_services/prcm_core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AM33XX-CM3 firmware 3 | * 4 | * Cortex-M3 (CM3) firmware for power management on Texas Instruments' AM33XX series of SoCs 5 | * 6 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 7 | * 8 | * This software is licensed under the standard terms and conditions in the Texas Instruments Incorporated 9 | * Technology and Software Publicly Available Software License Agreement , a copy of which is included in the 10 | * software download. 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* Explicit 0s imply don't care */ 23 | struct deep_sleep_data ds0_data = { 24 | .mosc_state = MOSC_OFF, 25 | .deepsleep_count = DS_COUNT_DEFAULT, 26 | .vdd_mpu_val = 0, 27 | 28 | .pd_mpu_state = PD_OFF, 29 | .pd_mpu_ram_ret_state = MEM_BANK_RET_ST_OFF, 30 | .pd_mpu_l1_ret_state = MEM_BANK_RET_ST_OFF, 31 | .pd_mpu_l2_ret_state = MEM_BANK_RET_ST_OFF, 32 | .pd_mpu_ram_on_state = 0, 33 | 34 | .pd_per_state = PD_RET, 35 | .pd_per_icss_mem_ret_state = MEM_BANK_RET_ST_OFF, 36 | .pd_per_mem_ret_state = MEM_BANK_RET_ST_OFF, 37 | .pd_per_ocmc_ret_state = MEM_BANK_RET_ST_RET, 38 | .pd_per_icss_mem_on_state = 0, 39 | .pd_per_mem_on_state = 0, 40 | .pd_per_ocmc_on_state = 0, 41 | 42 | .wake_sources = WAKE_ALL, 43 | .reserved = 0 44 | }; 45 | 46 | struct deep_sleep_data ds1_data = { 47 | .mosc_state = MOSC_OFF, 48 | .deepsleep_count = DS_COUNT_DEFAULT, 49 | .vdd_mpu_val = 0, 50 | 51 | .pd_mpu_state = PD_OFF, 52 | .pd_mpu_ram_ret_state = MEM_BANK_RET_ST_OFF, 53 | .pd_mpu_l1_ret_state = MEM_BANK_RET_ST_OFF, 54 | .pd_mpu_l2_ret_state = MEM_BANK_RET_ST_OFF, 55 | .pd_mpu_ram_on_state = 0, 56 | 57 | .pd_per_state = PD_ON, 58 | .pd_per_icss_mem_ret_state = 0, 59 | .pd_per_mem_ret_state = 0, 60 | .pd_per_ocmc_ret_state = 0, 61 | .pd_per_icss_mem_on_state = MEM_BANK_ON_ST_ON, 62 | .pd_per_mem_on_state = MEM_BANK_ON_ST_ON, 63 | .pd_per_ocmc_on_state = MEM_BANK_ON_ST_ON, 64 | 65 | .wake_sources = WAKE_ALL, 66 | .reserved = 0 67 | }; 68 | 69 | struct deep_sleep_data ds2_data = { 70 | .mosc_state = MOSC_OFF, 71 | .deepsleep_count = DS_COUNT_DEFAULT, 72 | .vdd_mpu_val = 0, 73 | 74 | .pd_mpu_state = PD_ON, 75 | .pd_mpu_ram_ret_state = 0, 76 | .pd_mpu_l1_ret_state = 0, 77 | .pd_mpu_l2_ret_state = 0, 78 | .pd_mpu_ram_on_state = MEM_BANK_ON_ST_ON, 79 | 80 | .pd_per_state = PD_ON, 81 | .pd_per_icss_mem_ret_state = 0, 82 | .pd_per_mem_ret_state = 0, 83 | .pd_per_ocmc_ret_state = 0, 84 | .pd_per_icss_mem_on_state = MEM_BANK_ON_ST_ON, 85 | .pd_per_mem_on_state = MEM_BANK_ON_ST_ON, 86 | .pd_per_ocmc_on_state = MEM_BANK_ON_ST_ON, 87 | 88 | .wake_sources = WAKE_ALL, 89 | .reserved = 0 90 | }; 91 | 92 | struct deep_sleep_data standby_data = { 93 | .mosc_state = MOSC_ON, 94 | .deepsleep_count = DS_COUNT_DEFAULT, 95 | .vdd_mpu_val = 0, 96 | 97 | .pd_mpu_state = PD_OFF, 98 | .pd_mpu_ram_ret_state = MEM_BANK_RET_ST_OFF, 99 | .pd_mpu_l1_ret_state = MEM_BANK_RET_ST_OFF, 100 | .pd_mpu_l2_ret_state = MEM_BANK_RET_ST_OFF, 101 | .pd_mpu_ram_on_state = 0, 102 | 103 | .pd_per_state = PD_ON, 104 | .pd_per_icss_mem_ret_state = 0, 105 | .pd_per_mem_ret_state = 0, 106 | .pd_per_ocmc_ret_state = 0, 107 | .pd_per_icss_mem_on_state = MEM_BANK_ON_ST_ON, 108 | .pd_per_mem_on_state = MEM_BANK_ON_ST_ON, 109 | .pd_per_ocmc_on_state = MEM_BANK_ON_ST_ON, 110 | 111 | /* TODO: wake_sources for standby should be MPU_WAKE */ 112 | .wake_sources = WAKE_ALL, 113 | .reserved = 0 114 | }; 115 | 116 | /* Clear out the global variables here */ 117 | void pm_init(void) 118 | { 119 | cmd_id = 0; 120 | cmd_stat = 0; 121 | 122 | cmd_global_data.cmd_id = 0; 123 | cmd_global_data.data = 0; 124 | 125 | pd_mpu_stctrl_next_val = 0; 126 | pd_per_stctrl_next_val = 0; 127 | pd_mpu_pwrstst_next_val = 0; 128 | pd_per_pwrstst_next_val = 0; 129 | pd_mpu_stctrl_prev_val = 0; 130 | pd_per_stctrl_prev_val = 0; 131 | pd_mpu_pwrstst_prev_val = 0; 132 | pd_per_pwrstst_prev_val = 0; 133 | } 134 | 135 | void setup_am335x_soc_revision(void) 136 | { 137 | am335x_soc_rev = (__raw_readl(DEVICE_ID) >> 0x1c) & 0xff; 138 | } 139 | 140 | unsigned int get_am335x_soc_rev(void) 141 | { 142 | return am335x_soc_rev; 143 | } 144 | 145 | int var_mod(int var, int mask, int bit_val) 146 | { 147 | int v; 148 | 149 | v = var; 150 | v &= ~mask; 151 | v |= bit_val; 152 | 153 | return v; 154 | } 155 | 156 | #define DEFAULT_IDLEST_SHIFT 16 157 | #define DEFAULT_IDLEST_MASK (3 << DEFAULT_IDLEST_SHIFT) 158 | #define DEFAULT_IDLEST_IDLE_VAL 3 159 | #define DEFAULT_IDLEST_ACTIVE_VAL 0 160 | 161 | /* TODO: Add a timeout and bail out */ 162 | static void _module_enable(int reg) 163 | { 164 | __raw_writel(MODULE_ENABLE, reg); 165 | 166 | while ((__raw_readl(reg) & DEFAULT_IDLEST_MASK)>>DEFAULT_IDLEST_SHIFT != 167 | DEFAULT_IDLEST_ACTIVE_VAL); 168 | } 169 | 170 | static void _module_disable(int reg) 171 | { 172 | __raw_writel(MODULE_DISABLE, reg); 173 | 174 | while ((__raw_readl(reg) & DEFAULT_IDLEST_MASK)>>DEFAULT_IDLEST_SHIFT != 175 | DEFAULT_IDLEST_IDLE_VAL); 176 | } 177 | 178 | int module_state_change(int state, int reg) 179 | { 180 | if (state == MODULE_DISABLE) 181 | _module_disable(reg); 182 | else 183 | _module_enable(reg); 184 | 185 | return 0; 186 | } 187 | 188 | #define DEFAULT_CLKTRCTRL_SHIFT 0 189 | #define DEFAULT_CLKTRCTRL_MASK (3 << DEFAULT_CLKTRCTRL_SHIFT) 190 | #define DEFAULT_CLKTRCTRL_WAKE 0x2 191 | #define DEFAULT_CLKTRCTRL_SLEEP 0x1 192 | 193 | #define CLKDM_SLEEP 0x1 194 | #define CLKDM_WAKE 0x2 195 | 196 | static void _clkdm_sleep(int reg) 197 | { 198 | int var = 0; 199 | 200 | var = __raw_readl(reg); 201 | var = var_mod(var, DEFAULT_CLKTRCTRL_MASK, DEFAULT_CLKTRCTRL_SLEEP); 202 | __raw_writel(var, reg); 203 | } 204 | 205 | static void _clkdm_wakeup(int reg) 206 | { 207 | int var = 0; 208 | 209 | var = __raw_readl(reg); 210 | var = var_mod(var, DEFAULT_CLKTRCTRL_MASK, DEFAULT_CLKTRCTRL_WAKE); 211 | __raw_writel(var, reg); 212 | } 213 | 214 | int clkdm_state_change(int state, int reg) 215 | { 216 | if (state == CLKDM_SLEEP) 217 | _clkdm_sleep(reg); 218 | else 219 | _clkdm_wakeup(reg); 220 | 221 | return 0; 222 | } 223 | 224 | /* 225 | * Looks like we'll have to ensure that we disable some modules when going down 226 | * ideally this list should have 0 entries but we need to check 227 | * what are the things that are really really necessary here 228 | */ 229 | int essential_modules_disable(void) 230 | { 231 | /* Disable only the bare essential modules */ 232 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_CLKDIV32K_CLKCTRL); 233 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_IEEE5000_CLKCTRL); 234 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_EMIF_FW_CLKCTRL); 235 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_GPMC_CLKCTRL); 236 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_OCMCRAM_CLKCTRL); 237 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_EMIF_CLKCTRL); 238 | 239 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_MAILBOX0_CLKCTRL); 240 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_UART0_CLKCTRL); 241 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_TIMER2_CLKCTRL); 242 | return 0; 243 | } 244 | 245 | int essential_modules_enable(void) 246 | { 247 | /* Enable only the bare essential modules */ 248 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_CLKDIV32K_CLKCTRL); 249 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_IEEE5000_CLKCTRL); 250 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_EMIF_FW_CLKCTRL); 251 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_GPMC_CLKCTRL); 252 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_OCMCRAM_CLKCTRL); 253 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_EMIF_CLKCTRL); 254 | 255 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_MAILBOX0_CLKCTRL); 256 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_UART0_CLKCTRL); 257 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_TIMER2_CLKCTRL); 258 | return 0; 259 | } 260 | 261 | int interconnect_modules_disable(void) 262 | { 263 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_EMIF_CLKCTRL); 264 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_EMIF_FW_CLKCTRL); 265 | 266 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_L4LS_CLKCTRL); 267 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_L4HS_CLKCTRL); 268 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_L4FW_CLKCTRL); 269 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_L3_INSTR_CLKCTRL); 270 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_L3_CLKCTRL); 271 | 272 | return 0; 273 | } 274 | 275 | int interconnect_modules_enable(void) 276 | { 277 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_L3_CLKCTRL); 278 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_L3_INSTR_CLKCTRL); 279 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_L4FW_CLKCTRL); 280 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_L4HS_CLKCTRL); 281 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_L4LS_CLKCTRL); 282 | 283 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_EMIF_FW_CLKCTRL); 284 | module_state_change(MODULE_ENABLE, AM335X_CM_PER_EMIF_CLKCTRL); 285 | 286 | return 0; 287 | } 288 | 289 | void mpu_disable(void) 290 | { 291 | module_state_change(MODULE_DISABLE, AM335X_CM_MPU_MPU_CLKCTRL); 292 | } 293 | 294 | void mpu_enable(void) 295 | { 296 | module_state_change(MODULE_ENABLE, AM335X_CM_MPU_MPU_CLKCTRL); 297 | } 298 | 299 | /* CLKDM related */ 300 | void clkdm_sleep(void) 301 | { 302 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_OCPWP_L3_CLKSTCTRL); 303 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_ICSS_CLKSTCTRL); 304 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_CPSW_CLKSTCTRL); 305 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_LCDC_CLKSTCTRL); 306 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_CLK_24MHZ_CLKSTCTRL); 307 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_L4LS_CLKSTCTRL); 308 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_L4HS_CLKSTCTRL); 309 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_L4FW_CLKSTCTRL); 310 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_L3S_CLKSTCTRL); 311 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_PER_L3_CLKSTCTRL); 312 | } 313 | 314 | void clkdm_wake(void) 315 | { 316 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_L3_CLKSTCTRL); 317 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_L3S_CLKSTCTRL); 318 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_L4FW_CLKSTCTRL); 319 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_L4HS_CLKSTCTRL); 320 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_L4LS_CLKSTCTRL); 321 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_CLK_24MHZ_CLKSTCTRL); 322 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_LCDC_CLKSTCTRL); 323 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_CPSW_CLKSTCTRL); 324 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_ICSS_CLKSTCTRL); 325 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_PER_OCPWP_L3_CLKSTCTRL); 326 | } 327 | 328 | void mpu_clkdm_sleep(void) 329 | { 330 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_MPU_CLKSTCTRL); 331 | } 332 | 333 | void mpu_clkdm_wake(void) 334 | { 335 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_MPU_CLKSTCTRL); 336 | } 337 | 338 | void wkup_clkdm_sleep(void) 339 | { 340 | clkdm_state_change(CLKDM_SLEEP, AM335X_CM_WKUP_CLKSTCTRL); 341 | } 342 | 343 | void wkup_clkdm_wake(void) 344 | { 345 | clkdm_state_change(CLKDM_WAKE, AM335X_CM_WKUP_CLKSTCTRL); 346 | } 347 | 348 | /* PD related */ 349 | int pd_state_change(int val, int pd) 350 | { 351 | if (pd == PD_MPU) { 352 | pd_mpu_stctrl_next_val = val; 353 | pd_mpu_pwrstst_prev_val = __raw_readl(AM335X_PM_MPU_PWRSTST); 354 | __raw_writel(val, AM335X_PM_MPU_PWRSTCTRL); 355 | } else if (pd == PD_PER) { 356 | pd_per_stctrl_next_val = val; 357 | pd_per_pwrstst_prev_val = __raw_readl(AM335X_PM_PER_PWRSTST); 358 | __raw_writel(val, AM335X_PM_PER_PWRSTCTRL); 359 | } 360 | 361 | return 0; 362 | } 363 | 364 | int mpu_ram_ret_state_change(int val, int var) 365 | { 366 | var = var_mod(var, MPU_RAM_RETSTATE_MASK, 367 | (val << MPU_RAM_RETSTATE_SHIFT)); 368 | 369 | return var; 370 | } 371 | 372 | int mpu_l1_ret_state_change(int val, int var) 373 | { 374 | var = var_mod(var, MPU_L1_RETSTATE_MASK, 375 | (val << MPU_L1_RETSTATE_SHIFT)); 376 | 377 | return var; 378 | } 379 | 380 | int mpu_l2_ret_state_change(int val, int var) 381 | { 382 | var = var_mod(var, MPU_L2_RETSTATE_MASK, 383 | (val << MPU_L2_RETSTATE_SHIFT)); 384 | 385 | return var; 386 | } 387 | 388 | int icss_mem_ret_state_change(int val, int var) 389 | { 390 | var = var_mod(var, PER_ICSS_MEM_RETSTATE_MASK, 391 | (val << PER_ICSS_MEM_RETSTATE_SHIFT)); 392 | 393 | return var; 394 | } 395 | 396 | int per_mem_ret_state_change(int val, int var) 397 | { 398 | var = var_mod(var, PER_MEM_RETSTATE_MASK, 399 | (val << PER_MEM_RETSTATE_SHIFT)); 400 | 401 | return var; 402 | } 403 | 404 | int ocmc_mem_ret_state_change(int val, int var) 405 | { 406 | var = var_mod(var, PER_RAM_MEM_RETSTATE_MASK, 407 | (val << PER_RAM_MEM_RETSTATE_SHIFT)); 408 | 409 | return var; 410 | } 411 | 412 | int mpu_ram_on_state_change(int val, int var) 413 | { 414 | /* Currently don't do anything */ 415 | return var; 416 | } 417 | 418 | int icss_mem_on_state_change(int val, int var) 419 | { 420 | var = var_mod(var, PER_ICSS_MEM_ONSTATE_MASK, 421 | (val << PER_ICSS_MEM_ONSTATE_SHIFT)); 422 | 423 | return var; 424 | } 425 | 426 | int per_mem_on_state_change(int val, int var) 427 | { 428 | var = var_mod(var, PER_MEM_ONSTATE_MASK, 429 | (val << PER_MEM_ONSTATE_SHIFT)); 430 | 431 | return var; 432 | } 433 | 434 | int ocmc_mem_on_state_change(int val, int var) 435 | { 436 | var = var_mod(var, PER_RAM_MEM_ONSTATE_MASK, 437 | (val << PER_RAM_MEM_ONSTATE_SHIFT)); 438 | 439 | return var; 440 | } 441 | 442 | int per_powerst_change(int val, int var) 443 | { 444 | var = var_mod(var, PER_POWERSTATE_MASK, 445 | (val << PER_POWERSTATE_SHIFT)); 446 | 447 | return var; 448 | } 449 | 450 | int mpu_powerst_change(int val, int var) 451 | { 452 | var = var_mod(var, MPU_POWERSTATE_MASK, 453 | (val << MPU_POWERSTATE_SHIFT)); 454 | 455 | return var; 456 | } 457 | 458 | static int _next_pd_per_stctrl_val(state) 459 | { 460 | int v = 0; 461 | 462 | if (state == 0) { 463 | v = per_powerst_change(ds0_data.pd_per_state, v); 464 | v = icss_mem_ret_state_change(ds0_data.pd_per_icss_mem_ret_state, v); 465 | v = per_mem_ret_state_change(ds0_data.pd_per_mem_ret_state, v); 466 | v = ocmc_mem_ret_state_change(ds0_data.pd_per_ocmc_ret_state, v); 467 | } else if (state == 1) { 468 | v = per_powerst_change(ds1_data.pd_per_state, v); 469 | v = icss_mem_on_state_change(ds1_data.pd_per_icss_mem_on_state, v); 470 | v = per_mem_on_state_change(ds1_data.pd_per_mem_on_state, v); 471 | v = ocmc_mem_on_state_change(ds1_data.pd_per_ocmc_on_state, v); 472 | } else if (state == 2) { 473 | v = per_powerst_change(ds2_data.pd_per_state, v); 474 | v = icss_mem_on_state_change(ds2_data.pd_per_icss_mem_on_state, v); 475 | v = per_mem_on_state_change(ds2_data.pd_per_mem_on_state, v); 476 | v = ocmc_mem_on_state_change(ds2_data.pd_per_ocmc_on_state, v); 477 | } else if (state == 3) { 478 | v = per_powerst_change 479 | (standby_data.pd_per_state, v); 480 | v = icss_mem_on_state_change 481 | (standby_data.pd_per_icss_mem_on_state, v); 482 | v = per_mem_on_state_change 483 | (standby_data.pd_per_mem_on_state, v); 484 | v = ocmc_mem_on_state_change 485 | (standby_data.pd_per_ocmc_on_state, v); 486 | } 487 | 488 | return v; 489 | } 490 | 491 | int get_pd_per_stctrl_val(int state) 492 | { 493 | /* Backup the current value for restoration */ 494 | pd_per_stctrl_prev_val = __raw_readl(AM335X_PM_PER_PWRSTCTRL); 495 | 496 | return _next_pd_per_stctrl_val(state); 497 | } 498 | 499 | static int _next_pd_mpu_stctrl_val(state) 500 | { 501 | int v = 0; 502 | 503 | if (state == 0) { 504 | v = mpu_powerst_change(ds0_data.pd_mpu_state, v); 505 | v = mpu_ram_ret_state_change(ds0_data.pd_mpu_ram_ret_state, v); 506 | v = mpu_l1_ret_state_change(ds0_data.pd_mpu_l1_ret_state, v); 507 | v = mpu_l2_ret_state_change(ds0_data.pd_mpu_l2_ret_state, v); 508 | } else if (state == 1) { 509 | v = mpu_powerst_change(ds1_data.pd_mpu_state, v); 510 | v = mpu_ram_ret_state_change(ds1_data.pd_mpu_ram_ret_state, v); 511 | v = mpu_l1_ret_state_change(ds1_data.pd_mpu_l1_ret_state, v); 512 | v = mpu_l2_ret_state_change(ds1_data.pd_mpu_l2_ret_state, v); 513 | } else if (state == 2) { 514 | v = mpu_powerst_change(ds2_data.pd_mpu_state, v); 515 | v = mpu_ram_on_state_change(ds2_data.pd_mpu_ram_on_state, v); 516 | } else if (state == 3) { 517 | v = mpu_powerst_change 518 | (standby_data.pd_mpu_state, v); 519 | v = mpu_ram_ret_state_change 520 | (standby_data.pd_mpu_ram_ret_state, v); 521 | v = mpu_l1_ret_state_change 522 | (standby_data.pd_mpu_l1_ret_state, v); 523 | v = mpu_l2_ret_state_change 524 | (standby_data.pd_mpu_l2_ret_state, v); 525 | } 526 | return v; 527 | } 528 | 529 | int get_pd_mpu_stctrl_val(int state) 530 | { 531 | /* Backup the current value for restoration */ 532 | pd_mpu_stctrl_prev_val = __raw_readl(AM335X_PM_MPU_PWRSTCTRL); 533 | 534 | return _next_pd_mpu_stctrl_val(state); 535 | } 536 | 537 | /* DeepSleep related */ 538 | int disable_master_oscillator(void) 539 | { 540 | int v = __raw_readl(DEEPSLEEP_CTRL); 541 | 542 | v = var_mod(v, DS_ENABLE_MASK, (1 << DS_ENABLE_SHIFT)); 543 | 544 | __raw_writel(v, DEEPSLEEP_CTRL); 545 | 546 | return 0; 547 | } 548 | 549 | int enable_master_oscillator() 550 | { 551 | int v = __raw_readl(DEEPSLEEP_CTRL); 552 | 553 | v = var_mod(v, DS_ENABLE_MASK, (0 << DS_ENABLE_SHIFT)); 554 | 555 | __raw_writel(v, DEEPSLEEP_CTRL); 556 | 557 | return 0; 558 | } 559 | 560 | void configure_deepsleep_count(int ds_count) 561 | { 562 | int v = __raw_readl(DEEPSLEEP_CTRL); 563 | 564 | v = var_mod(v, DS_COUNT_MASK, (ds_count << DS_COUNT_SHIFT)); 565 | 566 | __raw_writel(v, DEEPSLEEP_CTRL); 567 | } 568 | 569 | /* 1ms timer */ 570 | static int check_timer1(int base) 571 | { 572 | int v = 0; 573 | 574 | v = __raw_readl(base + 0x10); 575 | 576 | if ((v & 0x14) != 0x14) { 577 | __raw_writel(0x214, base + 0x10); 578 | return 1; 579 | } 580 | 581 | return 0; 582 | } 583 | 584 | static int check_i2c(int base) 585 | { 586 | int v = 0; 587 | 588 | v = __raw_readl(base + 0x10); 589 | 590 | if ((v & 0x1C) != 0x1C) { 591 | __raw_writel(0x1C, base + 0x10); 592 | return 1; 593 | } 594 | 595 | return 0; 596 | } 597 | 598 | static int check_adtsc(int base) 599 | { 600 | int v = 0; 601 | 602 | v = __raw_readl(base + 0x10); 603 | 604 | if ((v & 0xC) != 0xC) { 605 | __raw_writel(0xCc, base + 0x10); 606 | return 1; 607 | } 608 | 609 | return 0; 610 | } 611 | 612 | static int check_uart(int base) 613 | { 614 | int v = 0; 615 | 616 | v = __raw_readl(base + 0x54); 617 | 618 | if ((v & 0x1C) != 0x1C) { 619 | __raw_writel(0x1C, base + 0x54); 620 | return 1; 621 | } 622 | 623 | return 0; 624 | } 625 | 626 | static int check_gpio(int base) 627 | { 628 | int v = 0; 629 | 630 | v = __raw_readl(base + 0x10); 631 | 632 | if ((v & 0x1C) != 0x1C) { 633 | __raw_writel(0x1C, base + 0x10); 634 | return 1; 635 | } 636 | 637 | return 0; 638 | } 639 | 640 | static int check_rtc(int base) 641 | { 642 | int v = 0; 643 | 644 | v = __raw_readl(base + 0x78); 645 | 646 | if ((v & 0x3) != 0x3) { 647 | __raw_writel(0x3, base + 0x78); 648 | return 1; 649 | } 650 | 651 | return 0; 652 | } 653 | 654 | static int check_wdt(int base) 655 | { 656 | int v = 0; 657 | 658 | v = __raw_readl(base + 0x10); 659 | 660 | if ((v & 0x18) != 0x18) { 661 | __raw_writel(0x18, base + 0x10); 662 | return 1; 663 | } 664 | 665 | return 0; 666 | } 667 | 668 | /* 669 | * In standby state we expect only the MPU_WAKE interrupt to come in 670 | */ 671 | void configure_standby_wake_sources(int wake_sources, int mod_check) 672 | { 673 | nvic_enable_irq(AM335X_IRQ_MPU_WAKE); 674 | } 675 | 676 | /* 677 | * A8 is expected to have left the module in a state where it will 678 | * cause a wakeup event. Ideally, this function should just enable 679 | * the NVIC interrupt 680 | */ 681 | void configure_wake_sources(int wake_sources, int mod_check) 682 | { 683 | int v = 0; 684 | 685 | if (wake_sources != 0 || (mod_check == 0)) 686 | cmd_wake_sources = wake_sources; 687 | else 688 | cmd_wake_sources = WAKE_ALL; 689 | 690 | /* 691 | * This flag is for checking the SYSCONFIG of the module 692 | * and then gating the clock. The clock needs to be gated 693 | * for the module to generate swake 694 | */ 695 | mod_check = 0; 696 | 697 | /* Enable wakeup interrupts from required wake sources */ 698 | if (BB_USB_WAKE) { 699 | /* A8 driver needs to configure SYSCONFIG. No M3 access */ 700 | module_state_change(MODULE_DISABLE, AM335X_CM_PER_USB0_CLKCTRL); 701 | nvic_enable_irq(AM335X_IRQ_USBWAKEUP); 702 | } 703 | 704 | if(BB_I2C0_WAKE) { 705 | if(mod_check) { 706 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_I2C0_CLKCTRL); 707 | v = check_i2c(I2C0_BASE); 708 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_I2C0_CLKCTRL); 709 | } 710 | nvic_enable_irq(AM335X_IRQ_I2C0_WAKE); 711 | } 712 | 713 | if(BB_ADTSC_WAKE) { 714 | if(mod_check) { 715 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_ADC_TSC_CLKCTRL); 716 | v = check_adtsc(ADC_TSC_BASE); 717 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_ADC_TSC_CLKCTRL); 718 | } 719 | nvic_enable_irq(AM335X_IRQ_ADC_TSC_WAKE); 720 | } 721 | 722 | if(BB_UART0_WAKE) { 723 | if(mod_check) { 724 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_UART0_CLKCTRL); 725 | v = check_uart(UART0_BASE); 726 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_UART0_CLKCTRL); 727 | } 728 | nvic_enable_irq(AM335X_IRQ_UART0_WAKE); 729 | } 730 | 731 | if(BB_GPIO0_WAKE0) { 732 | if(mod_check) { 733 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 734 | v = check_gpio(GPIO_BASE); 735 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 736 | } 737 | nvic_enable_irq(AM335X_IRQ_GPIO0_WAKE0); 738 | } 739 | 740 | if(BB_GPIO0_WAKE1) { 741 | if(mod_check) { 742 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 743 | v = check_gpio(GPIO_BASE); 744 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 745 | } 746 | nvic_enable_irq(AM335X_IRQ_GPIO0_WAKE1); 747 | } 748 | 749 | if(BB_RTC_ALARM_WAKE) { 750 | if(mod_check) { 751 | module_state_change(MODULE_ENABLE, AM335X_CM_RTC_RTC_CLKCTRL); 752 | v = check_rtc(RTCSS_BASE); 753 | } 754 | nvic_enable_irq(AM335X_IRQ_RTC_ALARM_WAKE); 755 | } 756 | 757 | if(BB_TIMER1_WAKE) { 758 | if(mod_check) { 759 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_TIMER1_CLKCTRL); 760 | v = check_timer1(DMTIMER1_BASE); 761 | } 762 | nvic_enable_irq(AM335X_IRQ_TIMER1_WAKE); 763 | } 764 | 765 | if(BB_WDT1_WAKE) { 766 | if(mod_check) { 767 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_WDT1_CLKCTRL); 768 | v = check_wdt(WDT1_BASE); 769 | } 770 | nvic_enable_irq(AM335X_IRQ_WDT1_WAKE); 771 | } 772 | 773 | #if 0 774 | /* Not recommended */ 775 | if(BB_RTC_TIMER_WAKE) { 776 | module_state_change(MODULE_ENABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 777 | module_wakeup_enable(AM335X_CM_PER_USB0_SYSCONFIG); 778 | nvic_enable_irq(AM335X_IRQ_RTC_TIMER_WAKE); 779 | } 780 | 781 | if(BB_MPU_WAKE) { 782 | module_wakeup_enable(AM335X_CM_PER_USB0_SYSCONFIG); 783 | nvic_enable_irq(AM335X_IRQ_MPU_WAKE); 784 | } 785 | 786 | if(BB_TIMER0_WAKE) { 787 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 788 | module_wakeup_enable(AM335X_CM_PER_USB0_SYSCONFIG); 789 | nvic_enable_irq(AM335X_IRQ_TIMER0_WAKE); 790 | } 791 | 792 | if(BB_WDT0_WAKE) { 793 | module_state_change(MODULE_DISABLE, AM335X_CM_WKUP_GPIO0_CLKCTRL); 794 | module_wakeup_enable(AM335X_CM_PER_USB0_SYSCONFIG); 795 | nvic_enable_irq(AM335X_IRQ_WDT0_WAKE); 796 | } 797 | #endif 798 | 799 | if(BB_USBWOUT0) 800 | nvic_enable_irq(AM335X_IRQ_USB0WOUT); 801 | 802 | if(BB_USBWOUT1) 803 | nvic_enable_irq(AM335X_IRQ_USB1WOUT); 804 | } 805 | 806 | void clear_wake_sources(void) 807 | { 808 | /* 809 | * Clear the global variable 810 | * and then disable all wake interrupts 811 | */ 812 | 813 | cmd_wake_sources = 0x0; /* All disabled */ 814 | 815 | /* Disable the wake interrupts */ 816 | nvic_disable_irq(AM335X_IRQ_USBWAKEUP); 817 | nvic_disable_irq(AM335X_IRQ_I2C0_WAKE); 818 | nvic_disable_irq(AM335X_IRQ_RTC_TIMER_WAKE); 819 | nvic_disable_irq(AM335X_IRQ_RTC_ALARM_WAKE); 820 | nvic_disable_irq(AM335X_IRQ_TIMER0_WAKE); 821 | nvic_disable_irq(AM335X_IRQ_TIMER1_WAKE); 822 | nvic_disable_irq(AM335X_IRQ_UART0_WAKE); 823 | nvic_disable_irq(AM335X_IRQ_GPIO0_WAKE0); 824 | nvic_disable_irq(AM335X_IRQ_GPIO0_WAKE1); 825 | nvic_disable_irq(AM335X_IRQ_MPU_WAKE); 826 | nvic_disable_irq(AM335X_IRQ_WDT0_WAKE); 827 | nvic_disable_irq(AM335X_IRQ_WDT1_WAKE); 828 | nvic_disable_irq(AM335X_IRQ_ADC_TSC_WAKE); 829 | nvic_disable_irq(AM335X_IRQ_USB0WOUT); 830 | nvic_disable_irq(AM335X_IRQ_USB1WOUT); 831 | 832 | /* TODO: Clear all the pending interrupts */ 833 | } 834 | 835 | void pd_state_restore(void) 836 | { 837 | __raw_writel(pd_per_stctrl_prev_val, AM335X_PM_PER_PWRSTCTRL); 838 | __raw_writel(pd_mpu_stctrl_prev_val, AM335X_PM_MPU_PWRSTCTRL); 839 | } 840 | 841 | /* Checking only the stst bits for now */ 842 | int verify_pd_transitions(void) 843 | { 844 | int mpu_ctrl, mpu_stst, per_ctrl, per_stst; 845 | 846 | mpu_ctrl = __raw_readl(AM335X_PM_MPU_PWRSTCTRL); 847 | per_ctrl = __raw_readl(AM335X_PM_PER_PWRSTCTRL); 848 | 849 | mpu_stst = __raw_readl(AM335X_PM_MPU_PWRSTST); 850 | per_stst = __raw_readl(AM335X_PM_PER_PWRSTST); 851 | 852 | if (((mpu_ctrl & 0x3) == (mpu_stst & 0x3)) && 853 | ((per_ctrl & 0x3) == (per_stst & 0x3))) 854 | return CMD_STAT_PASS; 855 | else 856 | return CMD_STAT_FAIL; 857 | } 858 | 859 | /* New Power-down Sequence PG 2.0 */ 860 | void dpll_power_down(unsigned int dpll) 861 | { 862 | int dpll_reg, dpll_reg_val, dpll_pwr_sw_status_reg; 863 | unsigned int sw_ctrl_dpll_bit, isoscan_bit, ret_bit, reset_bit, iso_bit; 864 | unsigned int pgoodin_bit, ponin_bit; 865 | unsigned int pgoodout_status_bit, ponout_status_bit; 866 | 867 | switch (dpll) { 868 | case DPLL_PER: 869 | dpll_reg = DPLL_PWR_SW_CTRL; 870 | sw_ctrl_dpll_bit = SW_CTRL_PER_DPLL; 871 | isoscan_bit = ISOSCAN_PER; 872 | ret_bit = RET_PER; 873 | reset_bit = RESET_PER; 874 | iso_bit = ISO_PER; 875 | pgoodin_bit = PGOODIN_PER; 876 | ponin_bit = PONIN_PER; 877 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 878 | pgoodout_status_bit = PGOODOUT_PER_STATUS; 879 | ponout_status_bit = PONOUT_PER_STATUS; 880 | break; 881 | case DPLL_DISP: 882 | dpll_reg = DPLL_PWR_SW_CTRL; 883 | sw_ctrl_dpll_bit = SW_CTRL_DISP_DPLL; 884 | isoscan_bit = ISOSCAN_DISP; 885 | ret_bit = RET_DISP; 886 | reset_bit = RESET_DISP; 887 | iso_bit = ISO_DISP; 888 | pgoodin_bit = PGOODIN_DISP; 889 | ponin_bit = PONIN_DISP; 890 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 891 | pgoodout_status_bit = PGOODOUT_DISP_STATUS; 892 | ponout_status_bit = PONOUT_DISP_STATUS; 893 | break; 894 | case DPLL_DDR: 895 | dpll_reg = DPLL_PWR_SW_CTRL; 896 | sw_ctrl_dpll_bit = SW_CTRL_DDR_DPLL; 897 | isoscan_bit = ISOSCAN_DDR; 898 | ret_bit = RET_DDR; 899 | reset_bit = RESET_DDR; 900 | iso_bit = ISO_DDR; 901 | pgoodin_bit = PGOODIN_DDR; 902 | ponin_bit = PONIN_DDR; 903 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 904 | pgoodout_status_bit = PGOODOUT_DDR_STATUS; 905 | ponout_status_bit = PONOUT_DDR_STATUS; 906 | break; 907 | default: 908 | return; 909 | } 910 | 911 | /* Configure bit to select Control module selection for DPLL */ 912 | dpll_reg_val = __raw_readl(dpll_reg); 913 | dpll_reg_val |= sw_ctrl_dpll_bit; 914 | __raw_writel(dpll_reg_val, dpll_reg); 915 | 916 | /* Assert ISO bit high */ 917 | dpll_reg_val = __raw_readl(dpll_reg); 918 | dpll_reg_val |= iso_bit; 919 | __raw_writel(dpll_reg_val, dpll_reg); 920 | 921 | /* ISO_SCAN, RET should be asserted high */ 922 | dpll_reg_val = __raw_readl(dpll_reg); 923 | dpll_reg_val |= (isoscan_bit | ret_bit); 924 | __raw_writel(dpll_reg_val, dpll_reg); 925 | 926 | /* Assert DPLL reset to 1 */ 927 | dpll_reg_val = __raw_readl(dpll_reg); 928 | dpll_reg_val |= reset_bit; 929 | __raw_writel(dpll_reg_val, dpll_reg); 930 | 931 | /* PGOODIN signal is de-asserted low */ 932 | dpll_reg_val = __raw_readl(dpll_reg); 933 | dpll_reg_val &= ~pgoodin_bit; 934 | __raw_writel(dpll_reg_val, dpll_reg); 935 | 936 | /* PONIN signal is de-asserted low */ 937 | dpll_reg_val = __raw_readl(dpll_reg); 938 | dpll_reg_val &= ~ponin_bit; 939 | __raw_writel(dpll_reg_val, dpll_reg); 940 | 941 | /* Poll for PONOUT and PGOODOUT signal status as 0 */ 942 | while (__raw_readl(dpll_pwr_sw_status_reg) & 943 | (pgoodout_status_bit | ponout_status_bit)) { 944 | } 945 | } 946 | 947 | /* New Power-up Sequence PG 2.0 */ 948 | void dpll_power_up(unsigned int dpll) 949 | { 950 | int dpll_reg, dpll_reg_val, dpll_pwr_sw_status_reg; 951 | unsigned int sw_ctrl_dpll_bit, isoscan_bit, ret_bit, reset_bit, iso_bit; 952 | unsigned int pgoodin_bit, ponin_bit; 953 | unsigned int pgoodout_status_bit, ponout_status_bit; 954 | 955 | switch (dpll) { 956 | case DPLL_PER: 957 | dpll_reg = DPLL_PWR_SW_CTRL; 958 | sw_ctrl_dpll_bit = SW_CTRL_PER_DPLL; 959 | isoscan_bit = ISOSCAN_PER; 960 | ret_bit = RET_PER; 961 | reset_bit = RESET_PER; 962 | iso_bit = ISO_PER; 963 | pgoodin_bit = PGOODIN_PER; 964 | ponin_bit = PONIN_PER; 965 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 966 | pgoodout_status_bit = PGOODOUT_PER_STATUS; 967 | ponout_status_bit = PONOUT_PER_STATUS; 968 | break; 969 | case DPLL_DISP: 970 | dpll_reg = DPLL_PWR_SW_CTRL; 971 | sw_ctrl_dpll_bit = SW_CTRL_DISP_DPLL; 972 | isoscan_bit = ISOSCAN_DISP; 973 | ret_bit = RET_DISP; 974 | reset_bit = RESET_DISP; 975 | iso_bit = ISO_DISP; 976 | pgoodin_bit = PGOODIN_DISP; 977 | ponin_bit = PONIN_DISP; 978 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 979 | pgoodout_status_bit = PGOODOUT_DISP_STATUS; 980 | ponout_status_bit = PONOUT_DISP_STATUS; 981 | break; 982 | case DPLL_DDR: 983 | dpll_reg = DPLL_PWR_SW_CTRL; 984 | sw_ctrl_dpll_bit = SW_CTRL_DDR_DPLL; 985 | isoscan_bit = ISOSCAN_DDR; 986 | ret_bit = RET_DDR; 987 | reset_bit = RESET_DDR; 988 | iso_bit = ISO_DDR; 989 | pgoodin_bit = PGOODIN_DDR; 990 | ponin_bit = PONIN_DDR; 991 | dpll_pwr_sw_status_reg = DPLL_PWR_SW_STATUS; 992 | pgoodout_status_bit = PGOODOUT_DDR_STATUS; 993 | ponout_status_bit = PONOUT_DDR_STATUS; 994 | break; 995 | default: 996 | return; 997 | } 998 | 999 | /* PONIN is asserted high */ 1000 | dpll_reg_val = __raw_readl(dpll_reg); 1001 | dpll_reg_val |= ponin_bit; 1002 | __raw_writel(dpll_reg_val, dpll_reg); 1003 | 1004 | /* Poll for PONOUT to become high */ 1005 | while (!(__raw_readl(dpll_pwr_sw_status_reg) & ponout_status_bit)) { 1006 | } 1007 | 1008 | /* PGOODIN is asserted high */ 1009 | dpll_reg_val = __raw_readl(dpll_reg); 1010 | dpll_reg_val |= pgoodin_bit; 1011 | __raw_writel(dpll_reg_val, dpll_reg); 1012 | 1013 | /* Poll for PGOODOUT to become high */ 1014 | while (!(__raw_readl(dpll_pwr_sw_status_reg) & pgoodout_status_bit)) { 1015 | } 1016 | 1017 | /* De-assert DPLL RESET to 0 */ 1018 | dpll_reg_val = __raw_readl(dpll_reg); 1019 | dpll_reg_val &= ~reset_bit; 1020 | __raw_writel(dpll_reg_val, dpll_reg); 1021 | 1022 | /* ISO_SCAN, RET should be de-asserted low */ 1023 | dpll_reg_val = __raw_readl(dpll_reg); 1024 | dpll_reg_val &= ~(isoscan_bit | ret_bit); 1025 | __raw_writel(dpll_reg_val, dpll_reg); 1026 | 1027 | /* De-assert ISO signal */ 1028 | dpll_reg_val = __raw_readl(dpll_reg); 1029 | dpll_reg_val &= ~iso_bit; 1030 | __raw_writel(dpll_reg_val, dpll_reg); 1031 | 1032 | /* Re-Configure bit to select PRCM selection for DPLL */ 1033 | dpll_reg_val = __raw_readl(dpll_reg); 1034 | dpll_reg_val &= ~sw_ctrl_dpll_bit; 1035 | __raw_writel(dpll_reg_val, dpll_reg); 1036 | } 1037 | 1038 | void core_ldo_power_down(void) 1039 | { 1040 | unsigned int core_ldo; 1041 | 1042 | /* Configure RETMODE_ENABLE for CORE LDO */ 1043 | core_ldo = __raw_readl(AM335X_PRM_LDO_SRAM_CORE_CTRL); 1044 | core_ldo |= RETMODE_ENABLE; 1045 | __raw_writel(core_ldo, AM335X_PRM_LDO_SRAM_CORE_CTRL); 1046 | 1047 | /* Poll for LDO Status to be in retention (SRAMLDO_STATUS) */ 1048 | while (!(__raw_readl(AM335X_PRM_LDO_SRAM_CORE_CTRL) & SRAMLDO_STATUS)) { 1049 | } 1050 | } 1051 | 1052 | void core_ldo_power_up(void) 1053 | { 1054 | unsigned int core_ldo; 1055 | 1056 | /* Disable RETMODE for CORE LDO */ 1057 | core_ldo = __raw_readl(AM335X_PRM_LDO_SRAM_CORE_CTRL); 1058 | core_ldo &= ~RETMODE_ENABLE; 1059 | __raw_writel(core_ldo, AM335X_PRM_LDO_SRAM_CORE_CTRL); 1060 | 1061 | /* Poll for LDO status to be out of retention (SRAMLDO_STATUS) */ 1062 | while (__raw_readl(AM335X_PRM_LDO_SRAM_CORE_CTRL) & SRAMLDO_STATUS) { 1063 | } 1064 | } 1065 | --------------------------------------------------------------------------------