Files
banban/ql-kernel/threadx/quec_minsys/platform_pmu.c

781 lines
19 KiB
C

#ifdef CRANE_MCU_DONGLE
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
paltform_pmu.c
GENERAL DESCRIPTION
This file is for Power management.
EXTERNALIZED FUNCTIONS
INITIALIZATION AND SEQUENCING REQUIREMENTS
Copyright (c) 2019 by ASR, Incorporated. All Rights Reserved.
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*
*===========================================================================
EDIT HISTORY FOR MODULE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
when who what, where, why
-------- ------ ----------------------------------------------------------
05/30/2013 zhoujin Created module
===========================================================================*/
/*===========================================================================
INCLUDE FILES FOR MODULE
===========================================================================*/
#include "osa.h"
#include "utils.h"
#include "intc.h"
#include "sdio.h"
#include "cpmu_def.h"
#include "utilities.h"
#include "usb_macro.h"
#include "platform.h"
#include "mvUsbLog.h"
#include "qspi_dma.h"
#include "cgpio.h"
#include "Intc_Hw_TTC.h"
#include "quec_cust_feature.h"
/*===========================================================================
LOCAL MACRO
===========================================================================*/
/*===========================================================================
LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE
This section contains local definitions for constants, macros, types,
variables and other items needed by this module.
===========================================================================*/
/* Enter D2 count */
char D2EntryCnt = 0;
/* System sleep enable flag */
#if defined(QUEC_POWER_MANAGER_ENABLE)
//移远代码禁止默认进休眠
BOOL SystemSleepEnable_flag = FALSE;
#else
BOOL SystemSleepEnable_flag = TRUE;
#endif
UINT32 g_TS_last_D2Recover=0;
/*===========================================================================
EXTERN DEFINITIONS AND DECLARATIONS FOR MODULE
===========================================================================*/
/* PM usb busy flag */
extern volatile UINT32 pm_usb_busy;
/* UART busy flag */
extern unsigned int uart_busy_flag;
/* usb suspend flag */
extern volatile BOOL g_flag_usb_suspend;
/*===========================================================================
EXTERNAL FUNCTION DEFINITIONS
===========================================================================*/
#if !defined(LTEONLY_THIN_SINGLE_SIM_2MFLASH)
extern int psram_fast_refresh_exit(void);
extern int psram_fast_refresh_entry(void);
#endif
#ifdef BT_SUPPORT
extern int get_bt2host_gpio_no(void);
#endif
extern UINT8 GetUsbPmLock(void);
extern int bt_wakelock_status(void);
extern void USB2ShutdownPhyClock(void);
extern UINT8 sdio_work(void);
extern BOOL CraneLAdcWork(void);
extern int uartdrv_work(void);
#ifdef WIFI_FUNCTION_SUPPORT
extern int get_sdio2host_gpio_no(void);
#endif
#ifdef GPS_SUPPORT
extern unsigned char get_gps_pm_lock_stub(void);
#endif
#ifdef SPINOR_SUPPORT
extern BOOL spinor_dma_work(void);
#endif
#ifdef SPIDRV_SUPPORT
extern BOOL spidrv_dma_work(void);
#endif
/*===========================================================================
INTERNAL FUNCTION DEFINITIONS
===========================================================================*/
#if defined(BT_SUPPORT) || defined(WIFI_FUNCTION_SUPPORT)
BOOL GPIOWakeupEnable(int pin)
{
volatile UINT32 temp = 0;
unsigned int addr = 0xD401E0DC; // address of GPIO 0
switch(pin)
{
case 1:
addr = 0xD401E0E0;
break;
case 12: // GPIO 12
addr = 0xD401E10C;
break;
case 60: // GPIO 60
addr = 0xD401E304;
break;
case 86: // GPIO 86
addr = 0xD401E1F4;
break;
case 28: //GPIO 28
addr = 0xD401E14C;
break;
case 34: //GPIO 34
addr = 0xD401E164;
break;
default:
return FALSE;
}
temp = BU_REG_READ(addr);
temp = (temp | BIT_4 | BIT_5) & (~BIT_6);
BU_REG_WRITE(addr, temp);
return TRUE;
}
BOOL GPIOWakeupDisable(int pin)
{
volatile UINT32 temp = 0;
unsigned int addr = 0xD401E0DC; // address of GPIO 0
switch(pin)
{
case 1:
addr = 0xD401E0E0;
break;
case 12: // GPIO 12
addr = 0xD401E10C;
break;
case 60: // GPIO 60
addr = 0xD401E304;
break;
case 86: // GPIO 86
addr = 0xD401E1F4;
break;
case 28: //GPIO 28
addr = 0xD401E14C;
break;
case 34: //GPIO 34
addr = 0xD401E164;
break;
default:
return FALSE;
}
temp = BU_REG_READ(addr);
temp = temp | BIT_6;
BU_REG_WRITE(addr, temp);
return TRUE;
}
#endif
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : CommPMVbusDetect
* Returned Value : None
* Comments :
* check Vbus detect bit
*
*END*-----------------------------------------------------------------*/
BOOL CommPMVbusDetect(void)
{
/* Check Vbus on bit.*/
if((*(volatile UINT32 *)PMUA_SD_ROT_WAKE_CLR) & VBUS_DETECT)
{
return TRUE;
}
else
{
return FALSE;
}
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : CommPMUsbWakeupHandle
* Returned Value : None
* Comments :
* Services transaction complete interrupt
*
*END*-----------------------------------------------------------------*/
void CommPMUsbWakeupHandle(int state)
{
volatile UINT32 wakeup_src;
/*Management WakeUp Event*/
wakeup_src = BU_REG_READ(PMUM_CWUCRS) & BU_REG_READ(PMUM_CWUCRM);
/* Check whether it is USB wakeup source or not.*/
if(wakeup_src&(0x1<<5))
{
#ifdef CRANELS_SUPPORT
if(IsChipCraneLS())
{
volatile UINT32 irqPending = 0, int_number = 0;
if( (irqPending = InterruptController.own.ICU_IRQ_PENDING) & ICU_PENDING_INT_VALID_BITS_CRANE)
{
// identify the SOURCE interrupt
int_number = irqPending & ICU_PENDING_INT_NUM_BITS_CRANE;
// USB int number: 44, bt ipc int number: 23
if(int_number != (INTC_SRC_USB - INTC_SRC_XIRQ))
{
return;
}
}
}
#endif
#ifdef NO_USB_VBUS
pm_usb_busy = 1;
if(state)
{
USB_TRACE("C1WK"); //USB_TRACE("C1: usb wakeup");
}
else
{
USB_TRACE("D2WK"); //USB_TRACE("D2: usb wakeup");
}
#else
pm_usb_busy = 1;
/* Check Vbus on bit.*/
if(CommPMVbusDetect())
{
if(state)
{
USB_TRACE("C1WK"); //USB_TRACE("C1: usb wakeup");
}
else
{
USB_TRACE("D2WK"); //USB_TRACE("D2: usb wakeup");
}
}
else
{
//pm_usb_busy = 0;
if(state)
{
USB_TRACE("C1OFF");//USB_TRACE("C1: usb vbus off");
}
else
{
USB_TRACE("D2OFF"); //USB_TRACE("D2: usb vbus off");
}
}
#endif
}
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : CommPMEnableUsbWakeupSource
* Returned Value : None
* Comments :
* Services transaction complete interrupt
*
*END*-----------------------------------------------------------------*/
void CommPMEnableUbusWakeupSource(void)
{
volatile UINT32 temp = 0;
/* USB wakeup */
temp = BU_REG_READ(PMUM_CPCR);
temp &= ~(PMUM_CPCR_SLPWP5);
BU_REG_WRITE(PMUM_CPCR, temp);
temp = BU_REG_READ(PMUM_CWUCRM);
temp |= PMUM_CWUCRM_WAKEUP5;
BU_REG_WRITE(PMUM_CWUCRM, temp);
/* Clear USB interrupt */
/* Only clear line status wakeup interrupt, vbus must not */
temp = BU_REG_READ(PMUA_SD_ROT_WAKE_CLR);
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, temp | (USB_LINEST_WK_CLR));
/* Enable line0 status wakeup under C1 only under usb suspend */
#ifdef NO_USB_VBUS
if(g_flag_usb_suspend == TRUE)
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN | VBUS_VALID_WK_EN)) | LINEST0_WK_EN);
#else
/*enable usb wakeup source */
if(CommPMVbusDetect())
{
if(g_flag_usb_suspend == TRUE)
{
/* Enable wakeup source, vbus and line0(only under usb suspend) */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN)) | (LINEST0_WK_EN | VBUS_VALID_WK_EN));
}
else
{
/* Enable wakeup source, vbus only */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST0_WK_EN | LINEST1_WK_EN)) | (VBUS_VALID_WK_EN));
}
}
else
{
/* Enable wakeup source, vbus only */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST0_WK_EN | LINEST1_WK_EN)) | (VBUS_VALID_WK_EN));
}
#endif
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : CommPMDisableUbusWakeupSource
* Returned Value : None
* Comments :
* Services transaction complete interrupt
*
*END*-----------------------------------------------------------------*/
void CommPMDisableUbusWakeupSource(void)
{
volatile UINT32 temp = 0;
temp = BU_REG_READ(PMUA_SD_ROT_WAKE_CLR);
#ifdef NO_USB_VBUS
/* Disable line status and Vbus wakeup */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN | VBUS_VALID_WK_EN | LINEST0_WK_EN)));
#else
/* Disable line status wakeup, enable vbus only */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST0_WK_EN | LINEST1_WK_EN)) | (VBUS_VALID_WK_EN));
#endif
/* Mask usb wake up source.*/
temp = BU_REG_READ(PMUM_CWUCRM);
temp &= ~(PMUM_CWUCRM_WAKEUP5);
BU_REG_WRITE(PMUM_CWUCRM, temp);
temp = BU_REG_READ(PMUM_CPCR);
temp |= (PMUM_CPCR_SLPWP5);
BU_REG_WRITE(PMUM_CPCR, temp);
}
void CommPMEnableUsbWakeupSource(void)
{
volatile UINT32 temp = 0;
/* USB wakeup */
temp = BU_REG_READ(PMUM_CPCR);
temp &= ~(PMUM_CPCR_SLPWP5);
BU_REG_WRITE(PMUM_CPCR, temp);
temp = BU_REG_READ(PMUM_CWUCRM);
temp |= PMUM_CWUCRM_WAKEUP5;
BU_REG_WRITE(PMUM_CWUCRM, temp);
#if (defined(CRANELS_SUPPORT) || defined(CRANELG_SUPPORT))
/* GNSS WAKEUP HOST(WKSRC29) */
temp = BU_REG_READ(PMUM_CPCR);
temp &= ~(PMUM_CPCR_SLPWP0);
BU_REG_WRITE(PMUM_CPCR, temp);
temp = BU_REG_READ(PMUM_CWUCRM);
temp |= PMUM_CWUCRM_GSM_WAKEUPWMX;
BU_REG_WRITE(PMUM_CWUCRM, temp);
#endif /* CRANELS_SUPPORT || CRANELG_SUPPORT*/
#if defined(BT_SUPPORT) || defined(WIFI_FUNCTION_SUPPORT)
/* GPIO wakeup */
temp = BU_REG_READ(PMUM_CPCR);
temp &= ~(PMUM_CPCR_SLPWP2);
BU_REG_WRITE(PMUM_CPCR, temp);
temp = BU_REG_READ(PMUM_CWUCRM);
temp |= PMUM_CWUCRM_WAKEUP2;
BU_REG_WRITE(PMUM_CWUCRM, temp);
#endif
/* Clear USB interrupt */
temp = BU_REG_READ(PMUA_SD_ROT_WAKE_CLR);
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, temp | (USB_VBUS_WK_CLR | USB_LINEST_WK_CLR));
#ifdef NO_USB_VBUS
/* Enable line0 status wakeup under D2 */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN | VBUS_VALID_WK_EN)) | LINEST0_WK_EN);
#else
if(CommPMVbusDetect())
{
/* Enable wakeup source, vbus and line0 under D2 */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN)) | (LINEST0_WK_EN | VBUS_VALID_WK_EN));
}
else
{
/* Enable wakeup source, vbus only */
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST0_WK_EN | LINEST1_WK_EN)) | (VBUS_VALID_WK_EN));
}
#endif
#ifdef BT_SUPPORT
{
int no = get_bt2host_gpio_no();
if(no > 0)
{
GPIOWakeupEnable(no);
}
}
#endif
#ifdef WIFI_FUNCTION_SUPPORT
GPIOWakeupEnable(get_sdio2host_gpio_no());
#endif
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : CommPMDisableUsbWakeupSource
* Returned Value : None
* Comments :
* Services transaction complete interrupt
*
*END*-----------------------------------------------------------------*/
void CommPMDisableUsbWakeupSource(void)
{
volatile UINT32 temp = 0;
temp = BU_REG_READ(PMUA_SD_ROT_WAKE_CLR);
#ifdef NO_USB_VBUS
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST1_WK_EN | VBUS_VALID_WK_EN | LINEST0_WK_EN))); //disable line status wakeup
#else
BU_REG_WRITE(PMUA_SD_ROT_WAKE_CLR, (temp & ~(LINEST0_WK_EN | LINEST1_WK_EN)) | (VBUS_VALID_WK_EN)); //disable line status wakeup, enable vbus only
#endif
/* Mask usb wake up source.*/
temp = BU_REG_READ(PMUM_CWUCRM);
temp &= ~(PMUM_CWUCRM_WAKEUP5);
BU_REG_WRITE(PMUM_CWUCRM, temp);
temp = BU_REG_READ(PMUM_CPCR);
temp |= (PMUM_CPCR_SLPWP5);
BU_REG_WRITE(PMUM_CPCR, temp);
#if (defined(CRANELS_SUPPORT) || defined(CRANELG_SUPPORT))
/* Mask GNSS->Host WKSRC29*/
temp = BU_REG_READ(PMUM_CWUCRM);
temp &= ~(PMUM_CWUCRM_GSM_WAKEUPWMX);
BU_REG_WRITE(PMUM_CWUCRM, temp);
temp = BU_REG_READ(PMUM_CPCR);
temp |= (PMUM_CPCR_SLPWP0);
BU_REG_WRITE(PMUM_CPCR, temp);
#endif
#if defined(BT_SUPPORT) || defined(WIFI_FUNCTION_SUPPORT)
/* Mask GPIO wake up source.*/
temp = BU_REG_READ(PMUM_CWUCRM);
temp &= ~(PMUM_CWUCRM_WAKEUP2);
BU_REG_WRITE(PMUM_CWUCRM, temp);
temp = BU_REG_READ(PMUM_CPCR);
temp |= (PMUM_CPCR_SLPWP2);
BU_REG_WRITE(PMUM_CPCR, temp);
#ifdef BT_SUPPORT
{
int no = get_bt2host_gpio_no();
if(no > 0)
{
GPIOWakeupDisable(no);
}
}
#endif
#ifdef WIFI_FUNCTION_SUPPORT
GPIOWakeupDisable(get_sdio2host_gpio_no());
#endif
#endif
}
/*===========================================================================
FUNCTION PlatformC1Prepare
DESCRIPTION
This function consists of the platform internal C1 preparations..
DEPENDENCIES
None.
RETURN VALUE
none
SIDE EFFECTS
none
===========================================================================*/
void PlatformC1Prepare(void)
{
CommPMEnableUbusWakeupSource();
return;
}
/*===========================================================================
FUNCTION PlatformC1Recover
DESCRIPTION
This function consists of the platform internal C1 recovery.
DEPENDENCIES
None.
RETURN VALUE
none
SIDE EFFECTS
none
===========================================================================*/
void PlatformC1Recover(void)
{
CommPMUsbWakeupHandle(1);
CommPMDisableUbusWakeupSource();
return;
}
/*===========================================================================
FUNCTION PlatformD2Prepare
DESCRIPTION
This function consists of the platform internal D2 preparations..
DEPENDENCIES
None.
RETURN VALUE
none
SIDE EFFECTS
none
===========================================================================*/
#ifndef MIN_SYS
#ifdef QUEC_QSCLKEX_ENABLE
#include "quec_power_manager.h"
extern quec_qsclk_ex_s qsclkex_cfg;
#endif
#endif
void PlatformD2Prepare(void)
{
if(D2EntryCnt == 0)
{
#ifdef NO_USB_VBUS
if(pm_usb_busy == 0)
{
/* shutdown usb phy clock if system bring up without usb plugin */
USB2ShutdownPhyClock();
}
#endif
D2EntryCnt = 1;
USB_TRACE("->Enter D2");
}
if (!IsMiniSystem())
{
#ifndef MIN_SYS
extern GPIOReturnCode GpioEnableEdgeDetection_wakeup(UINT32 portHandle,GPIOTransitionType edge);
extern char quec_uart_get_wakeup_mode_flag(UART_Port port);
extern void quec_aotu_flow_Disable(UART_Port portNumber);
extern void* quec_get_gpio_wu_hisr(int gpio_num);
if(quec_uart_get_wakeup_mode_flag(UART_PORT_STUART)&&(!quec_get_gpio_wu_hisr(51)))
{
GpioEnableEdgeDetection_wakeup(51,GPIO_TWO_EDGE);//在GpioCommonWakeupCallback关闭边沿检测这里再打开 pony add 2023 11 07
}
quec_aotu_flow_Disable(UART_PORT_STUART);
#ifdef QUEC_QSCLKEX_ENABLE
if(TRUE == qsclkex_cfg.en)
{
quec_rrc_release_faster_handle(); //sleep not run,punish_remain_time is stop
}
#endif
#endif
}
CommPMEnableUsbWakeupSource();
#ifndef QUECTEL_PROJECT_CUST
/* Enable Edge detect wakeup interrupt. */
INTCEnable(INTC_SRC_ICU_RESERVED9);
#endif
#if !defined(LTEONLY_THIN_SINGLE_SIM_2MFLASH)
psram_fast_refresh_exit();
#endif
#ifdef NO_USB_VBUS
/* shut down usb phy clk again after usb pluged out*/
if((pm_usb_busy ==0) && (USB2_PHY_PLL_READY()))
{
USB2ShutdownPhyClock();
}
#endif
//USB_TRACE("D2P");
return;
}
/*===========================================================================
FUNCTION PlatformD2Recover
DESCRIPTION
This function consists of the platform internal D2 recovery.
DEPENDENCIES
None.
RETURN VALUE
none
SIDE EFFECTS
none
===========================================================================*/
void PlatformD2Recover(void)
{
volatile UINT32 wakeup_src;
#if !defined(LTEONLY_THIN_SINGLE_SIM_2MFLASH)
psram_fast_refresh_entry();
#endif
g_TS_last_D2Recover = get_current_TStimer_tick();
wakeup_src = BU_REG_READ(PMUM_CWUCRS) & BU_REG_READ(PMUM_CWUCRM);
USB_TRACE("D2R,Src:%x",wakeup_src);
CommPMUsbWakeupHandle(0);
CommPMDisableUsbWakeupSource();
return;
}
/*===========================================================================
FUNCTION PlatformPmLock
DESCRIPTION
This function get platform work lock flag.
DEPENDENCIES
None.
RETURN VALUE
none
SIDE EFFECTS
none
===========================================================================*/
#if defined(QUEC_POWER_MANAGER_ENABLE)
#include "qspi_dma.h"
#endif
#ifdef QUEC_CAMERA_SUPPORT
unsigned int cam_dma_busy_flag = 0;
void SleepFlag_CAM_DMA_Set(UINT8 flag)
{
if(flag)
cam_dma_busy_flag= 1;
else
cam_dma_busy_flag = 0;
return;
}
unsigned int QuecCameraIsWork (void)
{
return cam_dma_busy_flag;
}
#endif
#if defined(QUEC_GPS_SUPPORT)
extern unsigned char get_gps_pm_lock(void);
static char get_gps_lock(void)
{
if(!IsMiniSystem()){
return get_gps_pm_lock();
}else{
return 0;
}
}
#endif
BOOL PlatformWorkLock(void)
{
if (uart_busy_flag || GetUsbPmLock() || SDWork() || sdio_work()
#if defined(DM_SOC_ADC_SUPPORT)
|| CraneLAdcWork()
#endif
#if defined(QUEC_GPS_SUPPORT)
|| get_gps_lock()
#endif
#if defined(QUEC_POWER_MANAGER_ENABLE)
|| dma_wakelock()
#endif
#ifdef QUEC_CAMERA_SUPPORT
|| QuecCameraIsWork()
#endif
)
{
return TRUE;
}
else
{
return FALSE;
}
}
#endif
void quec_set_sleep_flag(char flag)
{
SystemSleepEnable_flag = flag;
}