diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig index 30740742731..487e7faaaf0 100644 --- a/arch/arm/src/cxd56xx/Kconfig +++ b/arch/arm/src/cxd56xx/Kconfig @@ -44,6 +44,36 @@ config CXD56_ICC bool default y +config CXD56_FARAPI + bool + default y + select CXD56_CPUFIFO + +menu "Far API Configuration" + depends on CXD56_FARAPI + +config CXD56_FARAPI_VERSION_CHECK + bool "Far API Version Compatibility Check" + default y + ---help--- + Enable the Far API version compatibility check. If the version + mismatch is deteced during system bootup, the target system shows + the message to update the loader and gnssfw firmwares. + +if CXD56_FARAPI_VERSION_CHECK + +config CXD56_FARAPI_VERSION_FAILED_PANIC + bool "Far API Version Check Failed to PANIC" + default n + ---help--- + If the version mismatch is detected, do PANIC() to stop the system. +endif + +config CXD56_FARAPI_DEBUG + bool "Debug Far API" + +endmenu # Far API Configuration + menu "CXD56xx Peripheral Support" config CXD56_GPIO_IRQ diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs index cbc488ef2bc..7358cf97d43 100644 --- a/arch/arm/src/cxd56xx/Make.defs +++ b/arch/arm/src/cxd56xx/Make.defs @@ -83,6 +83,8 @@ CMN_CSRCS += up_copyarmstate.c endif endif +CHIP_ASRCS += cxd56_farapistub.S + CHIP_CSRCS = cxd56_allocateheap.c cxd56_idle.c CHIP_CSRCS += cxd56_serial.c cxd56_uart.c cxd56_irq.c CHIP_CSRCS += cxd56_start.c @@ -93,6 +95,8 @@ CHIP_CSRCS += cxd56_gpio.c CHIP_CSRCS += cxd56_pmic.c CHIP_CSRCS += cxd56_cpufifo.c CHIP_CSRCS += cxd56_icc.c +CHIP_CSRCS += cxd56_powermgr.c +CHIP_CSRCS += cxd56_farapi.c ifeq ($(CONFIG_CXD56_GPIO_IRQ),y) CHIP_CSRCS += cxd56_gpioint.c diff --git a/arch/arm/src/cxd56xx/cxd56_farapi.c b/arch/arm/src/cxd56xx/cxd56_farapi.c new file mode 100644 index 00000000000..db0cd8a7fdb --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_farapi.c @@ -0,0 +1,287 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_farapi.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include "up_arch.h" +#include "up_internal.h" +#include "chip.h" +#include "cxd56_icc.h" +#include "cxd56_config.h" +#include "cxd56_farapistub.h" +#include "hardware/cxd5602_backupmem.h" + +int PM_WakeUpCpu(int cpuid); + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GPS_CPU_ID (1) + +#ifndef CONFIG_CXD56_FARAPI_VERSION_CHECK +#define CONFIG_CXD56_FARAPI_VERSION_CHECK 1 +#endif + +#define CPU_ID (CXD56_CPU_BASE + 0x40) + +/**************************************************************************** + * Private Type + ****************************************************************************/ + +typedef int farapicallback(void *data); + +struct modulelist_s +{ + void *mod; + int cpuno; + void *reserved; + int16_t mbxid; +}; + +struct apimsg_s +{ + int id; + void *arg; + int16_t mbxid; + int16_t flagid; + int flagbitno; +}; + +struct farcallback_s +{ + int (*cbfunc)(void *); /* pointer to callback function */ + void *data; /* callback data */ + int flagbitno; /* callback eventflag bitno */ +}; + +struct farmsghead_s +{ + struct farmsghead_s *next; +}; + +struct farmsg_s +{ + struct farmsghead_s head; /* message head */ + int cpuid; /* CPU ID of API caller */ + int modid; /* module table offset */ + union + { + struct apimsg_s api; + struct farcallback_s cb; + } u; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern char Image$$MODLIST$$Base[]; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static sem_t g_farwait; +static sem_t g_farlock; +static struct pm_cpu_wakelock_s g_wlock = { + .count = 0, + .info = PM_CPUWAKELOCK_TAG('R', 'M', 0), +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int farapi_semtake(sem_t *id) +{ + while (sem_wait(id) != 0) + { + ASSERT(errno == EINTR); + } + return OK; +} + +#ifdef CONFIG_CXD56_FARAPI_DEBUG +static void dump_farapi_message(struct farmsg_s *msg) +{ + _info("cpuid : %d\n", msg->cpuid); + _info("modid : %d\n", msg->modid); + _info("id : %d\n", msg->u.api.id); + _info("arg : %08x\n", msg->u.api.arg); + _info("mbxid : %d\n", msg->u.api.mbxid); + _info("flagid: %d\n", msg->u.api.flagid); + _info("flagbitno: %d\n", msg->u.api.flagbitno); +} +# define fainfo(x, ...) _info(x, ##__VA_ARGS__) +#else +# define dump_farapi_message(x) +# define fainfo(x, ...) +#endif + +static int cxd56_sendmsg(int cpuid, int protoid, int msgtype, uint16_t pdata, + uint32_t data) +{ + iccmsg_t msg; + + msg.cpuid = cpuid; + msg.msgid = msgtype << 4; + msg.protodata = pdata; + msg.data = data; + return cxd56_iccsend(protoid, &msg, 0); +} + +static int cxd56_farapidonehandler(int cpuid, int protoid, + uint32_t pdata, uint32_t data, + FAR void *userdata) +{ + /* Receive event flag message as Far API done. + * We need only far API done event. + */ + + if (protoid == CXD56_PROTO_FLG && (pdata & 0xf) == 0x7) + { + /* Send event flag response */ + + cxd56_sendmsg(cpuid, CXD56_PROTO_FLG, 5, pdata & 0xff00, 0); + sem_post(&g_farwait); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +__attribute__((used)) +void farapi_main(int id, void *arg, struct modulelist_s *mlist) +{ + struct farmsg_s msg; + struct apimsg_s *api; + int ret; +#ifdef CONFIG_CXD56_GNSS_HOT_SLEEP + uint32_t gnscken; + + if (mlist->cpuno == GPS_CPU_ID) + { + gnscken = getreg32(CXD56_TOPREG_GNSDSP_CKEN); + if (((gnscken & GNSDSP_CKEN_P1) != GNSDSP_CKEN_P1) && + ((gnscken & GNSDSP_CKEN_COP) != GNSDSP_CKEN_COP)) + { + PM_WakeUpCpu(GPS_CPU_ID); + } + } +#endif + + farapi_semtake(&g_farlock); + + api = &msg.u.api; + + msg.cpuid = getreg32(CPU_ID); + msg.modid = mlist - (struct modulelist_s *)&Image$$MODLIST$$Base; + + api->id = id; + api->arg = arg; + api->mbxid = mlist->mbxid; + api->flagid = (msg.cpuid + 1) << 8 | 7; /* 7 is a magic. not zero */ + api->flagbitno = 0; /* ignore */ + + dump_farapi_message(&msg); + + /* Send request by mailbox protocol */ + + ret = cxd56_sendmsg(mlist->cpuno, CXD56_PROTO_MBX, 4, 1 << 8 | 1, + (uint32_t)(uintptr_t)&msg); + if (ret) + { + _err("Failed far api push\n"); + goto err; + } + + /* Suppress hot sleep until Far API done */ + + up_pm_acquire_wakelock(&g_wlock); + + /* Wait event flag message as Far API done */ + + farapi_semtake(&g_farwait); + + /* Permit hot sleep with Far API done */ + + up_pm_release_wakelock(&g_wlock); + + dump_farapi_message(&msg); + +err: + sem_post(&g_farlock); +} + +void cxd56_farapiinitialize(void) +{ +#ifdef CONFIG_CXD56_FARAPI_VERSION_CHECK + if (GET_SYSFW_VERSION_BUILD() < FARAPISTUB_VERSION) + { + _alert("Mismatched version: loader(%d) != Self(%d)\n", + GET_SYSFW_VERSION_BUILD(), FARAPISTUB_VERSION); + _alert("Please update loader and gnssfw firmwares!!\n"); +# ifdef CONFIG_CXD56_FARAPI_VERSION_FAILED_PANIC + PANIC(); +# endif + } +#endif + sem_init(&g_farlock, 0, 1); + sem_init(&g_farwait, 0, 0); + + cxd56_iccinit(CXD56_PROTO_MBX); + cxd56_iccinit(CXD56_PROTO_FLG); + + /* Setup CPU FIFO interrupt for SYS and GNSS */ + + cxd56_iccregisterhandler(CXD56_PROTO_MBX, cxd56_farapidonehandler, NULL); + cxd56_iccregisterhandler(CXD56_PROTO_FLG, cxd56_farapidonehandler, NULL); +} diff --git a/arch/arm/src/cxd56xx/cxd56_farapi.h b/arch/arm/src/cxd56xx/cxd56_farapi.h new file mode 100644 index 00000000000..76cc9a127c0 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_farapi.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_farapi.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_FARAPI_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_FARAPI_H + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +void cxd56_farapiinitialize(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_FARAPI_H */ diff --git a/arch/arm/src/cxd56xx/cxd56_farapistub.S b/arch/arm/src/cxd56xx/cxd56_farapistub.S new file mode 100644 index 00000000000..28cddfc510a --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_farapistub.S @@ -0,0 +1,1186 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_farapistub.S + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_power_mgr + + .align 2 +3: + + /* PM_GpsPllClockSetSource */ + nop + nop + + /* PM_PmicGetChargingPortType */ + nop + nop + + /* PM_PmicSetChargingCurrentValue */ + nop + nop + + /* PM_PmicStartCharging */ + nop + nop + + /* PM_PmicStopCharging */ + nop + nop + + /* PM_PeriPowerOn */ + nop + nop + + /* PM_PeriPowerOff */ + nop + nop + + /* _PM_PeriClockEnable */ + nop + nop + + /* _PM_PeriClockDisable */ + nop + nop + + /* _PM_UpdateCpuFreqInfo */ + nop + nop + + /* PM_PmicPowerOn */ + nop + nop + + /* PM_PmicPowerOff */ + nop + nop + + /* PM_SetWakeupTrigger */ + nop + nop + + /* PM_HostifClockEnable */ + nop + nop + + /* PM_HostifClockDisable */ + nop + nop + + .global PM_StartCpu + .thumb_func +PM_StartCpu: + mov r12, pc + b 1b + + .global PM_StopCpu + .thumb_func +PM_StopCpu: + mov r12, pc + b 1b + + .global PM_SleepCpu + .thumb_func +PM_SleepCpu: + mov r12, pc + b 1b + + .global PM_WakeUpCpu + .thumb_func +PM_WakeUpCpu: + mov r12, pc + b 1b + + .global PM_ColdSleep + .thumb_func +PM_ColdSleep: + mov r12, pc + b 1b + + .global PM_DeepSleep + .thumb_func +PM_DeepSleep: + mov r12, pc + b 1b + + .global PM_Reboot + .thumb_func +PM_Reboot: + mov r12, pc + b 1b + + .global PM_LoadImage + .thumb_func +PM_LoadImage: + mov r12, pc + b 1b + + /* PM_LoadImageToAddress */ + nop + nop + + /* PM_RamControlByAddress */ + nop + nop + + /* PM_ChangeClock */ + nop + nop + + .global PM_PmicControl + .thumb_func +PM_PmicControl: + mov r12, pc + b 1b + + /* PM_BootCpu */ + nop + nop + + /* PM_BootCpuWithWaitMode */ + nop + nop + + /* PM_GetClock */ + nop + nop + + .section .modulelist, "ax" + .align 2 + .global _modulelist_power_mgr +_modulelist_power_mgr: + .weak _module_power_mgr + .word _module_power_mgr + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_flash_mgr + + .align 2 +3: + + /* FM_GetRegistryValue */ + nop + nop + + /* FM_SetRegistryValue */ + nop + nop + + /* FM_SetRegistryValueList */ + nop + nop + + /* FM_DeleteRegistryKey */ + nop + nop + + /* FM_GenerateRegistryKey */ + nop + nop + + /* FM_Sync */ + nop + nop + + /* FM_FileOpen */ + nop + nop + + /* FM_FileClose */ + nop + nop + + /* FM_FileRead */ + nop + nop + + /* FM_FileWrite */ + nop + nop + + /* FM_FileSeek */ + nop + nop + + /* FM_FileFlush */ + nop + nop + + /* FM_FileDelete */ + nop + nop + + .global FM_RawWrite + .thumb_func +FM_RawWrite: + mov r12, pc + b 1b + + .global FM_RawRead + .thumb_func +FM_RawRead: + mov r12, pc + b 1b + + .global FM_RawEraseSector + .thumb_func +FM_RawEraseSector: + mov r12, pc + b 1b + + /* FM_FileRename */ + nop + nop + + /* FM_FileGetAttr */ + nop + nop + + /* FM_FileSetAttr */ + nop + nop + + /* FM_FileClearAttr */ + nop + nop + + .global FM_RawVerifyWrite + .thumb_func +FM_RawVerifyWrite: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_flash_mgr +_modulelist_flash_mgr: + .weak _module_flash_mgr + .word _module_flash_mgr + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_rtc_mgr + + .align 2 +3: + + /* SYS_RtcMgrSetTime */ + nop + nop + + /* SYS_RtcMgrGetTime */ + nop + nop + + /* SYS_RtcMgrConvTime */ + nop + nop + + /* SYS_RtcMgrConvCalendarTime */ + nop + nop + + /* SYS_RtcMgrSetCalendarTime */ + nop + nop + + /* SYS_RtcMgrGetCalendarTime */ + nop + nop + + /* SYS_RtcMgrAdjustTime */ + nop + nop + + /* SYS_RtcMgrRequestAlarm */ + nop + nop + + /* SYS_RtcMgrCancelAlarm */ + nop + nop + + .section .modulelist, "ax" + .align 2 + .global _modulelist_rtc_mgr +_modulelist_rtc_mgr: + .weak _module_rtc_mgr + .word _module_rtc_mgr + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_gnss_pwr + + .align 2 +3: + + /* GNSP_ChangeClockBoot */ + nop + nop + + /* GNSP_ChangeClockNormal */ + nop + nop + + /* GNSP_SetAttribute */ + nop + nop + + /* GNSP_GetPowerStatus */ + nop + nop + + /* GNSP_PonGnss */ + nop + nop + + /* GNSP_PoffGnss */ + nop + nop + + /* GNSP_Sleep */ + nop + nop + + /* GNSP_Wakeup */ + nop + nop + + /* GNSP_SetWakeupTime */ + nop + nop + + /* GNSP_GetAttribute */ + nop + nop + + /* GNSP_ClockOn */ + nop + nop + + /* GNSP_ClockOff */ + nop + nop + + /* GNSP_ChangeMode */ + nop + nop + + /* GNSP_EnableIo */ + nop + nop + + /* GNSP_ControlGpioOut */ + nop + nop + + /* GNSP_Debug */ + nop + nop + + /* GNSP_ChangeClockRtc */ + nop + nop + + /* GNSP_ChangeClockSFCClkup */ + nop + nop + + /* GNSP_ChangeClockSFCClkdwn */ + nop + nop + + /* GNSP_GetBootCause */ + nop + nop + + /* GNSP_GetWakeupTrigger */ + nop + nop + + /* GNSP_SelfReboot */ + nop + nop + + /* GNSP_Start_KeepPPSOut */ + nop + nop + + /* GNSP_Stop_KeepPPSOut */ + nop + nop + + /* GNSP_SetSleepState */ + nop + nop + + /* GNSP_FreeSysMemory */ + nop + nop + + .section .modulelist, "ax" + .align 2 + .global _modulelist_gnss_pwr +_modulelist_gnss_pwr: + .weak _module_gnss_pwr + .word _module_gnss_pwr + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_aca + + .align 2 +3: + + .global AS_AcaControl + .thumb_func +AS_AcaControl: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_aca +_modulelist_aca: + .weak _module_aca + .word _module_aca + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_pinconfig + + .align 2 +3: + + .global PD_PinConfigs + .thumb_func +PD_PinConfigs: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_pinconfig +_modulelist_pinconfig: + .weak _module_pinconfig + .word _module_pinconfig + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_uart + + .align 2 +3: + + .global PD_UartInit + .thumb_func +PD_UartInit: + mov r12, pc + b 1b + + .global PD_UartUninit + .thumb_func +PD_UartUninit: + mov r12, pc + b 1b + + .global PD_UartConfiguration + .thumb_func +PD_UartConfiguration: + mov r12, pc + b 1b + + .global PD_UartEnable + .thumb_func +PD_UartEnable: + mov r12, pc + b 1b + + .global PD_UartDisable + .thumb_func +PD_UartDisable: + mov r12, pc + b 1b + + .global PD_UartReceive + .thumb_func +PD_UartReceive: + mov r12, pc + b 1b + + .global PD_UartSend + .thumb_func +PD_UartSend: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_uart +_modulelist_uart: + .weak _module_uart + .word _module_uart + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_update_mgr + + .align 2 +3: + + .global UM_Init + .thumb_func +UM_Init: + mov r12, pc + b 1b + + .global UM_Open + .thumb_func +UM_Open: + mov r12, pc + b 1b + + .global UM_Commit + .thumb_func +UM_Commit: + mov r12, pc + b 1b + + .global UM_Close + .thumb_func +UM_Close: + mov r12, pc + b 1b + + .global UM_CheckPoint + .thumb_func +UM_CheckPoint: + mov r12, pc + b 1b + + .global UM_DoUpdateSequence + .thumb_func +UM_DoUpdateSequence: + mov r12, pc + b 1b + + .global UM_Abort + .thumb_func +UM_Abort: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_update_mgr +_modulelist_update_mgr: + .weak _module_update_mgr + .word _module_update_mgr + .word 0 + .word 0 + .word 0 + + .syntax unified + .section .text.stub + .align 1 +1: + push {r0-r3} + adr r1, 3f + mov r0, r12 + subs r0, r0, r1 + mov r1, sp + ldr r2, 2f + push {r4, lr} + bl farapi_main + pop {r0, r1} + mov r12, r1 + pop {r0-r3} + bx r12 + + .align 2 +2: + .word _modulelist_gnss + + .align 2 +3: + + .global GD_Start + .thumb_func +GD_Start: + mov r12, pc + b 1b + + .global GD_Stop + .thumb_func +GD_Stop: + mov r12, pc + b 1b + + .global GD_SelectSatelliteSystem + .thumb_func +GD_SelectSatelliteSystem: + mov r12, pc + b 1b + + .global GD_GetSatelliteSystem + .thumb_func +GD_GetSatelliteSystem: + mov r12, pc + b 1b + + .global GD_SetReceiverPositionEllipsoidal + .thumb_func +GD_SetReceiverPositionEllipsoidal: + mov r12, pc + b 1b + + .global GD_SetReceiverPositionOrthogonal + .thumb_func +GD_SetReceiverPositionOrthogonal: + mov r12, pc + b 1b + + .global GD_SetOperationMode + .thumb_func +GD_SetOperationMode: + mov r12, pc + b 1b + + .global GD_GetOperationMode + .thumb_func +GD_GetOperationMode: + mov r12, pc + b 1b + + .global GD_SetTcxoOffset + .thumb_func +GD_SetTcxoOffset: + mov r12, pc + b 1b + + .global GD_GetTcxoOffset + .thumb_func +GD_GetTcxoOffset: + mov r12, pc + b 1b + + .global GD_SetTime + .thumb_func +GD_SetTime: + mov r12, pc + b 1b + + .global GD_GetAlmanac + .thumb_func +GD_GetAlmanac: + mov r12, pc + b 1b + + .global GD_SetAlmanac + .thumb_func +GD_SetAlmanac: + mov r12, pc + b 1b + + .global GD_GetEphemeris + .thumb_func +GD_GetEphemeris: + mov r12, pc + b 1b + + .global GD_SetEphemeris + .thumb_func +GD_SetEphemeris: + mov r12, pc + b 1b + + .global GD_GetVarEphemeris + .thumb_func +GD_GetVarEphemeris: + mov r12, pc + b 1b + + .global GD_SetVarEphemeris + .thumb_func +GD_SetVarEphemeris: + mov r12, pc + b 1b + + .global GD_StartGpsTest + .thumb_func +GD_StartGpsTest: + mov r12, pc + b 1b + + .global GD_StopGpsTest + .thumb_func +GD_StopGpsTest: + mov r12, pc + b 1b + + .global GD_GetGpsTestResult + .thumb_func +GD_GetGpsTestResult: + mov r12, pc + b 1b + + .global GD_SaveBackupdata + .thumb_func +GD_SaveBackupdata: + mov r12, pc + b 1b + + .global GD_EraseBackup + .thumb_func +GD_EraseBackup: + mov r12, pc + b 1b + + .global GD_CepSetAssistData + .thumb_func +GD_CepSetAssistData: + mov r12, pc + b 1b + + .global GD_CepEraseAssistData + .thumb_func +GD_CepEraseAssistData: + mov r12, pc + b 1b + + .global GD_CepCheckAssistData + .thumb_func +GD_CepCheckAssistData: + mov r12, pc + b 1b + + .global GD_CepGetAgeData + .thumb_func +GD_CepGetAgeData: + mov r12, pc + b 1b + + .global GD_CepInitAssistData + .thumb_func +GD_CepInitAssistData: + mov r12, pc + b 1b + + .global GD_SetAcquist + .thumb_func +GD_SetAcquist: + mov r12, pc + b 1b + + .global GD_SetFrameTime + .thumb_func +GD_SetFrameTime: + mov r12, pc + b 1b + + .global GD_SetTauGps + .thumb_func +GD_SetTauGps: + mov r12, pc + b 1b + + .global GD_SetTimeGps + .thumb_func +GD_SetTimeGps: + mov r12, pc + b 1b + + .global GD_ClearReceiverInfo + .thumb_func +GD_ClearReceiverInfo: + mov r12, pc + b 1b + + .global GD_SetTowAssist + .thumb_func +GD_SetTowAssist: + mov r12, pc + b 1b + + .global GD_SetUtcModel + .thumb_func +GD_SetUtcModel: + mov r12, pc + b 1b + + .global GD_SpectrumControl + .thumb_func +GD_SpectrumControl: + mov r12, pc + b 1b + + .global GD_ReadBuffer + .thumb_func +GD_ReadBuffer: + mov r12, pc + b 1b + + .global GD_WriteBuffer + .thumb_func +GD_WriteBuffer: + mov r12, pc + b 1b + + .global GD_SetNotifyMask + .thumb_func +GD_SetNotifyMask: + mov r12, pc + b 1b + + .global GD_GeoAddRegion + .thumb_func +GD_GeoAddRegion: + mov r12, pc + b 1b + + .global GD_GeoModifyRegion + .thumb_func +GD_GeoModifyRegion: + mov r12, pc + b 1b + + .global GD_GeoDeleteRegione + .thumb_func +GD_GeoDeleteRegione: + mov r12, pc + b 1b + + .global GD_GeoDeleteAllRegion + .thumb_func +GD_GeoDeleteAllRegion: + mov r12, pc + b 1b + + .global GD_GeoGetRegionData + .thumb_func +GD_GeoGetRegionData: + mov r12, pc + b 1b + + .global GD_GeoGetUsedRegionId + .thumb_func +GD_GeoGetUsedRegionId: + mov r12, pc + b 1b + + .global GD_GeoSetOpMode + .thumb_func +GD_GeoSetOpMode: + mov r12, pc + b 1b + + .global GD_GeoSetAllRgionNotifyRequest + .thumb_func +GD_GeoSetAllRgionNotifyRequest: + mov r12, pc + b 1b + + .global GD_RegisterGeofence + .thumb_func +GD_RegisterGeofence: + mov r12, pc + b 1b + + .global GD_ReleaseGeofence + .thumb_func +GD_ReleaseGeofence: + mov r12, pc + b 1b + + .global GD_RegisterPvtlog + .thumb_func +GD_RegisterPvtlog: + mov r12, pc + b 1b + + .global GD_ReleasePvtlog + .thumb_func +GD_ReleasePvtlog: + mov r12, pc + b 1b + + .global GD_PvtlogDeleteLog + .thumb_func +GD_PvtlogDeleteLog: + mov r12, pc + b 1b + + .global GD_PvtlogGetLogStatus + .thumb_func +GD_PvtlogGetLogStatus: + mov r12, pc + b 1b + + .global GD_RtkStart + .thumb_func +GD_RtkStart: + mov r12, pc + b 1b + + .global GD_RtkStop + .thumb_func +GD_RtkStop: + mov r12, pc + b 1b + + .global GD_RtkSetOutputInterval + .thumb_func +GD_RtkSetOutputInterval: + mov r12, pc + b 1b + + .global GD_RtkGetOutputInterval + .thumb_func +GD_RtkGetOutputInterval: + mov r12, pc + b 1b + + .global GD_RtkSetGnss + .thumb_func +GD_RtkSetGnss: + mov r12, pc + b 1b + + .global GD_RtkGetGnss + .thumb_func +GD_RtkGetGnss: + mov r12, pc + b 1b + + .global GD_RtkSetEphNotify + .thumb_func +GD_RtkSetEphNotify: + mov r12, pc + b 1b + + .global GD_RtkGetEphNotify + .thumb_func +GD_RtkGetEphNotify: + mov r12, pc + b 1b + + .section .modulelist, "ax" + .align 2 + .global _modulelist_gnss +_modulelist_gnss: + .weak _module_gnss + .word _module_gnss + .word 1 + .word 0 + .word 0 + + .section .modulelist, "ax" + .align 2 + .global _modulelist_gnss_geofence +_modulelist_gnss_geofence: + .weak _module_gnss_geofence + .word _module_gnss_geofence + .word 1 + .word 0 + .word 0 + + .section .modulelist, "ax" + .align 2 + .global _modulelist_gnss_pvtlog +_modulelist_gnss_pvtlog: + .weak _module_gnss_pvtlog + .word _module_gnss_pvtlog + .word 1 + .word 0 + .word 0 diff --git a/arch/arm/src/cxd56xx/cxd56_farapistub.h b/arch/arm/src/cxd56xx/cxd56_farapistub.h new file mode 100644 index 00000000000..a8af513e2d5 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_farapistub.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_farapistub.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_FARAPISTUB_H +#define __ARCH_ARM_SRC_CXD56XX_CXD56_FARAPISTUB_H + +#define FARAPISTUB_VERSION 17639 + +#endif diff --git a/arch/arm/src/cxd56xx/cxd56_powermgr.c b/arch/arm/src/cxd56xx/cxd56_powermgr.c new file mode 100644 index 00000000000..dace6660490 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_powermgr.c @@ -0,0 +1,1011 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_powermgr.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "up_internal.h" +#include "up_arch.h" +#include "cxd56_powermgr.h" +#include "cxd56_icc.h" +#include "cxd56_pmic.h" +#include "chip.h" +#include "hardware/cxd5602_backupmem.h" + +#define INTC_REG_INV(n) (CXD56_INTC_BASE + 0x20 + ((n) << 2)) +#define INTC_REG_EN(n) (CXD56_INTC_BASE + 0x10 + ((n) << 2)) + +/* bootmask control */ + +#define NON_MASKABLE_BOOTMASK (PM_BOOT_POR_NORMAL | \ + PM_BOOT_POR_DEADBATT | \ + PM_BOOT_WDT_REBOOT | \ + PM_BOOT_WDT_RESET | \ + PM_BOOT_DEEP_USB_ATTACH | \ + PM_BOOT_DEEP_OTHERS) +#define DEEP_PROHIBIT_BOOTMASK (PM_BOOT_DEEP_WKUPS | \ + PM_BOOT_DEEP_RTC) +#define CONFIG_INT_WKUP_REG (0x38) +#define WKUPL_ENABLE (0x2) +#define WKUPL_DISABLE (0x0) + +#define MSGID_BOOT 0 +#define MSGID_FREQLOCK 1 +#define MSGID_CLK_CHG_START 2 +#define MSGID_CLK_CHG_END 3 +#define MSGID_GET_CLK 4 +#define MSGID_HOT_SLEEP 5 +#define MSGID_RESUME 6 + +#define MQMSG_CLK_CHG_START 0 +#define MQMSG_CLK_CHG_END 1 +#define MQMSG_HOT_SLEEP 2 + +#define CXD56_PM_SYS_CPU (0) +#define CXD56_PM_SYS_APP (2) + +#define PM_CPUFREQLOCK_FLAG_INITIALIZED (0x8000) + +#ifdef CONFIG_CXD56_PM_DEBUG +# define pmerr(format, ...) _err(format, ##__VA_ARGS__) +# define pmwarn(format, ...) _warn(format, ##__VA_ARGS__) +# define pminfo(format, ...) _info(format, ##__VA_ARGS__) +#else +# define pmerr(x...) +# define pmwarn(x...) +# define pminfo(x...) +#endif + +void up_cpuctxload(void); +int cxd56_cpu_context_sleep(void); + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct cxd56_pm_target_id_s +{ + uint32_t sysiop; + uint32_t app; + uint32_t pmu; + uint32_t hostif; + uint32_t scu; + uint32_t gps; +}; + +struct cxd56_pm_hotsleep_info_s +{ + int cpu_id; + uint32_t entry; + uint64_t requested_sleeptime; + uint64_t sleep_starttime; + uint64_t wakeuptime; +}; + +struct cxd56_pm_message_s +{ + uint8_t mid; + uint32_t data; +}; + +struct pm_cbentry_s +{ + struct dq_entry_s dq_entry; + uint32_t target; + cxd56_pm_callback callback; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int cxd56_pm_do_callback(uint8_t id, + FAR struct cxd56_pm_target_id_s *table); +static int cxd56_pm_needcallback(uint32_t target, + FAR struct cxd56_pm_target_id_s *table); +static void cxd56_pm_clkchange(struct cxd56_pm_message_s *message); +static int cxd56_pm_semtake(FAR sem_t *id); +static void cxd56_pm_checkfreqlock(void); +static int cxd56_pm_maintask(int argc, FAR char *argv[]); +#if defined(CONFIG_CXD56_HOT_SLEEP) +static void cxd56_pm_do_hotsleep(uint32_t idletime); +static void cxd56_pm_intc_suspend(void); +static void cxd56_pm_intc_resume(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct cxd56_pm_target_id_s g_target_id_table; +static mqd_t g_queuedesc; +static sem_t g_regcblock; +static sem_t g_freqlock; +static sem_t g_freqlockwait; +static dq_queue_t g_cbqueue; +static sq_queue_t g_freqlockqueue; +static sq_queue_t g_wakelockqueue; +static uint32_t g_clockcange_start; +static int g_freqlock_flag; + +static struct pm_cpu_wakelock_s g_wlock = + PM_CPUWAKELOCK_INIT(PM_CPUWAKELOCK_TAG('P', 'M', 0)); + +static int cxd56_pm_semtake(FAR sem_t *id) +{ + while (sem_wait(id) != 0) + { + if (errno != EINTR) + { + pmerr("ERR:sem_wait\n"); + return errno; + } + } + return OK; +} + +static int cxd56_pm_needcallback(uint32_t target, + FAR struct cxd56_pm_target_id_s *table) +{ + uint32_t mask; + + switch (target & PM_DOMAIN_MASK) + { + case PM_DOMAIN_SYSIOP: + mask = table->sysiop; + break; + case PM_DOMAIN_HOSTIF: + mask = table->hostif; + break; + case PM_DOMAIN_PMU: + mask = table->pmu; + break; + case PM_DOMAIN_SCU: + mask = table->scu; + break; + case PM_DOMAIN_APP: + mask = table->app; + break; + case PM_DOMAIN_GPS: + mask = table->gps; + break; + default: + return 0; + } + + return mask & target; +} + +static int cxd56_pmsendmsg(int mid, uint32_t data) +{ + iccmsg_t msg; + + msg.cpuid = 0; + msg.msgid = 0; /* Power manger message does not used this field. */ + msg.protodata = mid; + msg.data = data; + return cxd56_iccsend(CXD56_PROTO_PM, &msg, 0); +} + +static int cxd56_pm_do_callback(uint8_t id, + struct cxd56_pm_target_id_s *targets) +{ + FAR struct pm_cbentry_s *entry; + FAR dq_entry_t *cur; + FAR dq_entry_t *last; + int ret = 0; + + for (cur = dq_peek(&g_cbqueue); cur; cur = dq_next(cur)) + { + entry = (FAR struct pm_cbentry_s *)cur; + last = cur; + if (cxd56_pm_needcallback(entry->target, targets)) + { + ret = entry->callback(id); + if (ret != 0) + { + break; + } + } + } + + /* If one of the callbacks has been failed, then recovery call to previously + * called entries. + */ + + if (ret != 0) + { + /* Replace callback ID to recovery */ + + if (id == CXD56_PM_CALLBACK_ID_CLK_CHG_START) + { + id = CXD56_PM_CALLBACK_ID_CLK_CHG_END; + } + if (id == CXD56_PM_CALLBACK_ID_HOT_SLEEP) + { + id = CXD56_PM_CALLBACK_ID_HOT_BOOT; + } + + for (cur = dq_peek(&g_cbqueue); cur != last; cur = dq_next(cur)) + { + entry = (FAR struct pm_cbentry_s *)cur; + if (cxd56_pm_needcallback(entry->target, targets)) + { + entry->callback(id); + } + } + } + + return ret; +} + +static void cxd56_pm_clkchange(struct cxd56_pm_message_s *message) +{ + uint8_t id; + int mid; + int ret; + + switch (message->mid) + { + case MQMSG_CLK_CHG_START: + id = CXD56_PM_CALLBACK_ID_CLK_CHG_START; + mid = MSGID_CLK_CHG_START; + g_clockcange_start = 1; + break; + case MQMSG_CLK_CHG_END: + if (g_clockcange_start == 0) + { + return; + } + id = CXD56_PM_CALLBACK_ID_CLK_CHG_END; + mid = MSGID_CLK_CHG_END; + g_clockcange_start = 0; + break; + default: + return; + } + + cxd56_pm_semtake(&g_regcblock); + + ret = cxd56_pm_do_callback(id, &g_target_id_table); + + cxd56_pmsendmsg(mid, ret); + + sem_post(&g_regcblock); +} + +static void cxd56_pm_checkfreqlock(void) +{ + FAR sq_entry_t *entry; + FAR struct pm_cpu_freqlock_s *lock; + int flag = PM_CPUFREQLOCK_FLAG_INITIALIZED; + + for (entry = sq_peek(&g_freqlockqueue); entry; entry = sq_next(entry)) + { + lock = (FAR struct pm_cpu_freqlock_s *)entry; + flag |= lock->flag & PM_CPUFREQLOCK_FLAG_LV; + flag |= lock->flag & PM_CPUFREQLOCK_FLAG_HV; + } + + if (g_freqlock_flag != flag) + { + g_freqlock_flag = flag; + cxd56_pmsendmsg(MSGID_FREQLOCK, flag); + cxd56_pm_semtake(&g_freqlockwait); + } +} + +#if defined(CONFIG_CXD56_HOT_SLEEP) +static void cxd56_pm_intc_suspend(void) +{ + int i; + + for (i = 0; i < 4; i++) + { + BKUP->irq_inv_map[i] = getreg32(INTC_REG_INV(i)); + BKUP->irq_wake_map[i] = getreg32(INTC_REG_EN(i)); + putreg32(0, INTC_REG_INV(i)); + putreg32(0, INTC_REG_EN(i)); + } +} + +static void cxd56_pm_intc_resume(void) +{ + int i; + + for (i = 0; i < 4; i++) + { + putreg32(BKUP->irq_inv_map[i], INTC_REG_INV(i)); + putreg32(BKUP->irq_wake_map[i], INTC_REG_EN(i)); + } +} + +static void cxd56_pm_do_hotsleep(uint32_t idletime) +{ + irqstate_t flags; + uint64_t time; + uint32_t tick; + struct cxd56_pm_hotsleep_info_s info; + struct cxd56_pm_target_id_s table; + iccmsg_t msg; + int ret; + + if (up_pm_count_acquire_wakelock() != 0) + { + return; + } + + table.sysiop = PM_DOMAIN_SYSIOP | ~PM_DOMAIN_MASK; + table.app = PM_DOMAIN_APP | ~PM_DOMAIN_MASK; + table.pmu = PM_DOMAIN_PMU | ~PM_DOMAIN_MASK; + table.hostif = PM_DOMAIN_HOSTIF | ~PM_DOMAIN_MASK; + table.scu = PM_DOMAIN_SCU | ~PM_DOMAIN_MASK; + table.gps = PM_DOMAIN_GPS | ~PM_DOMAIN_MASK; + + ret = cxd56_pm_do_callback(CXD56_PM_CALLBACK_ID_HOT_SLEEP, &table); + if (ret != 0) + { + return; + } + + flags = enter_critical_section(); + + info.cpu_id = CXD56_PM_SYS_APP; + info.entry = (uint32_t)up_cpuctxload | 0x1; + info.requested_sleeptime = idletime; + info.sleep_starttime = 0; + info.wakeuptime = 0; + + cxd56_pmsendmsg(MSGID_HOT_SLEEP, (uint32_t)(uintptr_t)&info); + + cxd56_pm_intc_suspend(); + cxd56_cpu_context_sleep(); + + leave_critical_section(flags); + + if (info.sleep_starttime != 0) + { + time = info.wakeuptime - info.sleep_starttime; + tick = (time * USEC_PER_MSEC) / CONFIG_USEC_PER_TICK; + sched_process_timer_skip(tick); + } + + cxd56_pm_do_callback(CXD56_PM_CALLBACK_ID_HOT_BOOT, &table); + + cxd56_pm_intc_resume(); + + cxd56_pmsendmsg(MSGID_RESUME, 0); +} +#endif + +static int cxd56_pm_maintask(int argc, FAR char *argv[]) +{ + int size; + struct cxd56_pm_message_s message; + + while (1) + { + size = mq_receive(g_queuedesc, (FAR char *)&message, sizeof(message), + NULL); + if (size == sizeof(message)) + { + switch (message.mid) + { + case MQMSG_CLK_CHG_START: + case MQMSG_CLK_CHG_END: + cxd56_pm_clkchange(&message); + break; + case MQMSG_HOT_SLEEP: +#if defined(CONFIG_CXD56_HOT_SLEEP) + cxd56_pm_do_hotsleep(message.data); +#endif + break; + default: + break; + } + } + } + + return EXIT_SUCCESS; +} + +FAR void *cxd56_pm_register_callback(uint32_t target, + cxd56_pm_callback callback) +{ + struct pm_cbentry_s *entry = NULL; + + cxd56_pm_semtake(&g_regcblock); + + entry = (struct pm_cbentry_s *)kmm_malloc(sizeof(struct pm_cbentry_s)); + if (entry == NULL) + { + sem_post(&g_regcblock); + return NULL; + } + + entry->target = target; + entry->callback = callback; + + dq_addlast((FAR dq_entry_t *)entry, &g_cbqueue); + sem_post(&g_regcblock); + + return (void *)entry; +} + +void cxd56_pm_unregister_callback(FAR void *handle) +{ + cxd56_pm_semtake(&g_regcblock); + + dq_rem((FAR dq_entry_t *)handle, &g_cbqueue); + kmm_free(handle); + + sem_post(&g_regcblock); +} + +static int cxd56_pmmsghandler(int cpuid, int protoid, uint32_t pdata, + uint32_t data, FAR void *userdata) +{ + uint32_t msgid; + struct cxd56_pm_message_s message; + int ret; + + msgid = pdata; + + if (msgid == MSGID_CLK_CHG_START) + { + message.mid = MQMSG_CLK_CHG_START; + ret = mq_send(g_queuedesc, (FAR const char *)&message, sizeof(message), + CXD56_PM_MESSAGE_PRIO); + if (ret < 0) + { + pmerr("ERR:mq_send(CLK_CHG_START)\n"); + } + } + else if (msgid == MSGID_CLK_CHG_END) + { + message.mid = MQMSG_CLK_CHG_END; + ret = mq_send(g_queuedesc, (FAR const char *)&message, sizeof(message), + CXD56_PM_MESSAGE_PRIO); + if (ret < 0) + { + pmerr("ERR:mq_send(CLK_CHG_END)\n"); + } + } + else if (msgid == MSGID_FREQLOCK) + { + sem_post(&g_freqlockwait); + } + else + { + pmerr("Unknown message %d\n", msgid); + } + + return 0; +} + +int cxd56_pm_bootup(void) +{ + /* BOOT indicate to M0P */ + + cxd56_pmsendmsg(MSGID_BOOT, (uint32_t)(uintptr_t)&g_target_id_table); + return OK; +} + +/**************************************************************************** + * Name: up_pm_acquire_freqlock + * + * Description: + * Acquire the specified freqlock. If the higher freqlock is acquired, the + * system can clockup until it is released. + * + * Parameter: + * lock - the pointer of a wakelock variable + * + ****************************************************************************/ + +void up_pm_acquire_freqlock(struct pm_cpu_freqlock_s *lock) +{ + FAR sq_entry_t *entry; + + DEBUGASSERT(lock); + + up_pm_acquire_wakelock(&g_wlock); + + cxd56_pm_semtake(&g_freqlock); + + for (entry = sq_peek(&g_freqlockqueue); entry; entry = sq_next(entry)) + { + if (entry == (struct sq_entry_s *)lock) + { + break; + } + } + + if (!entry) + { + sq_addlast((FAR sq_entry_t *)lock, &g_freqlockqueue); + cxd56_pm_checkfreqlock(); + } + + lock->count++; + + sem_post(&g_freqlock); + + up_pm_release_wakelock(&g_wlock); +} + +/**************************************************************************** + * Name: up_pm_release_freqlock + * + * Description: + * Release the specified freqlock. If the freqlock are released, the system + * can drop to the lower clock mode for power saving. + * + * Parameter: + * lock - the pointer of a freqlock variable + * + ****************************************************************************/ + +void up_pm_release_freqlock(struct pm_cpu_freqlock_s *lock) +{ + FAR sq_entry_t *entry; + + DEBUGASSERT(lock); + + up_pm_acquire_wakelock(&g_wlock); + + cxd56_pm_semtake(&g_freqlock); + + for (entry = sq_peek(&g_freqlockqueue); entry; entry = sq_next(entry)) + { + if (entry == (struct sq_entry_s *)lock) + { + lock->count--; + if (lock->count <= 0) + { + sq_rem(entry, &g_freqlockqueue); + cxd56_pm_checkfreqlock(); + } + break; + } + } + + sem_post(&g_freqlock); + + up_pm_release_wakelock(&g_wlock); +} + +/**************************************************************************** + * Name: up_pm_get_freqlock_count + * + * Description: + * Get the locked count of the specified freqlock + * + * Parameter: + * lock - the pointer of a freqlock variable + * + * Return: + * the locked count of the specified freqlock + * + ****************************************************************************/ + +int up_pm_get_freqlock_count(struct pm_cpu_freqlock_s *lock) +{ + FAR sq_entry_t *entry; + int count = 0; + + DEBUGASSERT(lock); + + cxd56_pm_semtake(&g_freqlock); + + for (entry = sq_peek(&g_freqlockqueue); entry; entry = sq_next(entry)) + { + if (entry == (struct sq_entry_s *)lock) + { + count = lock->count; + break; + } + } + + sem_post(&g_freqlock); + return count; +} + +/**************************************************************************** + * Name: up_pm_acquire_wakelock + * + * Description: + * Acquire the specified wakelock. If any wakelock is acquired, CPU can't + * enter to the hot sleep state. + * + * Parameter: + * lock - the pointer of a wakelock variable + * + ****************************************************************************/ + +void up_pm_acquire_wakelock(struct pm_cpu_wakelock_s *lock) +{ + irqstate_t flags; + FAR sq_entry_t *entry; + + DEBUGASSERT(lock); + + flags = enter_critical_section(); + + for (entry = sq_peek(&g_wakelockqueue); entry; entry = sq_next(entry)) + { + if (entry == (struct sq_entry_s *)lock) + { + break; + } + } + + if (!entry) + { + sq_addlast((FAR sq_entry_t *)lock, &g_wakelockqueue); + } + + lock->count++; + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_pm_release_wakelock + * + * Description: + * Release the specified wakelock. If all of the wakelock are released, + * CPU can enter to the hot sleep state. + * + * Parameter: + * lock - the pointer of a wakelock variable + * + ****************************************************************************/ + +void up_pm_release_wakelock(struct pm_cpu_wakelock_s *lock) +{ + irqstate_t flags; + FAR sq_entry_t *entry; + + DEBUGASSERT(lock); + + flags = enter_critical_section(); + + for (entry = sq_peek(&g_wakelockqueue); entry; entry = sq_next(entry)) + { + if (entry == (struct sq_entry_s *)lock) + { + lock->count--; + if (lock->count <= 0) + { + sq_rem(entry, &g_wakelockqueue); + } + break; + } + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_pm_count_acquire_wakelock + * + * Description: + * Count the total number of wakelock + * + * Return: + * the total number of wakelock + * + ****************************************************************************/ + +int up_pm_count_acquire_wakelock(void) +{ + irqstate_t flags; + int num; + + flags = enter_critical_section(); + + num = sq_count(&g_wakelockqueue); + + leave_critical_section(flags); + + return num; +} + +int cxd56_pm_hotsleep(int idletime) +{ + struct cxd56_pm_message_s message; + int ret; + + if (up_pm_count_acquire_wakelock() != 0) + { + return -1; + } + + message.mid = MQMSG_HOT_SLEEP; + message.data = (uint32_t)idletime; + ret = mq_send(g_queuedesc, (FAR const char *)&message, sizeof(message), + CXD56_PM_MESSAGE_PRIO); + if (ret < 0) + { + pmerr("ERR:mq_send(HOT_SLEEP)\n"); + return -1; + } + + return 0; +} + +int cxd56_pm_initialize(void) +{ + struct mq_attr attr; + int taskid; + int ret; + + cxd56_iccinit(CXD56_PROTO_PM); + + /* Register power manager messaging protocol handler. */ + + cxd56_iccregisterhandler(CXD56_PROTO_PM, cxd56_pmmsghandler, NULL); + + dq_init(&g_cbqueue); + sq_init(&g_freqlockqueue); + sq_init(&g_wakelockqueue); + + ret = sem_init(&g_regcblock, 0, 1); + if (ret < 0) + { + return -EPERM; + } + + ret = sem_init(&g_freqlock, 0, 1); + if (ret < 0) + { + return -EPERM; + } + + ret = sem_init(&g_freqlockwait, 0, 0); + if (ret < 0) + { + return -EPERM; + } + + attr.mq_maxmsg = 8; + attr.mq_msgsize = sizeof(struct cxd56_pm_message_s); + attr.mq_curmsgs = 0; + attr.mq_flags = 0; + g_queuedesc = mq_open("cxd56_pm_message", O_RDWR | O_CREAT, 0666, &attr); + if (g_queuedesc < 0) + { + return -EPERM; + } + + taskid = task_create("cxd56_pm_task", CXD56_PM_TASK_PRIO, + CXD56_PM_TASK_STACKSIZE, cxd56_pm_maintask, + (FAR char * const *)NULL); + if (taskid < 0) + { + return -EPERM; + } + + return OK; +} + +/**************************************************************************** + * Name: up_pm_get_bootcause + * + * Description: + * Get the system boot cause. This boot cause indicates the cause why the + * system is launched from the state of power-off, deep sleep or cold sleep. + * Each boot cause is defined as PM_BOOT_XXX. + * + * Return: + * Boot cause + * + ****************************************************************************/ + +uint32_t up_pm_get_bootcause(void) +{ + return BKUP->bootcause; +} + +/**************************************************************************** + * Name: up_pm_get_bootmask + * + * Description: + * Get the system boot mask. This boot mask indicates whether the specified + * bit is enabled or not as the boot cause. If a bit of boot mask is set, + * the boot cause is enabled. Each boot mask is defined as PM_BOOT_XXX. + * + * Return: + * Boot mask + * + ****************************************************************************/ + +uint32_t up_pm_get_bootmask(void) +{ + return BKUP->bootmask; +} + +/**************************************************************************** + * Name: up_pm_set_bootmask + * + * Description: + * Enable the boot cause of the specified bit. + * + * Parameter: + * mask - OR of Boot mask definied as PM_BOOT_XXX + * + * Return: + * Updated boot mask + * + ****************************************************************************/ + +uint32_t up_pm_set_bootmask(uint32_t mask) +{ + irqstate_t flags; + + /* Enable emergency recovery by WKUPL + * only when bootmask is changed from disable to enable + */ + +#ifdef CONFIG_CXD56_PMIC + if (!(BKUP->bootmask & PM_BOOT_DEEP_WKUPL) && (mask & PM_BOOT_DEEP_WKUPL)) + { + uint8_t value = WKUPL_ENABLE; + cxd56_pmic_write(CONFIG_INT_WKUP_REG, &value, sizeof(value)); + } +#endif + + flags = enter_critical_section(); + + BKUP->bootmask |= mask; + + leave_critical_section(flags); + + return BKUP->bootmask; +} + +/**************************************************************************** + * Name: up_pm_clr_bootmask + * + * Description: + * Disable the boot cause of the specified bit. + * + * Parameter: + * mask - OR of Boot mask definied as PM_BOOT_XXX + * + * Return: + * Updated boot mask + * + ****************************************************************************/ + +uint32_t up_pm_clr_bootmask(uint32_t mask) +{ + irqstate_t flags; + + /* Disable emergency recovery by WKUPL, + * only when bootmask is changed from enable to disable + */ + +#ifdef CONFIG_CXD56_PMIC + if ((BKUP->bootmask & PM_BOOT_DEEP_WKUPL) && (mask & PM_BOOT_DEEP_WKUPL)) + { + uint8_t value = WKUPL_DISABLE; + cxd56_pmic_write(CONFIG_INT_WKUP_REG, &value, sizeof(value)); + } +#endif + + flags = enter_critical_section(); + + /* Check if non-maskable bit */ + + if (mask & NON_MASKABLE_BOOTMASK) + { + pmwarn("Can't be disabled 0x%08x\n", (mask & NON_MASKABLE_BOOTMASK)); + mask &= ~NON_MASKABLE_BOOTMASK; + } + + /* Make it impossible to be disable both WKUPS and RTC in DEEP */ + + if (((BKUP->bootmask & ~mask) & DEEP_PROHIBIT_BOOTMASK) == 0) + { + pmwarn("Can't be disabled both 0x%08x and 0x%08x\n", + PM_BOOT_DEEP_WKUPS, PM_BOOT_DEEP_RTC); + mask &= ~DEEP_PROHIBIT_BOOTMASK; + } + + BKUP->bootmask &= ~mask; + + leave_critical_section(flags); + + return BKUP->bootmask; +} + +/**************************************************************************** + * Name: up_pm_sleep + * + * Description: + * Enter sleep mode. This function never returns. + * + * Parameter: + * mode - PM_SLEEP_DEEP or PM_SLEEP_COLD + * + ****************************************************************************/ + +int up_pm_sleep(enum pm_sleepmode_e mode) +{ + int PM_DeepSleep(void *); + int PM_ColdSleep(void *); + + switch (mode) + { + case PM_SLEEP_DEEP: + PM_DeepSleep(NULL); + break; + case PM_SLEEP_COLD: + PM_ColdSleep(NULL); + break; + } + __asm volatile ("dsb"); + for (; ; ); +} + +/**************************************************************************** + * Name: up_pm_reboot + * + * Description: + * System reboot. This function never returns. + * + ****************************************************************************/ + +int up_pm_reboot(void) +{ + void PM_Reboot(void); + PM_Reboot(); + __asm volatile ("dsb"); + for (; ; ); +} diff --git a/arch/arm/src/cxd56xx/cxd56_powermgr.h b/arch/arm/src/cxd56xx/cxd56_powermgr.h new file mode 100644 index 00000000000..d62ccca5492 --- /dev/null +++ b/arch/arm/src/cxd56xx/cxd56_powermgr.h @@ -0,0 +1,350 @@ +/**************************************************************************** + * arch/arm/src/cxd56xx/cxd56_powermgr.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_CXD56XX_POWERMGR_H +#define __ARCH_ARM_SRC_CXD56XX_POWERMGR_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CXD56_PM_SET_CPUID(wrd0, cpuid) ((((cpuid) & 0xF) << 28) |\ + ((wrd0) & 0x0FFFFFFF)) +#define CXD56_PM_SET_PROTO(msg, proto) ((((proto) & 0xF) << 24) |\ + ((msg) & 0xF0FFFFFF)) + +#define CXD56_PM_FIFO_PROTO_PM (10) + +#define CXD56_PM_FIFO_MSG_ID_BOOT_INDE (0) +#define CXD56_PM_FIFO_MSG_ID_FREQLOCK (1) +#define CXD56_PM_FIFO_MSG_ID_CLK_CHG_START (2) +#define CXD56_PM_FIFO_MSG_ID_CLK_CHG_END (3) +#define CXD56_PM_FIFO_MSG_ID_GET_CLK (4) +#define CXD56_PM_FIFO_MSG_ID_HOT_SLEEP (5) +#define CXD56_PM_FIFO_MSG_ID_RESUME (6) + +#define CXD56_PM_SYS_CPU (0) +#define CXD56_PM_SYS_APP (2) + +#define CXD56_PM_TASK_PRIO (200) +#define CXD56_PM_TASK_STACKSIZE (1024) +#define CXD56_PM_MESSAGE_PRIO (1) + +#define CXD56_PM_INTERNAL_MGS_CLK_CHG_START (0) +#define CXD56_PM_INTERNAL_MGS_CLK_CHG_END (1) +#define CXD56_PM_INTERNAL_MGS_HOT_SLEEP (2) + +#define CXD56_PM_CALLBACK_ID_CLK_CHG_START (0) +#define CXD56_PM_CALLBACK_ID_CLK_CHG_END (1) +#define CXD56_PM_CALLBACK_ID_HOT_SLEEP (2) +#define CXD56_PM_CALLBACK_ID_HOT_BOOT (3) + +#define PM_CPUFREQLOCK_FLAG_INITIALIZED (0x8000) + +/* Data corresponding to a clock tree */ + +/* Power DOMAIN */ + +#define PM_DOMAIN_SELF_CPU (0x00000000ul) +#define PM_DOMAIN_SYSIOP (0x20000000ul) +#define PM_DOMAIN_HOSTIF (0x40000000ul) +#define PM_DOMAIN_PMU (0x60000000ul) +#define PM_DOMAIN_SCU (0x80000000ul) +#define PM_DOMAIN_APP (0xA0000000ul) +#define PM_DOMAIN_GPS (0xC0000000ul) +#define PM_DOMAIN_MASK (0xE0000000ul) +#define PM_DOMAIN_PLUS (0x20000000ul) + +/* Clock Tree Bit Data */ + +/* SYSIOP */ + +#define PM_CLOCK_SYS_CTRL_SEL_B (0x00010000ul) /**< 16*/ +#define PM_CLOCK_SYSPLL_DIV_B (0x00008000ul) /**< 15:CKSEL_ROOT.SWCTL_CLK_SEL_RFPLL1 */ +#define PM_CLOCK_SYS_CPU_SEL_B (0x00002000ul) /**< 13:CKSEL_ROOT.SWCTL_CLK_SEL */ +#define PM_CLOCK_SYS_CPU_DIV_B (0x00001000ul) /**< 12:CKDIV_CPU_DSP_BUS.CK_M0 */ +#define PM_CLOCK_SYS_AHB_DIV_B (0x00000800ul) /**< 11:CKDIV_CPU_DSP_BUS.CK_AHB */ +#define PM_CLOCK_SYS_APB_DIV_B (0x00000400ul) /**< 10:CKDIV_CPU_DSP_BUS.CK_APB */ +#define PM_CLOCK_SYS_COMIF_DIV_B (0x00000200ul) /**< 9;CKDIV_COM.CK_COM */ +#define PM_CLOCK_SYS_UART1_SEL_B (0x00000100ul) /**< 8:CKSEL_SYSIOP_SUB.SEL_UART1 */ +#define PM_CLOCK_SYS_SFC_DIV_B (0x00000080ul) /**< 7:CKDIV_CPU_DSP_BUS.SFC_HCLK_LOW */ +#define PM_CLOCK_PMU_RTC_PCLK_SEL_B (0x00000040ul) /**< 6:CKSEL_PMU.SEL_RTC_PCLK */ + +/* HOSTIF */ + +#define PM_CLOCK_HIF_SEL_B (0x00000040ul) /**< CKSEL_SYSIOP.SEL_HOST */ +#define PM_CLOCK_HIF_DIV_B (0x00000020ul) /**< CKDIV_HOSTIFC.CK_HOSTIFC */ +#define PM_CLOCK_HIF_SEL2_B (0x00000004ul) /**< CKSEL_SYSIOP.SEL_HOST2 */ +#define PM_CLOCK_HIF_UART0_SEL_B (0x00000002ul) /**< CKSEL_SYSIOP.SEL_UART0 */ +#define PM_CLOCK_HIF_I2C_SEL_B (0x00000001ul) /**< CKSEL_SYSIOP.SEL_I2CS */ + +/* SCU */ + +#define PM_CLOCK_SCU_XOSC_DIV_B (0x00000010ul) /**< CKSEL_SCU.SEL_SCU_XTAL */ +#define PM_CLOCK_SCU_SEL_B (0x00000004ul) /**< CKSEL_SCU.SEL_SCU */ +#define PM_CLOCK_SCU_32K_SEL_B (0x00000008ul) /**< CKSEL_SCU.SEL_SCU_32K */ +#define PM_CLOCK_SCU_HPADC_SEL_B (0x00000002ul) /**< CKDIV_SCU.SCU_U32KH */ +#define PM_CLOCK_SCU_LPADC_DIV_B (0x00000001ul) /**< CKDIV_SCU.SCU_U32KL */ + +/* APP */ + +#define PM_CLOCK_APP_SYSPLL_DIV_B (0x00004000ul) /**< APP_CKSEL.SWCTL_CLK_SEL_SP */ +#define PM_CLOCK_APP_CPU_SEL_B (0x00000400ul) /**< APP_CKSEL.SWCTL_CLK_SEL */ +#define PM_CLOCK_APP_AUD_MCLK_DIV_B (0x00000200ul) /**< APP_DIV.AU_MCLK */ +#define PM_CLOCK_APP_AUD_MCLK_SEL_B (0x00000100ul) /**< APP_CKSEL.AU_MCLK */ +#define PM_CLOCK_APP_AHB_GEAR_B (0x00000080ul) /**< GEAR_AHB */ +#define PM_CLOCK_APP_UART_GEAR_B (0x00000040ul) /**< GEAR_IMG_UART */ +#define PM_CLOCK_APP_SPI_GEAR_B (0x00000020ul) /**< GEAR_IMG_SPI */ +#define PM_CLOCK_APP_WSPI_GEAR_B (0x00000008ul) /**< GEAR_IMG_WSPI */ +#define PM_CLOCK_APP_SDIO_GEAR_B (0x00000004ul) /**< GEAR_PER_SDIO */ +#define PM_CLOCK_APP_USB_GEAR_B (0x00000002ul) /**< GEAR_PER_USB */ +#define PM_CLOCK_APP_VSYNC_GEAR_B (0x00000001ul) /**< GEAR_M_IMG_VENB/GEAR_N_IMG_VENB */ +#define PM_CLOCK_APP_VSYNC_GEAR_N (0x00020000ul) /**< GEAR_N_IMG_VENB */ + +/* GPS */ + +#define PM_CLOCK_GPS_PLL_SEL_B (0x00004000ul) /**< CKSEL_ROOT.SEL_RF_PLL_0 */ +#define PM_CLOCK_GPS_ACQ_SEL_B (0x00000200ul) /**< CKSEL_GNSS_BB.SEL_ACQ */ +#define PM_CLOCK_GPS_ITP_TRK_SEL_B (0x00000080ul) /**< CKDIV_ITP.ITP_TRK */ +#define PM_CLOCK_GPS_BB_MODE_SEL_B (0x00000400ul) /**< CKSEL_GNSS_BB.GNSS_MODE */ +#define PM_CLOCK_GPS_LOGGER_SEL_B (0x00000040ul) /**< CKSEL_GNSS_BB.SEL_LOG */ +#define PM_CLOCK_GPS_ITB_FFT_SEL_B (0x00000020ul) /**< CKSEL_GNSS_BB.SEL_ITB_FFT */ +#define PM_CLOCK_GPS_BB_SEL_B (0x00000100ul) /**< CKSEL_GNSS_BB.SEL_GNSS_BB */ +#define PM_CLOCK_GPS_PPS_SEL_B (0x00000004ul) /**< CKSEL_GNSS_BB.SEL_PPS */ +#define PM_CLOCK_GPS_CPU_DIV_B (0x00000002ul) /**< GNSS_DIV.CPU */ +#define PM_CLOCK_GPS_AHB_DIV_B (0x00000001ul) /**< GNSS_DIV.AHB */ + +/* PMU */ + +#define PM_CLOCK_PMU_SEL_B (0x00000004ul) /**< CKSEL_ROOT.PMU_SWCTL_CLK_SEL */ +#define PM_CLOCK_PMU_PWCTL_SEL_B (0x00000002ul) /**< CKSEL_ROOT.SWCTL_CLK_SEL_RO_RTC */ +#define PM_CLOCK_PMU_PWCTL_DIV_B (0x00000001ul) /**< CKDIV_PMU.PMUA */ + +#define PM_CLOCK_DOMAIN_MASK ( PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B |\ + PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_CPU_DIV_B |\ + PM_CLOCK_SYS_AHB_DIV_B) + +/* Clock Tree Data */ + +/* Target_id bit field */ + +/* |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00| */ + +/* | Domain | Domain another bit field | */ + +/**************************************************************************** + * Base Define + *****************************************************************************/ + +/* SYSIOP */ + +#define PM_CLOCK_SYS_CTRL_SEL (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B) +#define PM_CLOCK_SYSPLL_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B) +#define PM_CLOCK_SYS_CPU_SEL (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B) +#define PM_CLOCK_SYS_CPU_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_CPU_DIV_B) +#define PM_CLOCK_SYS_AHB_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_CPU_DIV_B | PM_CLOCK_SYS_AHB_DIV_B) +#define PM_CLOCK_SYS_APB_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_CPU_DIV_B | PM_CLOCK_SYS_AHB_DIV_B | PM_CLOCK_SYS_APB_DIV_B) +#define PM_CLOCK_SYS_COMIF_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_COMIF_DIV_B) +#define PM_CLOCK_SYS_UART1_SEL (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_COMIF_DIV_B | PM_CLOCK_SYS_UART1_SEL_B) +#define PM_CLOCK_SYS_SFC_DIV (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_SFC_DIV_B) +#define PM_CLOCK_PMU_RTC_PCLK_SEL (PM_DOMAIN_SYSIOP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_SYS_CPU_DIV_B| PM_CLOCK_SYS_AHB_DIV_B | PM_CLOCK_SYS_APB_DIV_B | PM_CLOCK_PMU_RTC_PCLK_SEL_B) + +/* HOSTIF */ + +#define PM_CLOCK_HIF_SEL (PM_DOMAIN_HOSTIF | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_HIF_SEL_B) +#define PM_CLOCK_HIF_DIV (PM_DOMAIN_HOSTIF | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_HIF_SEL_B | PM_CLOCK_HIF_DIV_B) +#define PM_CLOCK_HIF_SEL2 (PM_DOMAIN_HOSTIF | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_HIF_SEL_B | PM_CLOCK_HIF_DIV_B | PM_CLOCK_SCU_XOSC_DIV_B | PM_CLOCK_HIF_SEL2_B) +#define PM_CLOCK_HIF_UART0_SEL (PM_DOMAIN_HOSTIF | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_HIF_SEL_B | PM_CLOCK_HIF_DIV_B | PM_CLOCK_SCU_XOSC_DIV_B | PM_CLOCK_HIF_SEL2_B | PM_CLOCK_HIF_UART0_SEL_B) +#define PM_CLOCK_HIF_I2C_SEL (PM_DOMAIN_HOSTIF | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_HIF_SEL_B | PM_CLOCK_HIF_DIV_B | PM_CLOCK_SCU_XOSC_DIV_B | PM_CLOCK_HIF_SEL2_B | PM_CLOCK_HIF_I2C_SEL_B) + +/* SCU */ + +#define PM_CLOCK_SCU_XOSC_DIV (PM_DOMAIN_SCU | PM_CLOCK_SCU_XOSC_DIV_B) +#define PM_CLOCK_SCU_SEL (PM_DOMAIN_SCU | PM_CLOCK_SCU_XOSC_DIV_B | PM_CLOCK_SCU_32K_SEL_B | PM_CLOCK_SCU_SEL_B) +#define PM_CLOCK_SCU_32K_SEL (PM_DOMAIN_SCU | PM_CLOCK_SCU_32K_SEL_B) +#define PM_CLOCK_SCU_HPADC_SEL (PM_DOMAIN_SCU | PM_CLOCK_SCU_32K_SEL_B | PM_CLOCK_SCU_HPADC_SEL_B) +#define PM_CLOCK_SCU_LPADC_DIV (PM_DOMAIN_SCU | PM_CLOCK_SCU_32K_SEL_B | PM_CLOCK_SCU_LPADC_DIV_B) + +/* APP */ + +#define PM_CLOCK_APP_SYSPLL_DIV (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_APP_SYSPLL_DIV_B) +#define PM_CLOCK_APP_SEL (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B) +#define PM_CLOCK_APP_AUD_MCLK_DIV (PM_DOMAIN_APP | PM_CLOCK_APP_AUD_MCLK_DIV_B) +#define PM_CLOCK_APP_AUD_MCLK_SEL (PM_DOMAIN_APP | PM_CLOCK_APP_AUD_MCLK_DIV_B | PM_CLOCK_APP_AUD_MCLK_SEL_B) +#define PM_CLOCK_APP_AHB_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_AHB_GEAR_B) +#define PM_CLOCK_APP_UART_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_UART_GEAR_B) +#define PM_CLOCK_APP_SPI_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_SPI_GEAR_B) +#define PM_CLOCK_APP_WSPI_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_WSPI_GEAR_B) +#define PM_CLOCK_APP_SDIO_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_SDIO_GEAR_B) +#define PM_CLOCK_APP_USB_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_USB_GEAR_B) +#define PM_CLOCK_APP_VSYNC_GEAR (PM_DOMAIN_APP | PM_CLOCK_SYS_CTRL_SEL_B |PM_CLOCK_APP_SYSPLL_DIV_B | PM_CLOCK_APP_CPU_SEL_B | PM_CLOCK_APP_VSYNC_GEAR_B) +#define PM_CLOCK_APP_VSYNC_N_GEAR (PM_DOMAIN_APP | PM_CLOCK_APP_VSYNC_GEAR_N) + +/* GPS */ + +#define PM_CLOCK_GPS_PLL_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B) +#define PM_CLOCK_GPS_ACQ_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B | PM_CLOCK_GPS_ACQ_SEL_B) +#define PM_CLOCK_GPS_ITP_TRK_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B | PM_CLOCK_GPS_ACQ_SEL_B | PM_CLOCK_GPS_ITP_TRK_SEL_B) +#define PM_CLOCK_GPS_BB_MODE_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B) +#define PM_CLOCK_GPS_LOGGER_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_LOGGER_SEL_B) +#define PM_CLOCK_GPS_ITB_FFT_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B | PM_CLOCK_GPS_ITB_FFT_SEL_B) +#define PM_CLOCK_GPS_BB_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B | PM_CLOCK_GPS_BB_SEL_B) +#define PM_CLOCK_GPS_PPS_SEL (PM_DOMAIN_GPS | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_GPS_PLL_SEL_B | PM_CLOCK_GPS_BB_MODE_SEL_B | PM_CLOCK_GPS_PPS_SEL_B) +#define PM_CLOCK_GPS_CPU_DIV (PM_DOMAIN_GPS | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_GPS_CPU_DIV_B) +#define PM_CLOCK_GPS_AHB_DIV (PM_DOMAIN_GPS | PM_CLOCK_SYS_CTRL_SEL_B | PM_CLOCK_SYSPLL_DIV_B | PM_CLOCK_SYS_CPU_SEL_B | PM_CLOCK_GPS_CPU_DIV_B | PM_CLOCK_GPS_AHB_DIV_B) + +/* PMU */ + +#define PM_CLOCK_PMU_SEL (PM_DOMAIN_PMU | PM_CLOCK_PMU_SEL_B) +#define PM_CLOCK_PMU_PWCTL_SEL (PM_DOMAIN_PMU | PM_CLOCK_PMU_SEL_B | PM_CLOCK_PMU_PWCTL_SEL_B) +#define PM_CLOCK_PMU_PWCTL_DIV (PM_DOMAIN_PMU | PM_CLOCK_PMU_SEL_B | PM_CLOCK_PMU_PWCTL_SEL_B | PM_CLOCK_PMU_PWCTL_DIV_B ) + +/**************************************************************************** + * cxd56_pm_getclock & cxd56_pm_register_callback Interface Define + *****************************************************************************/ + +#define PM_CLOCK_SYS_CTRL PM_CLOCK_SYS_CTRL_SEL +#define PM_CLOCK_SYSPLL PM_CLOCK_SYSPLL_DIV +#define PM_CLOCK_SYS_CPU PM_CLOCK_SYS_CPU_DIV +#define PM_CLOCK_SYS_AHB PM_CLOCK_SYS_AHB_DIV +#define PM_CLOCK_SYS_APB PM_CLOCK_SYS_APB_DIV +#define PM_CLOCK_SYS_COMIF PM_CLOCK_SYS_COMIF_DIV +#define PM_CLOCK_SYS_UART1 PM_CLOCK_SYS_UART1_SEL +#define PM_CLOCK_SYS_SFC PM_CLOCK_SYS_SFC_DIV +#define PM_CLOCK_XOSC (PM_DOMAIN_SYSIOP | 0x00100000ul) +#define PM_CLOCK_RCOSC (PM_DOMAIN_SYSIOP | 0x00200000ul) +#define PM_CLOCK_RTC (PM_DOMAIN_SYSIOP | 0x00080000ul) +#define PM_CLOCK_PMU_I2C PM_CLOCK_PMU_RTC_PCLK_SEL + +/* HOSTIF */ + +#define PM_CLOCK_HIF PM_CLOCK_HIF_SEL2 +#define PM_CLOCK_HIF_UART0 PM_CLOCK_HIF_UART0_SEL +#define PM_CLOCK_HIF_I2C PM_CLOCK_HIF_I2C_SEL + +/* SCU */ + +#define PM_CLOCK_SCU_XOSC PM_CLOCK_SCU_XOSC_DIV +#define PM_CLOCK_SCU PM_CLOCK_SCU_SEL +#define PM_CLOCK_SCU_32K PM_CLOCK_SCU_32K_SEL +#define PM_CLOCK_SCU_HPADC PM_CLOCK_SCU_HPADC_SEL +#define PM_CLOCK_SCU_LPADC PM_CLOCK_SCU_LPADC_DIV + +/* APP */ + +#define PM_CLOCK_APP_SYSPLL PM_CLOCK_APP_SYSPLL_DIV +#define PM_CLOCK_APP PM_CLOCK_APP_SEL +#define PM_CLOCK_APP_AUD PM_CLOCK_APP_AUD_MCLK_SEL +#define PM_CLOCK_APP_AHB PM_CLOCK_APP_AHB_GEAR +#define PM_CLOCK_APP_CPU PM_CLOCK_APP_AHB +#define PM_CLOCK_APP_UART PM_CLOCK_APP_UART_GEAR +#define PM_CLOCK_APP_SPI PM_CLOCK_APP_SPI_GEAR +#define PM_CLOCK_APP_WSPI PM_CLOCK_APP_WSPI_GEAR +#define PM_CLOCK_APP_SDIO PM_CLOCK_APP_SDIO_GEAR +#define PM_CLOCK_APP_USB PM_CLOCK_APP_USB_GEAR +#define PM_CLOCK_APP_VSYNC PM_CLOCK_APP_VSYNC_GEAR +#define PM_CLOCK_APP_VSYNC_N PM_CLOCK_APP_VSYNC_N_GEAR +#define PM_CLOCK_APP_VSYNC_M PM_CLOCK_APP_VSYNC_GEAR + +/* GPS */ + +#define PM_CLOCK_GPS_PLL PM_CLOCK_GPS_PLL_SEL +#define PM_CLOCK_GPS_ACQ PM_CLOCK_GPS_ACQ_SEL +#define PM_CLOCK_GPS_ITP_TRK PM_CLOCK_GPS_ITP_TRK_SEL +#define PM_CLOCK_GPS_BB_MODE PM_CLOCK_GPS_BB_MODE_SEL +#define PM_CLOCK_GPS_LOGGER PM_CLOCK_GPS_LOGGER_SEL +#define PM_CLOCK_GPS_ITB_FFT PM_CLOCK_GPS_ITB_FFT_SEL +#define PM_CLOCK_GPS_BB PM_CLOCK_GPS_BB_SEL +#define PM_CLOCK_GPS_PPS PM_CLOCK_GPS_PPS_SEL +#define PM_CLOCK_GPS_CPU PM_CLOCK_GPS_CPU_DIV +#define PM_CLOCK_GPS_AHB PM_CLOCK_GPS_AHB_DIV + +/* PMU */ + +#define PM_CLOCK_PMU PM_CLOCK_PMU_PWCTL_SEL +#define PM_CLOCK_PMUA PM_CLOCK_PMU_PWCTL_DIV + +#define PM_CLOCK_SYS_DMAC PM_CLOCK_SYS_AHB +#define PM_CLOCK_SYS_SAKE PM_CLOCK_SYS_AHB +#define PM_CLOCK_SYS_KAKI PM_CLOCK_SYS_AHB +#define PM_CLOCK_SYS_SPIM PM_CLOCK_SYS_COMIF +#define PM_CLOCK_SYS_I2CM PM_CLOCK_SYS_COMIF +#define PM_CLOCK_APP_DMAC PM_CLOCK_APP_AHB_GEAR +#define PM_CLOCK_APP_SAKE PM_CLOCK_APP_AHB_GEAR +#define PM_CLOCK_APP_KAKI PM_CLOCK_APP_AHB_GEAR + +#define PM_CLOCK_CPUID(id) ((0 == (id)) ? PM_CLOCK_SYS_CPU : \ + (1 == (id)) ? PM_CLOCK_GPS_CPU : \ + PM_CLOCK_APP_CPU) + +/* CPU status change callback */ + +#define PM_CPU_STATUS_CHANGE (PM_DOMAIN_SELF_CPU | 0x10000000ul) + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef int (*cxd56_pm_callback)(uint8_t id); + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void *cxd56_pm_register_callback(uint32_t target, cxd56_pm_callback callback); +void cxd56_pm_unregister_callback(void *handle); +int cxd56_pm_fifo_handlear(int cpuid, uint32_t data[2]); +int cxd56_pm_main_task(int argc, FAR char *argv[]); +int cxd56_pm_initialize(void); +int cxd56_pm_bootup(void); +uint32_t cxd56_pm_getclock(uint32_t target); +int cxd56_pm_hotsleep(int idletime); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_ARM_SRC_CXD56XX_POWERMGR_H */