summaryrefslogtreecommitdiff
path: root/drivers/platform/sprd/pm-scx35.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/sprd/pm-scx35.c')
-rw-r--r--drivers/platform/sprd/pm-scx35.c1829
1 files changed, 1829 insertions, 0 deletions
diff --git a/drivers/platform/sprd/pm-scx35.c b/drivers/platform/sprd/pm-scx35.c
new file mode 100644
index 00000000..7ec92fa0
--- /dev/null
+++ b/drivers/platform/sprd/pm-scx35.c
@@ -0,0 +1,1829 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+#include <linux/io.h>
+#include <linux/kthread.h>
+#include <asm/irqflags.h>
+//#include <asm/hardware/cache-l2x0.h>
+#include <asm/cacheflush.h>
+#include <soc/sprd/system.h>
+#include <soc/sprd/pm_debug.h>
+#include <soc/sprd/common.h>
+#include <soc/sprd/hardware.h>
+#include <soc/sprd/sci_glb_regs.h>
+//#include <mach/irqs.h>
+#include <soc/sprd/sci.h>
+//#include "emc_repower.h"
+#include <linux/clockchips.h>
+#include <linux/wakelock.h>
+#include <soc/sprd/adi.h>
+#include <soc/sprd/arch_misc.h>
+#include <asm/suspend.h>
+#include <asm/barrier.h>
+#include <linux/cpu_pm.h>
+#if defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8)
+#include <soc/sprd/sprd_persistent_clock.h>
+#endif
+#if defined(CONFIG_SPRD_DEBUG)
+/* For saving Fault status */
+#include <soc/sprd/sprd_debug.h>
+#endif
+
+extern void (*arm_pm_restart)(char str, const char *cmd);
+extern int sc8830_get_clock_status(void);
+extern void secondary_startup(void);
+extern int sp_pm_collapse(unsigned int cpu, unsigned int save_state);
+extern void sp_pm_collapse_exit(void);
+extern void sc8830_standby_iram(void);
+extern void sc8830_standby_iram_end(void);
+extern void sc8830_standby_exit_iram(void);
+extern int sc_cpuidle_init(void);
+void pm_ana_ldo_config(void);
+struct ap_ahb_reg_bak {
+ u32 ahb_eb;
+ u32 ca7_ckg_cfg;
+ u32 ca7_div_cfg;
+ u32 misc_ckg_en;
+ u32 misc_cfg;
+ u32 usb_phy_tune;
+};
+struct ap_clk_reg_bak {
+ u32 ap_ahb_cfg;
+ u32 ap_apb_cfg;
+ u32 clk_gsp_cfg;
+ u32 dispc0_cfg;
+ u32 dispc0_dbi_cfg;
+ u32 dispc0_dpi_cfg;
+ u32 dispc1_cfg;
+ u32 dispc1_dbi_cfg;
+ u32 dispc1_dpi_cfg;
+ u32 nfc_cfg;
+ u32 sdio0_cfg;
+ u32 sdio1_cfg;
+ u32 sdio2_cfg;
+ u32 emmc_cfg;
+ u32 gps_cfg;
+ u32 gps_tcxo_cfg;
+ u32 usb_ref_cfg;
+ u32 uart0_cfg;
+ u32 uart1_cfg;
+ u32 uart2_cfg;
+ u32 uart3_cfg;
+ u32 uart4_cfg;
+ u32 i2c0_cfg;
+ u32 i2c1_cfg;
+ u32 i2c2_cfg;
+ u32 i2c3_cfg;
+ u32 i2c4_cfg;
+ u32 spi0_cfg;
+ u32 spi1_cfg;
+ u32 spi2_cfg;
+ u32 iis0_cfg;
+ u32 iis1_cfg;
+ u32 iis2_cfg;
+ u32 iis3_cfg;
+};
+struct ap_apb_reg_bak {
+ u32 apb_eb;
+ u32 usb_phy_tune;
+ u32 usb_phy_ctrl;
+ u32 apb_misc_ctrl;
+};
+struct pub_reg_bak {
+ u32 ddr_qos_cfg1;
+ u32 ddr_qos_cfg2;
+ u32 ddr_qos_cfg3;
+};
+struct mm_reg_bak {
+ u32 mm_cfg1;
+ u32 mm_cfg2;
+};
+
+struct auto_pd_en {
+ volatile u32 magic_header;
+ volatile u32 bits;
+ volatile u32 magic_end;
+ char pd_config_menu[6][16];
+};
+
+struct dcdc_core_ds_step_info{
+ u32 ctl_reg;
+ u32 ctl_sht;
+ u32 cal_reg;
+ u32 cal_sht;
+};
+
+static struct ap_ahb_reg_bak ap_ahb_reg_saved;
+static struct ap_clk_reg_bak ap_clk_reg_saved;
+static struct ap_apb_reg_bak ap_apb_reg_saved;
+static struct pub_reg_bak pub_reg_saved;
+
+#if defined(CONFIG_ARCH_SCX15)
+static struct mm_reg_bak mm_reg_saved;
+#endif
+
+#if defined(CONFIG_ARCH_SCX30G)
+static unsigned long ana_chip_id;
+#endif
+
+/* bits definition
+ * bit_0 : ca7 top
+ * bit_1 : ca7 c0
+ * bit_2 : pub
+ * bit_3 : mm
+ * bit_4 : ap sys
+ * bit_5 : dcdc arm
+*/
+static struct auto_pd_en pd_config = {
+ 0x6a6aa6a6, 0x3f,0xa6a66a6a,
+ .pd_config_menu = {
+ "ca7_top",
+ "ca7_c0",
+ "pub",
+ "mm",
+ "ap_sys",
+ "dcdc_arm",
+ },
+};
+
+/*
+ * we just conigure the auto_pd_en property for parts of power domain, ldo here
+ * clr = 0 means called when kernel init and after real deep sleep
+ * clr = 1 means just called before real deep sleep
+ */
+static void configure_for_deepsleep(int clr)
+{
+#if defined(CONFIG_ARCH_SCX15)
+ if (clr) {
+ sci_glb_clr(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_PMU_APB_PD_AP_SYS_CFG, BIT_PD_AP_SYS_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+ /* FIXME: we can't powerdown ca7 because of stability problem when idle deep sleep */
+ //sci_glb_clr(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+ //sci_glb_clr(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_clr(REG_PMU_APB_PD_APCPU_TOP_CFG, BIT_PD_CA53_TOP_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_PMU_APB_PD_APCPU_C0_CFG, BIT_PD_CA53_LIT_C0_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_clr(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#endif
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_DCDCARM_PD_EN);
+ /*
+ * because we can power down rf0 and vdd25 in idle deep now
+ * so we can let it be configured in u-boot
+ */
+ /* sci_adi_set(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_LDORF0_PD_EN); */
+ /* sci_adi_set(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_LDOVDD25_PD_EN); */
+#if defined(CONFIG_MACH_CORSICA_VE)
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOSIM2_PD_EN);
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOCAMMOT_PD_EN);
+#endif
+ } else {
+ if (pd_config.bits & (0x1 << 0))
+ //sci_glb_set(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_PMU_APB_PD_APCPU_TOP_CFG, BIT_PD_CA53_TOP_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_set(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+#endif
+ if (pd_config.bits & (0x1 << 1))
+ //sci_glb_set(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_PMU_APB_PD_APCPU_C0_CFG, BIT_PD_CA53_LIT_C0_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_set(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#endif
+ if (pd_config.bits & (0x1 << 2))
+ sci_glb_set(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+ if (pd_config.bits & (0x1 << 3))
+ sci_glb_set(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ if (pd_config.bits & (0x1 << 4))
+ sci_glb_set(REG_PMU_APB_PD_AP_SYS_CFG, BIT_PD_AP_SYS_AUTO_SHUTDOWN_EN);
+ if (pd_config.bits & (0x1 << 5))
+ sci_adi_set(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_DCDCARM_PD_EN);
+#if defined(CONFIG_MACH_CORSICA_VE)
+ sci_adi_set(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOSIM2_PD_EN);
+ sci_adi_set(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOCAMMOT_PD_EN);
+#endif
+ #if defined(CONFIG_SS_FUNCTION)
+ sci_glb_set(REG_PMU_APB_PD_PUB_SYS_CFG,BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+ #endif
+ }
+#endif
+}
+
+static void setup_autopd_mode(void)
+{
+ if (soc_is_scx35_v0())
+ sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, 0x3a);
+ else
+ sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, 0x3B);
+ sci_glb_write(REG_PMU_APB_AP_WAKEUP_POR_CFG, 0x1, -1UL);//AP_WAKEUP_POR_CFG
+
+ //sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, BIT_AP_EMC_AUTO_GATE_EN | BIT_CA7_EMC_AUTO_GATE_EN | BIT_CA7_CORE_AUTO_GATE_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, BIT_AP_EMC_AUTO_GATE_EN | BIT_CA53_EMC_AUTO_GATE_EN | BIT_CA53_CORE_AUTO_GATE_EN);
+#else
+ sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, BIT_AP_EMC_AUTO_GATE_EN | BIT_CA7_EMC_AUTO_GATE_EN | BIT_CA7_CORE_AUTO_GATE_EN);
+#endif
+
+ // INTC0_EB, INTC1_EB, INTC2_EB, INTC3_EB
+ sci_glb_set(REG_AP_APB_APB_EB, 0xf<<19);
+
+ //set PD_CA7_C0_AUTO_SHUTDOWN_EN
+ //sci_glb_set(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_PMU_APB_PD_APCPU_TOP_CFG, BIT_PD_CA53_TOP_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_set(REG_PMU_APB_PD_CA7_TOP_CFG, BIT_PD_CA7_TOP_AUTO_SHUTDOWN_EN);
+#endif
+ //set PD_CA7_C0_AUTO_SHUTDOWN_EN
+ //sci_glb_set(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_PMU_APB_PD_CA53_LIT_C0_CFG, BIT_PD_CA53_LIT_C0_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_set(REG_PMU_APB_PD_CA7_C0_CFG, BIT_PD_CA7_C0_AUTO_SHUTDOWN_EN);
+#endif
+ sci_glb_set(SPRD_INT_BASE + 0x8, BIT(14) | BIT(4)); //ana & eic
+ /* Temporarily put it in here for AON Timer can wakeup cluster gating */
+ sci_glb_set(SPRD_INT_BASE + 0x8, BIT(2));
+
+ sci_glb_set(SPRD_INTC1_BASE + 0x8, BIT(6) | BIT(4)); //ana & kpd
+ //sci_glb_set(SPRD_INT_BASE + 0x8, BIT(2)); //ana & eic
+ //sci_glb_set(SPRD_INTC0_BASE + 0x8, BIT(30) | BIT(31)); //syst & aon_syst
+
+ //sci_adi_set(ANA_REG_GLB_LDO_SLP_CTRL0, BIT_SLP_IO_EN | BIT_SLP_LDORF0_PD_EN | BIT_SLP_LDORF1_PD_EN | BIT_SLP_LDORF2_PD_EN);
+ //sci_adi_clr(ANA_REG_GLB_LDO_SLP_CTRL0, BIT_SLP_IO_EN | BIT_SLP_LDORF0_PD_EN | BIT_SLP_LDORF1_PD_EN | BIT_SLP_LDORF2_PD_EN);
+
+ //sci_adi_set(ANA_REG_GLB_LDO_SLP_CTRL1, BIT_SLP_LDO_PD_EN);
+ sci_adi_clr(ANA_REG_GLB_XTL_WAIT_CTRL, BIT_SLP_XTLBUF_PD_EN);
+ //sci_adi_set(ANA_REG_GLB_XTL_WAIT_CTRL, BIT_SLP_XTLBUF_PD_EN);
+ //sci_adi_set(ANA_REG_GLB_LDO_SLP_CTRL2, BIT_SLP_LDORF2_LP_EN | BIT_SLP_LDORF1_LP_EN | BIT_SLP_LDORF0_LP_EN);
+
+ //sci_adi_clr(ANA_REG_GLB_LDO_SLP_CTRL2, BIT_SLP_LDORF2_LP_EN | BIT_SLP_LDORF1_LP_EN | BIT_SLP_LDORF0_LP_EN);
+
+ //sci_glb_set(REG_PMU_APB_DDR_SLEEP_CTRL, 7<<4);
+ //sci_glb_set(REG_PMU_APB_DDR_SLEEP_CTRL, 5<<4);
+#if defined(CONFIG_ARCH_SCX15)
+ sci_glb_set(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+#else
+ if (soc_is_scx35_v1()) {
+ sci_glb_set(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+ }
+#if !(defined(CONFIG_ARCH_SCX30G) || defined(CONFIG_ARCH_SCX35L))
+ else {
+ sci_glb_clr(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+ }
+#endif
+
+#if defined(CONFIG_SCX35_DMC_FREQ_DDR3)
+ sci_glb_clr(REG_PMU_APB_PD_PUB_SYS_CFG, BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+#endif
+
+#endif
+
+#if defined(CONFIG_ARCH_SCX15)
+ sci_glb_set(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_PMU_APB_PD_PUB_SYS_CFG,BIT_PD_PUB_SYS_AUTO_SHUTDOWN_EN);
+#else
+ sci_glb_clr(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+#endif
+ sci_glb_write(REG_PMU_APB_AP_WAKEUP_POR_CFG, 0x1, -1UL);
+ /* KEEP eMMC/SD power */
+#if defined(CONFIG_ADIE_SC2723)
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_LDOEMMCCORE_PD_EN);
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOSDCORE_PD_EN | BIT_SLP_LDOSDIO_PD_EN);
+#elif defined(CONFIG_ADIE_SC2723S)
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL0, BIT_SLP_LDOEMMCCORE_PD_EN); /* | BIT_SLP_LDOEMMCIO_PD_EN);*/
+ sci_adi_clr(ANA_REG_GLB_PWR_SLP_CTRL1, BIT_SLP_LDOSDIO_PD_EN );
+#else
+ sci_adi_clr(ANA_REG_GLB_LDO_SLP_CTRL0, BIT_SLP_LDOEMMCCORE_PD_EN | BIT_SLP_LDOEMMCIO_PD_EN);
+ sci_adi_clr(ANA_REG_GLB_LDO_SLP_CTRL1, BIT_SLP_LDOSD_PD_EN );
+#endif
+ /***************** for idle to deep ****************/
+ configure_for_deepsleep(1);
+ return;
+}
+void disable_mm(void)
+{
+ sci_glb_clr(REG_MM_AHB_GEN_CKG_CFG, BIT_JPG_AXI_CKG_EN | BIT_VSP_AXI_CKG_EN |\
+ BIT_ISP_AXI_CKG_EN | BIT_DCAM_AXI_CKG_EN | BIT_SENSOR_CKG_EN | BIT_MIPI_CSI_CKG_EN | BIT_CPHY_CFG_CKG_EN);
+ sci_glb_clr(REG_MM_AHB_AHB_EB, BIT_JPG_EB | BIT_CSI_EB | BIT_VSP_EB | BIT_ISP_EB | BIT_CCIR_EB | BIT_DCAM_EB);
+ sci_glb_clr(REG_MM_AHB_GEN_CKG_CFG, BIT_MM_AXI_CKG_EN);
+ sci_glb_clr(REG_MM_AHB_GEN_CKG_CFG, BIT_MM_MTX_AXI_CKG_EN);
+ sci_glb_clr(REG_MM_AHB_AHB_EB, BIT_MM_CKG_EB);
+ sci_glb_clr(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ sci_glb_clr(REG_AON_APB_APB_EB0, BIT_MM_EB);
+ sci_glb_set(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ return;
+}
+void bak_restore_mm(int bak)
+{
+ static uint32_t gen_ckg, ahb_eb, mm_top, aon_eb0;
+ static uint32_t gen_ckg_en_mask = BIT_JPG_AXI_CKG_EN | BIT_VSP_AXI_CKG_EN |\
+ BIT_ISP_AXI_CKG_EN | BIT_DCAM_AXI_CKG_EN | BIT_SENSOR_CKG_EN | BIT_MIPI_CSI_CKG_EN | BIT_CPHY_CFG_CKG_EN;
+ static uint32_t ahb_eb_mask = BIT_JPG_EB | BIT_CSI_EB | BIT_VSP_EB | BIT_ISP_EB | BIT_CCIR_EB | BIT_DCAM_EB;
+ if(bak){
+ gen_ckg = sci_glb_read(REG_MM_AHB_GEN_CKG_CFG, -1UL);
+ ahb_eb = sci_glb_read(REG_MM_AHB_AHB_EB, -1UL);
+ mm_top = sci_glb_read(REG_PMU_APB_PD_MM_TOP_CFG, -1UL);
+ aon_eb0 = sci_glb_read(REG_AON_APB_APB_EB0, -1UL);
+ }else{
+ sci_glb_clr(REG_PMU_APB_PD_MM_TOP_CFG,BIT_PD_MM_TOP_AUTO_SHUTDOWN_EN);
+ if(aon_eb0 & BIT_MM_EB)
+ sci_glb_set(REG_AON_APB_APB_EB0, BIT_MM_EB);
+ if(ahb_eb & BIT_MM_CKG_EB)
+ sci_glb_set(REG_MM_AHB_AHB_EB, BIT_MM_CKG_EB);
+ if(gen_ckg & BIT_MM_MTX_AXI_CKG_EN)
+ sci_glb_set(REG_MM_AHB_GEN_CKG_CFG, BIT_MM_MTX_AXI_CKG_EN);
+ if(gen_ckg & BIT_MM_AXI_CKG_EN)
+ sci_glb_set(REG_MM_AHB_GEN_CKG_CFG, BIT_MM_AXI_CKG_EN);
+ if(ahb_eb & ahb_eb_mask)
+ sci_glb_write(REG_MM_AHB_AHB_EB, ahb_eb, ahb_eb_mask);
+ if(gen_ckg & gen_ckg_en_mask)
+ sci_glb_write(REG_MM_AHB_GEN_CKG_CFG, gen_ckg, gen_ckg_en_mask);
+ }
+ return;
+}
+void disable_dma(void)
+{
+ int reg = sci_glb_read(SPRD_DMA0_BASE, BIT(16));
+ int cnt = 30;
+ if(reg){
+ sci_glb_set((SPRD_DMA0_BASE), BIT(0)); // pause dma
+ while(cnt-- && reg){
+ sci_glb_read(SPRD_DMA0_BASE, BIT(16));
+ udelay(100);
+ reg = sci_glb_read(SPRD_DMA0_BASE, BIT(16));
+ }
+ if(reg)
+ printk("disable dma failed\n");
+ }
+ sci_glb_clr(REG_AP_AHB_AHB_EB, BIT_DMA_EB);
+}
+void disable_ahb_module(void)
+{
+ //sci_glb_write(REG_AP_AHB_AHB_EB, 0, -1UL);
+ sci_glb_clr(REG_AP_AHB_AHB_EB, 0x1fff);
+
+ // AP_PERI_FORCE_SLP
+
+ sci_glb_set(REG_AP_AHB_AP_SYS_FORCE_SLEEP_CFG, BIT_AP_PERI_FORCE_SLP);
+ //sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_SLEEP_FOLLOW_CA7_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_SLEEP_FOLLOW_CA53_EN);
+#else
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_SLEEP_FOLLOW_CA7_EN);
+#endif
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_DEEP_SLEEP_EN);
+
+ //AP_SYS_AUTO_SLEEP_CFG
+ sci_glb_set(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG, 0x3B);
+
+ return;
+}
+void bak_restore_ahb(int bak)
+{
+ volatile u32 i;
+ if(bak){
+ ap_ahb_reg_saved.ahb_eb = sci_glb_read(REG_AP_AHB_AHB_EB, -1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ //ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_SEL_CFG, -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_APCPU_CKG_SEL_CFG, -1UL);
+#else
+ ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_SEL_CFG, -1UL);
+#endif
+ ap_ahb_reg_saved.usb_phy_tune = sci_glb_read(REG_AP_AHB_OTG_PHY_TUNE, -1UL);
+ //ap_ahb_reg_saved.ca7_div_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_DIV_CFG, -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ ap_ahb_reg_saved.ca7_div_cfg = sci_glb_read(REG_AP_AHB_APCPU_CKG_DIV_CFG, -1UL);
+#else
+ ap_ahb_reg_saved.ca7_div_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_DIV_CFG, -1UL);
+#endif
+#else
+ //ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_CFG, -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_APCPU_CKG_CFG, -1UL);
+#else
+ ap_ahb_reg_saved.ca7_ckg_cfg = sci_glb_read(REG_AP_AHB_CA7_CKG_CFG, -1UL);
+#endif
+#endif
+ ap_ahb_reg_saved.misc_ckg_en = sci_glb_read(REG_AP_AHB_MISC_CKG_EN, -1UL);
+ ap_ahb_reg_saved.misc_cfg = sci_glb_read(REG_AP_AHB_MISC_CFG, -1UL);
+ } else{
+ sci_glb_write(REG_AP_AHB_AHB_EB, ap_ahb_reg_saved.ahb_eb, -1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg & (~0x7), -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg & (~0x7), -1UL);
+#else
+ sci_glb_write(REG_AP_AHB_CA7_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg & (~0x7), -1UL);
+#endif
+ for(i = 0; i < 20; i++);
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg, -1UL);
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg, -1UL);
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#else
+ sci_glb_write(REG_AP_AHB_CA7_CKG_DIV_CFG, ap_ahb_reg_saved.ca7_div_cfg, -1UL);
+ sci_glb_write(REG_AP_AHB_CA7_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#endif
+ for(i = 0; i < 20; i++);
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#else
+ sci_glb_write(REG_AP_AHB_CA7_CKG_SEL_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#endif
+ sci_glb_write(REG_AP_AHB_OTG_PHY_TUNE, ap_ahb_reg_saved.usb_phy_tune, -1UL);
+#else
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#else
+ sci_glb_write(REG_AP_AHB_CA7_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg & (~0x7), -1UL);
+#endif
+ for(i = 0; i < 20; i++);
+ //sci_glb_write(REG_AP_AHB_CA7_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_write(REG_AP_AHB_APCPU_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#else
+ sci_glb_write(REG_AP_AHB_CA7_CKG_CFG, ap_ahb_reg_saved.ca7_ckg_cfg, -1UL);
+#endif
+#endif
+ sci_glb_write(REG_AP_AHB_MISC_CKG_EN, ap_ahb_reg_saved.misc_ckg_en, -1UL);
+ sci_glb_write(REG_AP_AHB_MISC_CFG, ap_ahb_reg_saved.misc_cfg, -1UL);
+ }
+ return;
+}
+
+void disable_apb_module(void)
+{
+ int stat;
+ stat = sci_glb_read(REG_AP_APB_APB_EB, -1UL);
+ stat &=(0xf<<19 | BIT_UART1_EB | BIT_UART0_EB); // leave intc on
+ sci_glb_write(REG_AP_APB_APB_EB, stat, -1UL);
+ return;
+}
+void bak_restore_apb(int bak)
+{
+ if(bak){
+ ap_apb_reg_saved.apb_eb = sci_glb_read(REG_AP_APB_APB_EB, -1UL);
+ ap_apb_reg_saved.apb_misc_ctrl = sci_glb_read(REG_AP_APB_APB_MISC_CTRL, -1UL);
+#if !defined(CONFIG_ARCH_SCX35L)
+#if !defined(CONFIG_ARCH_SCX20)
+ ap_apb_reg_saved.usb_phy_tune = sci_glb_read(REG_AP_APB_USB_PHY_TUNE, -1UL);
+#endif //#if !defined(CONFIG_ARCH_SCX20)
+#endif
+ }else{
+ sci_glb_write(REG_AP_APB_APB_EB, ap_apb_reg_saved.apb_eb, -1UL);
+ sci_glb_write(REG_AP_APB_APB_MISC_CTRL, ap_apb_reg_saved.apb_misc_ctrl, -1UL);
+#if !defined(CONFIG_ARCH_SCX35L)
+#if !defined(CONFIG_ARCH_SCX20)
+ sci_glb_write(REG_AP_APB_USB_PHY_TUNE, ap_apb_reg_saved.usb_phy_tune, -1UL);
+#endif //#if !defined(CONFIG_ARCH_SCX20)
+#endif
+ }
+ return;
+}
+#if defined(CONFIG_ARCH_SCX15)
+extern void __iomap_page(unsigned long virt, unsigned long size, int enable);
+void bak_restore_mm_scx15(int bak)
+{
+ sci_glb_set(REG_AON_APB_APB_EB0, BIT_MM_EB);
+ __iomap_page(REGS_MM_AHB_BASE, SZ_4K, 1);
+ if(bak){
+ mm_reg_saved.mm_cfg1= sci_glb_read(SPRD_MMAHB_BASE, -1UL);
+ mm_reg_saved.mm_cfg2 = sci_glb_read(SPRD_MMAHB_BASE + 0x8, -1UL);
+ }else{
+ sci_glb_write(SPRD_MMAHB_BASE, mm_reg_saved.mm_cfg1, -1UL);
+ sci_glb_write(SPRD_MMAHB_BASE + 0x8, mm_reg_saved.mm_cfg2, -1UL);
+ }
+ __iomap_page(REGS_MM_AHB_BASE, SZ_4K, 0);
+ sci_glb_clr(REG_AON_APB_APB_EB0, BIT_MM_EB);
+ return;
+}
+#endif
+static void bak_ap_clk_reg(int bak)
+{
+ volatile u32 i;
+ if(bak) {
+ ap_clk_reg_saved.ap_ahb_cfg = sci_glb_read(REG_AP_CLK_AP_AHB_CFG , -1UL);
+ ap_clk_reg_saved.ap_apb_cfg = sci_glb_read(REG_AP_CLK_AP_APB_CFG , -1UL);
+ ap_clk_reg_saved.clk_gsp_cfg = sci_glb_read(REG_AP_CLK_GSP_CFG , -1UL);
+ ap_clk_reg_saved.dispc0_cfg = sci_glb_read(REG_AP_CLK_DISPC0_CFG , -1UL);
+ ap_clk_reg_saved.dispc0_dbi_cfg = sci_glb_read(REG_AP_CLK_DISPC0_DBI_CFG , -1UL);
+ ap_clk_reg_saved.dispc0_dpi_cfg = sci_glb_read(REG_AP_CLK_DISPC0_DPI_CFG , -1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ ap_clk_reg_saved.nfc_cfg = sci_glb_read(REG_AP_CLK_NANDC_ECC_CFG , -1UL);
+#else
+ ap_clk_reg_saved.dispc1_cfg = sci_glb_read(REG_AP_CLK_DISPC1_CFG , -1UL);
+ ap_clk_reg_saved.dispc1_dbi_cfg = sci_glb_read(REG_AP_CLK_DISPC1_DBI_CFG , -1UL);
+ ap_clk_reg_saved.dispc1_dpi_cfg = sci_glb_read(REG_AP_CLK_DISPC1_DPI_CFG , -1UL);
+ ap_clk_reg_saved.nfc_cfg = sci_glb_read(REG_AP_CLK_NFC_CFG , -1UL);
+#endif
+ ap_clk_reg_saved.sdio0_cfg = sci_glb_read(REG_AP_CLK_SDIO0_CFG , -1UL);
+ ap_clk_reg_saved.sdio1_cfg = sci_glb_read(REG_AP_CLK_SDIO1_CFG , -1UL);
+ ap_clk_reg_saved.sdio2_cfg = sci_glb_read(REG_AP_CLK_SDIO2_CFG , -1UL);
+ ap_clk_reg_saved.emmc_cfg = sci_glb_read(REG_AP_CLK_EMMC_CFG , -1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ ap_clk_reg_saved.usb_ref_cfg = sci_glb_read(REG_AP_CLK_OTG_REF_CFG , -1UL);
+#else
+ ap_clk_reg_saved.gps_cfg = sci_glb_read(REG_AP_CLK_GPS_CFG , -1UL);
+ ap_clk_reg_saved.gps_tcxo_cfg = sci_glb_read(REG_AP_CLK_GPS_TCXO_CFG , -1UL);
+ ap_clk_reg_saved.usb_ref_cfg = sci_glb_read(REG_AP_CLK_USB_REF_CFG , -1UL);
+#endif
+ ap_clk_reg_saved.uart0_cfg = sci_glb_read(REG_AP_CLK_UART0_CFG , -1UL);
+ ap_clk_reg_saved.uart1_cfg = sci_glb_read(REG_AP_CLK_UART1_CFG , -1UL);
+ ap_clk_reg_saved.uart2_cfg = sci_glb_read(REG_AP_CLK_UART2_CFG , -1UL);
+ ap_clk_reg_saved.uart3_cfg = sci_glb_read(REG_AP_CLK_UART3_CFG , -1UL);
+ ap_clk_reg_saved.uart4_cfg = sci_glb_read(REG_AP_CLK_UART4_CFG , -1UL);
+ ap_clk_reg_saved.i2c0_cfg = sci_glb_read(REG_AP_CLK_I2C0_CFG , -1UL);
+ ap_clk_reg_saved.i2c1_cfg = sci_glb_read(REG_AP_CLK_I2C1_CFG , -1UL);
+ ap_clk_reg_saved.i2c2_cfg = sci_glb_read(REG_AP_CLK_I2C2_CFG , -1UL);
+ ap_clk_reg_saved.i2c3_cfg = sci_glb_read(REG_AP_CLK_I2C3_CFG , -1UL);
+ ap_clk_reg_saved.i2c4_cfg = sci_glb_read(REG_AP_CLK_I2C4_CFG , -1UL);
+ ap_clk_reg_saved.spi0_cfg = sci_glb_read(REG_AP_CLK_SPI0_CFG , -1UL);
+ ap_clk_reg_saved.spi1_cfg = sci_glb_read(REG_AP_CLK_SPI1_CFG , -1UL);
+ ap_clk_reg_saved.spi2_cfg = sci_glb_read(REG_AP_CLK_SPI2_CFG , -1UL);
+ ap_clk_reg_saved.iis0_cfg = sci_glb_read(REG_AP_CLK_IIS0_CFG , -1UL);
+ ap_clk_reg_saved.iis1_cfg = sci_glb_read(REG_AP_CLK_IIS1_CFG , -1UL);
+ ap_clk_reg_saved.iis2_cfg = sci_glb_read(REG_AP_CLK_IIS2_CFG , -1UL);
+ ap_clk_reg_saved.iis3_cfg = sci_glb_read(REG_AP_CLK_IIS3_CFG , -1UL);
+ }
+ else {
+ sci_glb_write(REG_AP_CLK_AP_AHB_CFG , ap_clk_reg_saved.ap_ahb_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_AP_APB_CFG , ap_clk_reg_saved.ap_apb_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_GSP_CFG , ap_clk_reg_saved.clk_gsp_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_DISPC0_CFG , ap_clk_reg_saved.dispc0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC0_CFG , ap_clk_reg_saved.dispc0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_DISPC0_DBI_CFG , ap_clk_reg_saved.dispc0_dbi_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC0_DBI_CFG , ap_clk_reg_saved.dispc0_dbi_cfg ,-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC0_DPI_CFG , ap_clk_reg_saved.dispc0_dpi_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC0_DPI_CFG , ap_clk_reg_saved.dispc0_dpi_cfg ,-1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ sci_glb_write(REG_AP_CLK_NANDC_ECC_CFG , ap_clk_reg_saved.nfc_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_NANDC_ECC_CFG , ap_clk_reg_saved.nfc_cfg ,-1UL);
+#else
+ sci_glb_write(REG_AP_CLK_DISPC1_CFG , ap_clk_reg_saved.dispc1_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC1_CFG , ap_clk_reg_saved.dispc1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_DISPC1_DBI_CFG , ap_clk_reg_saved.dispc1_dbi_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC1_DBI_CFG , ap_clk_reg_saved.dispc1_dbi_cfg ,-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC1_DPI_CFG , ap_clk_reg_saved.dispc1_dpi_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_DISPC1_DPI_CFG , ap_clk_reg_saved.dispc1_dpi_cfg ,-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_NFC_CFG , ap_clk_reg_saved.nfc_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_NFC_CFG , ap_clk_reg_saved.nfc_cfg ,-1UL);
+#endif
+ sci_glb_write(REG_AP_CLK_SDIO0_CFG , ap_clk_reg_saved.sdio0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_SDIO0_CFG , ap_clk_reg_saved.sdio0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_SDIO1_CFG , ap_clk_reg_saved.sdio1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_SDIO2_CFG , ap_clk_reg_saved.sdio2_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_EMMC_CFG , ap_clk_reg_saved.emmc_cfg ,-1UL);
+#if defined(CONFIG_ARCH_SCX35L)
+ sci_glb_write(REG_AP_CLK_OTG_REF_CFG , ap_clk_reg_saved.usb_ref_cfg ,-1UL);
+#else
+ sci_glb_write(REG_AP_CLK_GPS_CFG , ap_clk_reg_saved.gps_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_GPS_TCXO_CFG , ap_clk_reg_saved.gps_tcxo_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_USB_REF_CFG , ap_clk_reg_saved.usb_ref_cfg ,-1UL);
+#endif
+ sci_glb_write(REG_AP_CLK_UART0_CFG , ap_clk_reg_saved.uart0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_UART0_CFG , ap_clk_reg_saved.uart0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_UART1_CFG , ap_clk_reg_saved.uart1_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_UART1_CFG , ap_clk_reg_saved.uart1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_UART2_CFG , ap_clk_reg_saved.uart2_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_UART2_CFG , ap_clk_reg_saved.uart2_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_UART3_CFG , ap_clk_reg_saved.uart3_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_UART3_CFG , ap_clk_reg_saved.uart3_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_UART4_CFG , ap_clk_reg_saved.uart4_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_UART4_CFG , ap_clk_reg_saved.uart4_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_I2C0_CFG , ap_clk_reg_saved.i2c0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_I2C0_CFG , ap_clk_reg_saved.i2c0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_I2C1_CFG , ap_clk_reg_saved.i2c1_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_I2C1_CFG , ap_clk_reg_saved.i2c1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_I2C2_CFG , ap_clk_reg_saved.i2c2_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_I2C2_CFG , ap_clk_reg_saved.i2c2_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_I2C3_CFG , ap_clk_reg_saved.i2c3_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_I2C3_CFG , ap_clk_reg_saved.i2c3_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_I2C4_CFG , ap_clk_reg_saved.i2c4_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_I2C4_CFG , ap_clk_reg_saved.i2c4_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_SPI0_CFG , ap_clk_reg_saved.spi0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_SPI0_CFG , ap_clk_reg_saved.spi0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_SPI1_CFG , ap_clk_reg_saved.spi1_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_SPI1_CFG , ap_clk_reg_saved.spi1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_SPI2_CFG , ap_clk_reg_saved.spi2_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_SPI2_CFG , ap_clk_reg_saved.spi2_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_IIS0_CFG , ap_clk_reg_saved.iis0_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_IIS0_CFG , ap_clk_reg_saved.iis0_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_IIS1_CFG , ap_clk_reg_saved.iis1_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_IIS1_CFG , ap_clk_reg_saved.iis1_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_IIS2_CFG , ap_clk_reg_saved.iis2_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_IIS2_CFG , ap_clk_reg_saved.iis2_cfg ,-1UL);
+ sci_glb_write(REG_AP_CLK_IIS3_CFG , ap_clk_reg_saved.iis3_cfg & (~0x3),-1UL);
+ for(i = 0; i < 10; i++);
+ sci_glb_write(REG_AP_CLK_IIS3_CFG , ap_clk_reg_saved.iis3_cfg ,-1UL);
+ }
+}
+void disable_aon_module(void)
+{
+ //sci_glb_clr(REG_AON_APB_APB_EB0, BIT_CA7_DAP_EB | BIT_GPU_EB);
+ //sci_glb_clr(REG_AON_APB_APB_EB0, BIT_CA7_DAP_EB);
+
+ sci_glb_clr(REG_AON_APB_APB_EB0, BIT_AON_TMR_EB | BIT_AP_TMR0_EB);
+ sci_glb_clr(REG_AON_APB_APB_EB1, BIT_AP_TMR2_EB | BIT_AP_TMR1_EB);
+ sci_glb_clr(REG_AON_APB_APB_EB1, BIT_DISP_EMC_EB);
+}
+void bak_restore_aon(int bak)
+{
+ static uint32_t apb_eb1, pwr_ctl, apb_eb0;
+ if(bak){
+ apb_eb0 = sci_glb_read(REG_AON_APB_APB_EB0, -1UL);
+ apb_eb1 = sci_glb_read(REG_AON_APB_APB_EB1, -1UL);
+ pwr_ctl = sci_glb_read(REG_AON_APB_PWR_CTRL, -1UL);
+ }else{
+ if(apb_eb1 & BIT_DISP_EMC_EB)
+ sci_glb_set(REG_AON_APB_APB_EB1, BIT_DISP_EMC_EB);
+ sci_glb_write(REG_AON_APB_APB_EB0, apb_eb0, -1UL);
+ sci_glb_write(REG_AON_APB_APB_EB1, apb_eb1, -1UL);
+ }
+ return;
+}
+
+void disable_ana_module(void)
+{
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ sci_adi_set(ANA_REG_GLB_LDO_PD_CTRL, BIT_LDO_SD_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD | BIT_DCDC_WPA_PD);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ sci_adi_set(ANA_REG_GLB_LDO_PD_CTRL, BIT_LDO_SDIO_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD | BIT_DCDC_WPA_PD);
+#endif
+#if defined(CONFIG_ADIE_SC2723)
+ sci_adi_set(ANA_REG_GLB_LDO_PD_CTRL, BIT_LDO_SDIO_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD | BIT_LDO_SDCORE_PD | BIT_LDO_WIFIPA_PD | BIT_DCDC_CON_PD | BIT_DCDC_WPA_PD);
+#endif
+}
+void bak_restore_ana(int bak)
+{
+ static uint32_t ldo_pd_ctrl;
+ static uint32_t mask;
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ mask = BIT_LDO_SD_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD | BIT_DCDC_WPA_PD;
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ mask = BIT_LDO_SDIO_PD | BIT_LDO_SIM0_PD | BIT_LDO_SIM1_PD | BIT_LDO_SIM2_PD | BIT_LDO_CAMA_PD |\
+ BIT_LDO_CAMD_PD | BIT_LDO_CAMIO_PD | BIT_LDO_CAMMOT_PD | BIT_DCDC_WPA_PD;
+#endif
+
+ if(bak){
+ ldo_pd_ctrl = sci_adi_read(ANA_REG_GLB_LDO_PD_CTRL);
+ }else{
+ sci_adi_write(ANA_REG_GLB_LDO_PD_CTRL, ldo_pd_ctrl, mask);
+ }
+ return;
+}
+static void bak_restore_pub(int bak)
+{
+ /*v0 not set auto power down*/
+ if (soc_is_scx35_v0()) {
+ return ;
+ }
+ if(bak) {
+ pub_reg_saved.ddr_qos_cfg1 = sci_glb_read(REG_PUB_APB_DDR_QOS_CFG1, -1UL);
+ pub_reg_saved.ddr_qos_cfg2 = sci_glb_read(REG_PUB_APB_DDR_QOS_CFG2, -1UL);
+ pub_reg_saved.ddr_qos_cfg3 = sci_glb_read(REG_PUB_APB_DDR_QOS_CFG3, -1UL);
+ } else {
+ sci_glb_write(REG_PUB_APB_DDR_QOS_CFG1, pub_reg_saved.ddr_qos_cfg1, -1UL);
+ sci_glb_write(REG_PUB_APB_DDR_QOS_CFG2, pub_reg_saved.ddr_qos_cfg2, -1UL);
+ sci_glb_write(REG_PUB_APB_DDR_QOS_CFG3, pub_reg_saved.ddr_qos_cfg3, -1UL);
+ }
+}
+
+static void bak_restore_ap_intc(int bak)
+{
+ static u32 intc0_eb, intc1_eb, intc2_eb,intc3_eb;
+ if(bak) {
+ intc0_eb = sci_glb_read(SPRD_INTC0_BASE + 0x8, -1UL);
+ intc1_eb = sci_glb_read(SPRD_INTC1_BASE + 0x8, -1UL);
+ intc2_eb = sci_glb_read(SPRD_INTC2_BASE + 0x8, -1UL);
+ intc3_eb = sci_glb_read(SPRD_INTC3_BASE + 0x8, -1UL);
+ } else {
+ sci_glb_write(SPRD_INTC0_BASE + 0x8, intc0_eb, -1UL);
+ sci_glb_write(SPRD_INTC1_BASE + 0x8, intc1_eb, -1UL);
+ sci_glb_write(SPRD_INTC2_BASE + 0x8, intc2_eb, -1UL);
+ sci_glb_write(SPRD_INTC3_BASE + 0x8, intc3_eb, -1UL);
+ }
+}
+
+#define REG_PIN_XTLEN ( SPRD_PIN_BASE + 0x0138 )
+#define REG_PIN_CHIP_SLEEP ( SPRD_PIN_BASE + 0x0208 )
+#define REG_PIN_XTL_BUF_EN0 ( SPRD_PIN_BASE + 0x020C )
+#define REG_PIN_XTL_BUF_EN1 ( SPRD_PIN_BASE + 0x0210 )
+#define REG_PIN_XTL_BUF_EN2 ( SPRD_PIN_BASE + 0x0214 )
+void show_pin_reg(void)
+{
+ sci_glb_set(SPRD_INT_BASE + 0x8, BIT(14) | BIT(4)); //ana & eic
+ printk("REG_PIN_XTLEN 0x%08x\n", sci_glb_read(REG_PIN_XTLEN, -1UL));
+ printk("REG_PIN_XTL_BUF_EN0 0x%08x\n", sci_glb_read(REG_PIN_XTL_BUF_EN0, -1UL));
+ printk("REG_PIN_XTL_BUF_EN1 0x%08x\n", sci_glb_read(REG_PIN_XTL_BUF_EN1, -1UL));
+ printk("REG_PIN_XTL_BUF_EN2 0x%08x\n", sci_glb_read(REG_PIN_XTL_BUF_EN2, -1UL));
+ printk("REG_PIN_CHIP_SLEEP 0x%08x\n", sci_glb_read(REG_PIN_CHIP_SLEEP, -1UL));
+ printk("### uart1 ckd 0x%08x\n", sci_glb_read(SPRD_UART1_BASE + 0X24, -1UL));
+ printk("### uart1 ctl 0x%08x\n", sci_glb_read(SPRD_UART1_BASE + 0X18, -1UL));
+#if defined(CONFIG_ARCH_SCX15)
+ sci_glb_set(REG_PMU_APB_XTL0_REL_CFG, 0x4);
+ sci_glb_set(REG_PMU_APB_XTLBUF0_REL_CFG, 0x4);
+#if !defined(CONFIG_ARCH_SCX35L)
+ sci_glb_clr(REG_PMU_APB_PD_CP1_TD_CFG, BIT(24));
+#endif /* CONFIG_ARCH_SCX35L */
+#endif
+ printk("REG_PMU_APB_XTL0_REL_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_XTL0_REL_CFG, -1UL));
+ printk("REG_PMU_APB_XTL1_REL_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_XTL1_REL_CFG, -1UL));
+#if !defined(CONFIG_ARCH_SCX35L)
+ printk("REG_PMU_APB_XTL2_REL_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_XTL2_REL_CFG, -1UL));
+#endif
+ printk("REG_PMU_APB_XTLBUF0_REL_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_XTLBUF0_REL_CFG, -1UL));
+ printk("REG_PMU_APB_XTLBUF1_REL_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_XTLBUF1_REL_CFG, -1UL));
+#if !defined(CONFIG_ARCH_SCX35L)
+ printk("REG_PMU_APB_PD_CP1_TD_CFG 0x%08x\n", sci_glb_read(REG_PMU_APB_PD_CP1_TD_CFG, -1Ul));
+#endif
+}
+void force_mcu_core_sleep(void)
+{
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_CORE_SLEEP);
+}
+void enable_mcu_deep_sleep(void)
+{
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_DEEP_SLEEP_EN | BIT_MCU_LIGHT_SLEEP_EN);
+}
+void disable_mcu_deep_sleep(void)
+{
+ sci_glb_clr(REG_AP_AHB_MCU_PAUSE, BIT_MCU_DEEP_SLEEP_EN | BIT_MCU_LIGHT_SLEEP_EN);
+}
+#define BITS_SET_CHECK(__reg, __bits, __string) do{\
+ uint32_t mid =sci_glb_read(__reg, __bits); \
+ if(mid != __bits) \
+ printk(__string " not 1" "\n"); \
+ }while(0)
+#define BITS_CLEAR_CHECK(__reg, __bits, __string) do{\
+ uint32_t mid = sci_glb_read(__reg, __bits); \
+ if(mid & __bits) \
+ printk(__string " not 0" "\n"); \
+ }while(0)
+#define PRINT_REG(__reg) do{\
+ uint32_t mid = sci_glb_read(__reg, -1UL); \
+ printk(#__reg "value 0x%x\n", mid); \
+ }while(0)
+void show_reg_status(void)
+{
+ //BITS_CLEAR_CHECK(REG_AON_APB_APB_EB0, BIT_CA7_DAP_EB, "ca7_dap_eb");
+#if defined(CONFIG_ARCH_SCX35LT8)
+ /*BITS_CLEAR_CHECK(REG_AON_APB_APB_EB0, BIT_DAP_CA53_CCI_EN, "ca7_dap_eb");*/
+#else
+ BITS_CLEAR_CHECK(REG_AON_APB_APB_EB0, BIT_CA7_DAP_EB, "ca7_dap_eb");
+#endif
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_DMA_EB, "dma_eb");
+ BITS_CLEAR_CHECK((SPRD_DMA0_BASE + 0x1c), BIT(20), "dma_busy");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_USB_EB, "usb_eb");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_SDIO0_EB, "sdio0_eb");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_SDIO1_EB, "sdio1_eb");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_SDIO2_EB, "sdio2_eb");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_EMMC_EB, "emmc_eb");
+ BITS_CLEAR_CHECK(REG_AP_AHB_AHB_EB, BIT_NFC_EB, "nfc_eb");
+ PRINT_REG(REG_PMU_APB_SLEEP_STATUS);
+}
+uint32_t pwr_stat0=0, pwr_stat1=0, pwr_stat2=0, pwr_stat3=0, apb_eb0=0, apb_eb1=0, ahb_eb=0, apb_eb=0, mcu_pause=0, sys_force_sleep=0, sys_auto_sleep_cfg=0;
+uint32_t ldo_slp_ctrl0, ldo_slp_ctrl1, ldo_slp_ctrl2, xtl_wait_ctrl, ldo_slp_ctrl3, ldo_slp_ctrl4, ldo_aud_ctrl4;
+uint32_t mm_apb, ldo_pd_ctrl, arm_module_en;
+uint32_t cp_slp_status_dbg0, cp_slp_status_dbg1, sleep_ctrl, ddr_sleep_ctrl, sleep_status, pwr_ctrl, ca7_standby_status;
+uint32_t pd_pub_sys;
+#if defined(CONFIG_ARCH_SCX15)
+uint32_t ldo_dcdc_pd_ctrl;
+uint32_t xtl0_rel_cfg, xtl1_rel_cfg, xtl2_rel_cfg, xtlbuf0_rel_cfg, xtlbuf1_rel_cfg;
+uint32_t mpll_rel_cfg, dpll_rel_cfg, tdpll_rel_cfg, wpll_rel_cfg, cpll_rel_cfg, wifipll1_rel_cfg, wifipll2_rel_cfg;
+uint32_t ddr_chn_sleep_ctrl0, ddr_chn_sleep_ctrl1;
+#endif
+#if defined(CONFIG_ARCH_SCX35L)
+extern void cp0_power_domain_debug(void);
+extern void cp1_power_domain_debug(void);
+#endif
+
+void bak_last_reg(void)
+{
+#if defined(CONFIG_ARCH_SCX35L)
+ cp0_power_domain_debug();
+ cp1_power_domain_debug();
+#endif
+ pd_pub_sys = __raw_readl(REG_PMU_APB_PD_PUB_SYS_CFG);
+ cp_slp_status_dbg0 = __raw_readl(REG_PMU_APB_CP_SLP_STATUS_DBG0);
+#if !defined(CONFIG_ARCH_SCX35L)
+ cp_slp_status_dbg1 = __raw_readl(REG_PMU_APB_CP_SLP_STATUS_DBG1);
+#endif
+ pwr_stat0 = __raw_readl(REG_PMU_APB_PWR_STATUS0_DBG);
+ pwr_stat1 = __raw_readl(REG_PMU_APB_PWR_STATUS1_DBG);
+ pwr_stat2 = __raw_readl(REG_PMU_APB_PWR_STATUS2_DBG);
+#if !defined(CONFIG_ARCH_SCX35L)
+ pwr_stat3 = __raw_readl(REG_PMU_APB_PWR_STATUS3_DBG);
+#endif
+ sleep_ctrl = __raw_readl(REG_PMU_APB_SLEEP_CTRL);
+ ddr_sleep_ctrl = __raw_readl(REG_PMU_APB_DDR_SLEEP_CTRL);
+ sleep_status = __raw_readl(REG_PMU_APB_SLEEP_STATUS);
+
+#if defined(CONFIG_ARCH_SCX15)
+ xtl0_rel_cfg = __raw_readl(REG_PMU_APB_XTL0_REL_CFG);
+ xtl1_rel_cfg = __raw_readl(REG_PMU_APB_XTL1_REL_CFG);
+ xtl2_rel_cfg = __raw_readl(REG_PMU_APB_XTL2_REL_CFG);
+ xtlbuf0_rel_cfg = __raw_readl(REG_PMU_APB_XTLBUF0_REL_CFG);
+ xtlbuf1_rel_cfg = __raw_readl(REG_PMU_APB_XTLBUF1_REL_CFG);
+ mpll_rel_cfg = __raw_readl(REG_PMU_APB_MPLL_REL_CFG);
+ dpll_rel_cfg = __raw_readl(REG_PMU_APB_DPLL_REL_CFG);
+ tdpll_rel_cfg = __raw_readl(REG_PMU_APB_TDPLL_REL_CFG);
+ wpll_rel_cfg = __raw_readl(REG_PMU_APB_WPLL_REL_CFG);
+ cpll_rel_cfg = __raw_readl(REG_PMU_APB_CPLL_REL_CFG);
+ wifipll1_rel_cfg = __raw_readl(REG_PMU_APB_WIFIPLL1_REL_CFG);
+ wifipll2_rel_cfg = __raw_readl(REG_PMU_APB_WIFIPLL2_REL_CFG);
+ ddr_chn_sleep_ctrl0 = __raw_readl(REG_PMU_APB_DDR_CHN_SLEEP_CTRL0);
+ ddr_chn_sleep_ctrl1 = __raw_readl(REG_PMU_APB_DDR_CHN_SLEEP_CTRL1);
+#endif
+
+ apb_eb0 = __raw_readl(REG_AON_APB_APB_EB0);
+ apb_eb1 = __raw_readl(REG_AON_APB_APB_EB1);
+ pwr_ctrl = __raw_readl(REG_AON_APB_PWR_CTRL);
+
+ ahb_eb = __raw_readl(REG_AP_AHB_AHB_EB);
+
+ apb_eb = __raw_readl(REG_AP_APB_APB_EB);
+ mcu_pause = __raw_readl(REG_AP_AHB_MCU_PAUSE);
+ sys_force_sleep = __raw_readl(REG_AP_AHB_AP_SYS_FORCE_SLEEP_CFG);
+ sys_auto_sleep_cfg = __raw_readl(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG);
+ //ca7_standby_status = __raw_readl(REG_AP_AHB_CA7_STANDBY_STATUS);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ ca7_standby_status = __raw_readl(REG_AP_AHB_APCPU_STANDBY_STATUS);
+#else
+ ca7_standby_status = __raw_readl(REG_AP_AHB_CA7_STANDBY_STATUS);
+#endif
+
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ ldo_slp_ctrl0 = sci_adi_read(ANA_REG_GLB_LDO_SLP_CTRL0);
+ ldo_slp_ctrl1 = sci_adi_read(ANA_REG_GLB_LDO_SLP_CTRL1);
+ ldo_slp_ctrl2 = sci_adi_read(ANA_REG_GLB_LDO_SLP_CTRL2);
+ ldo_slp_ctrl3 = sci_adi_read(ANA_REG_GLB_LDO_SLP_CTRL3);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ ldo_slp_ctrl0 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL0);
+ ldo_slp_ctrl1 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL1);
+ ldo_slp_ctrl2 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL2);
+ ldo_slp_ctrl3 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL3);
+#endif
+#if defined(CONFIG_ADIE_SC2723)
+ ldo_slp_ctrl0 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL0);
+ ldo_slp_ctrl1 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL1);
+ ldo_slp_ctrl2 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL2);
+ ldo_slp_ctrl3 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL3);
+ ldo_slp_ctrl4 = sci_adi_read(ANA_REG_GLB_PWR_SLP_CTRL4);
+#endif
+
+#if defined(CONFIG_ARCH_SCX15)
+#else
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ ldo_aud_ctrl4 = sci_adi_read(ANA_REG_GLB_AUD_SLP_CTRL4);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ ldo_aud_ctrl4 = sci_adi_read(ANA_REG_GLB_AUD_SLP_CTRL);
+#endif
+#if defined(CONFIG_ADIE_SC2723)
+ ldo_aud_ctrl4 = sci_adi_read(ANA_REG_GLB_AUD_SLP_CTRL);
+#endif
+#endif
+ xtl_wait_ctrl = sci_adi_read(ANA_REG_GLB_XTL_WAIT_CTRL);
+#if defined(CONFIG_ARCH_SCX15)
+ ldo_dcdc_pd_ctrl = sci_adi_read(ANA_REG_GLB_LDO_DCDC_PD);
+#endif
+ ldo_pd_ctrl = sci_adi_read(ANA_REG_GLB_LDO_PD_CTRL);
+ arm_module_en = sci_adi_read(ANA_REG_GLB_ARM_MODULE_EN);
+}
+void print_last_reg(void)
+{
+ printk("aon pmu status reg\n");
+ printk("REG_PMU_APB_PD_PUB_SYS_CFG ------ 0x%08x\n", pd_pub_sys);
+ printk("REG_PMU_APB_PD_MM_TOP_CFG ------ 0x%08x\n",
+ sci_glb_read(REG_PMU_APB_PD_MM_TOP_CFG, -1UL) );
+ printk("REG_PMU_APB_PD_AP_SYS_CFG ------ 0x%08x\n",
+ sci_glb_read(REG_PMU_APB_PD_AP_SYS_CFG, -1UL) );
+#ifdef REG_PMU_APB_PD_AP_DISP_CFG
+ printk("REG_PMU_APB_PD_AP_DISP_CFG ------ 0x%08x\n",
+ sci_glb_read(REG_PMU_APB_PD_AP_DISP_CFG, -1UL) );
+#endif
+
+#if defined(CONFIG_ARCH_SCX30G)
+ printk("REG_PMU_APB_PD_DDR_PUBL_CFG ------ 0x%08x\n",
+ sci_glb_read(REG_PMU_APB_PD_DDR_PUBL_CFG, -1UL) );
+ printk("REG_PMU_APB_PD_DDR_PHY_CFG ------ 0x%08x\n",
+ sci_glb_read(REG_PMU_APB_PD_DDR_PHY_CFG, -1UL) );
+#endif
+ printk("REG_PMU_APB_CP_SLP_STATUS_DBG0 ----- 0x%08x\n", cp_slp_status_dbg0);
+#if !defined(CONFIG_ARCH_SCX35L)
+ printk("REG_PMU_APB_CP_SLP_STATUS_DBG1 ----- 0x%08x\n", cp_slp_status_dbg1);
+#endif
+ printk("REG_PMU_APB_PWR_STATUS0_DBG ----- 0x%08x\n", pwr_stat0);
+ printk("REG_PMU_APB_PWR_STATUS1_DBG ----- 0x%08x\n", pwr_stat1);
+ printk("REG_PMU_APB_PWR_STATUS2_DBG ----- 0x%08x\n", pwr_stat2);
+#if !defined(CONFIG_ARCH_SCX35L)
+ printk("REG_PMU_APB_PWR_STATUS3_DBG ----- 0x%08x\n", pwr_stat3);
+#endif
+ printk("REG_PMU_APB_SLEEP_CTRL ----- 0x%08x\n", sleep_ctrl);
+ printk("REG_PMU_APB_DDR_SLEEP_CTRL ----- 0x%08x\n", ddr_sleep_ctrl);
+ printk("REG_PMU_APB_SLEEP_STATUS ----- 0x%08x\n", sleep_status);
+#if defined(CONFIG_ARCH_SCX15)
+ printk("REG_PMU_APB_XTL0_REL_CFG ----- 0x%08x\n", xtl0_rel_cfg);
+ printk("REG_PMU_APB_XTL1_REL_CFG ----- 0x%08x\n", xtl1_rel_cfg);
+ printk("REG_PMU_APB_XTL2_REL_CFG ----- 0x%08x\n", xtl2_rel_cfg);
+ printk("REG_PMU_APB_XTLBUF0_REL_CFG ----- 0x%08x\n", xtlbuf0_rel_cfg);
+ printk("REG_PMU_APB_XTLBUF1_REL_CFG ----- 0x%08x\n", xtlbuf1_rel_cfg);
+ printk("REG_PMU_APB_MPLL_REL_CFG ----- 0x%08x\n", mpll_rel_cfg);
+ printk("REG_PMU_APB_DPLL_REL_CFG ----- 0x%08x\n", dpll_rel_cfg);
+ printk("REG_PMU_APB_TDPLL_REL_CFG ----- 0x%08x\n", tdpll_rel_cfg);
+ printk("REG_PMU_APB_WPLL_REL_CFG ----- 0x%08x\n", wpll_rel_cfg);
+ printk("REG_PMU_APB_CPLL_REL_CFG ----- 0x%08x\n", cpll_rel_cfg);
+ printk("REG_PMU_APB_WIFIPLL1_REL_CFG ----- 0x%08x\n", wifipll1_rel_cfg);
+ printk("REG_PMU_APB_WIFIPLL2_REL_CFG ----- 0x%08x\n", wifipll2_rel_cfg);
+ printk("REG_PMU_APB_DDR_CHN_SLEEP_CTRL0 ----- 0x%08x\n", ddr_chn_sleep_ctrl0);
+ printk("REG_PMU_APB_DDR_CHN_SLEEP_CTRL1 ----- 0x%08x\n", ddr_chn_sleep_ctrl1);
+#endif
+
+ printk("aon apb reg\n");
+ printk("REG_AON_APB_APB_EB0 ----- 0x%08x\n", apb_eb0);
+ printk("REG_AON_APB_APB_EB1 ----- 0x%08x\n", apb_eb1);
+ printk("REG_AON_APB_PWR_CTRL ----- 0x%08x\n", pwr_ctrl);
+ printk("REG_AON_APB_BB_BG_CTRL ------ 0x%08x\n",
+ sci_glb_read(REG_AON_APB_BB_BG_CTRL, -1UL) );
+
+ printk("ap ahb reg \n");
+ printk("REG_AP_AHB_AHB_EB ----- 0x%08x\n", ahb_eb);
+
+ printk("ap apb reg\n");
+ printk("REG_AP_APB_APB_EB ---- 0x%08x\n", apb_eb);
+ printk("REG_AP_AHB_MCU_PAUSE --- 0x%08x\n", mcu_pause);
+ printk("REG_AP_AHB_AP_SYS_FORCE_SLEEP_CFG --- 0x%08x\n", sys_force_sleep);
+ printk("REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG ---- 0x%08x\n", sys_auto_sleep_cfg);
+ printk("REG_AP_AHB_CA7_STANDBY_STATUS ---- 0x%08x\n", ca7_standby_status);
+
+ printk("ana reg \n");
+ printk("ANA_REG_GLB_LDO_SLP_CTRL0 --- 0x%08x\n", ldo_slp_ctrl0);
+ printk("ANA_REG_GLB_LDO_SLP_CTRL1 --- 0x%08x\n", ldo_slp_ctrl1);
+ printk("ANA_REG_GLB_LDO_SLP_CTRL2 --- 0x%08x\n", ldo_slp_ctrl2);
+ printk("ANA_REG_GLB_LDO_SLP_CTRL3 --- 0x%08x\n", ldo_slp_ctrl3);
+ printk("ANA_REG_GLB_AUD_SLP_CTRL4 --- 0x%08x\n", ldo_aud_ctrl4);
+ printk("ANA_REG_GLB_XTL_WAIT_CTRL --- 0x%08x\n", xtl_wait_ctrl);
+
+ printk("ANA_REG_GLB_PWR_XTL_EN0 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN0));
+ printk("ANA_REG_GLB_PWR_XTL_EN1 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN1));
+ printk("ANA_REG_GLB_PWR_XTL_EN2 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN2));
+ printk("ANA_REG_GLB_PWR_XTL_EN3 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN3));
+#if !defined(CONFIG_ADIE_SC2723) && !defined(CONFIG_ADIE_SC2723S)
+ printk("ANA_REG_GLB_PWR_XTL_EN4 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN4));
+#endif
+#if !defined(CONFIG_ARCH_SCX15) && !defined(CONFIG_ADIE_SC2723) && !defined(CONFIG_ADIE_SC2723S)
+ printk("ANA_REG_GLB_PWR_XTL_EN5 -- 0x%08x\n", sci_adi_read(ANA_REG_GLB_PWR_XTL_EN5));
+#endif
+ printk("mm reg\n");
+ printk("REG_MM_AHB_AHB_EB ---- 0x%08x\n", mm_apb);
+
+ printk("ana reg\n");
+#if defined(CONFIG_ARCH_SCX15)
+ printk("ANA_REG_GLB_LDO_DCDC_PD --- 0x%08x\n", ldo_dcdc_pd_ctrl);
+#endif
+ printk("ANA_REG_GLB_LDO_PD_CTRL --- 0x%08x\n", ldo_pd_ctrl);
+ printk("ANA_REG_GLB_ARM_MODULE_EN --- 0x%08x\n", arm_module_en);
+}
+#if 0
+static void test_setup_timer(int load)
+{
+ //AP_TMR0_EB
+ sci_glb_set(REG_AON_APB_APB_EB0, BIT(12));
+
+ //AP_TMR0_RTC_EB
+ sci_glb_set(REG_AON_APB_APB_RTC_EB, BIT(5));
+
+ //load value
+ sci_glb_write(SPRD_APTIMER0_BASE, load, -1UL);
+
+ //int en
+ sci_glb_set(SPRD_APTIMER0_BASE + 0xc, BIT(0));
+
+
+ //AP_TMR0_RTC_EB --- TIMER_INT_EN timer0 INTC0 en
+ sci_glb_set(SPRD_INT_BASE + 0x8, BIT(2) | BIT(29));
+
+ //int en
+ sci_glb_set(SPRD_APTIMER0_BASE + 0x8, BIT(7));
+
+ sci_glb_write(SPRD_INT_BASE + 0x8, 0xffffffff, -1UL);
+ return;
+}
+#endif
+void check_ldo(void)
+{
+}
+
+void check_pd(void)
+{
+}
+
+unsigned int sprd_irq_pending(void)
+{
+ uint32_t bits = 0;
+ bits = sci_glb_read(SPRD_INT_BASE, -1UL);
+ if(bits)
+ return 1;
+ else
+ return 0;
+}
+
+/*copy code for deepsleep return */
+#define SAVED_VECTOR_SIZE 64
+static uint32_t *sp_pm_reset_vector = NULL;
+static uint32_t saved_vector[SAVED_VECTOR_SIZE];
+void __iomem *iram_start;
+struct emc_repower_param *repower_param;
+
+
+#define SPRD_RESET_VECTORS 0X00000000
+#define SLEEP_RESUME_CODE_PHYS 0X400
+#define SLEEP_CODE_SIZE 0x800
+#define SPRD_IRAM0_PHYS 0x0
+
+extern unsigned long reg_aon_apb_eb0_vir;
+extern unsigned long reg_aon_apb_eb0_phy;
+extern unsigned long reg_uart1_enable_vir;
+extern unsigned long reg_uart1_enable_phy;
+
+static int init_reset_vector(void)
+{
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ sp_pm_reset_vector = (u32 *)SPRD_IRAM0_BASE;
+
+ reg_aon_apb_eb0_vir = SPRD_AONAPB_BASE;
+ reg_aon_apb_eb0_phy = SPRD_AONAPB_PHYS;
+ reg_uart1_enable_vir = SPRD_APBREG_BASE;
+ reg_uart1_enable_phy = SPRD_APBREG_PHYS;
+
+ iram_start = (void __iomem *)(SPRD_IRAM0_BASE + SLEEP_RESUME_CODE_PHYS);
+ /* copy sleep code to (IRAM). */
+ if ((sc8830_standby_iram_end - sc8830_standby_iram) > SLEEP_CODE_SIZE) {
+ panic("##: code size is larger than expected, need more memory!\n");
+ }
+ memcpy_toio(iram_start, sc8830_standby_iram, SLEEP_CODE_SIZE);
+
+
+ /* just make sure*/
+ flush_cache_all();
+ outer_flush_all();
+ sp_pm_reset_vector[65] = virt_to_phys(sp_pm_collapse_exit);
+#endif
+ return 0;
+}
+void save_reset_vector(void)
+{
+ int i = 0;
+ for (i = 0; i < SAVED_VECTOR_SIZE; i++)
+ saved_vector[i] = sp_pm_reset_vector[i];
+}
+
+void set_reset_vector(void)
+{
+ int i = 0;
+ printk("SAVED_VECTOR_SIZE 0x%x\n", SAVED_VECTOR_SIZE);
+ for (i = 0; i < SAVED_VECTOR_SIZE; i++)
+ sp_pm_reset_vector[i] = 0xe320f000; /* nop*/
+
+ sp_pm_reset_vector[SAVED_VECTOR_SIZE - 2] = 0xE51FF004; /* ldr pc, 4 */
+
+ sp_pm_reset_vector[SAVED_VECTOR_SIZE - 1] = (sc8830_standby_exit_iram -
+ sc8830_standby_iram + SLEEP_RESUME_CODE_PHYS); /* place v7_standby_iram here */
+}
+
+#ifdef CONFIG_DDR_VALIDITY_TEST
+#include <linux/slab.h>
+static unsigned long *vtest = NULL;
+static unsigned long *ptest = NULL;
+static void test_memory(void)
+{
+ int i;
+#ifndef CONFIG_ARCH_SCX30G
+ vtest = kmalloc(64*1024, GFP_KERNEL);
+ if (vtest) {
+ for (i = 0; i < (64*1024/4); i++) {
+ vtest[i] = 0x12345678;
+ }
+#else
+ vtest = kmalloc(2 * sizeof(int), GFP_KERNEL);
+ if (vtest) {
+ vtest[0] = 0x12345678;
+#endif
+ printk("%s %p %p\n", __func__, vtest, virt_to_phys(vtest));
+ ptest = virt_to_phys(vtest);
+ } else {
+ printk("error kmalloc\n");
+ }
+ sp_pm_reset_vector[64] = ptest;
+}
+#endif
+
+void restore_reset_vector(void)
+{
+ int i;
+ for (i = 0; i < SAVED_VECTOR_SIZE; i++)
+ sp_pm_reset_vector[i] = saved_vector[i];
+}
+/* irq functions */
+#define hw_raw_irqs_disabled_flags(flags) \
+({ \
+ (int)((flags) & PSR_I_BIT); \
+})
+
+#define hw_irqs_disabled() \
+({ \
+ unsigned long _flags; \
+ local_irq_save(_flags); \
+ hw_raw_irqs_disabled_flags(_flags); \
+})
+
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+u32 __attribute__ ((naked)) read_cpsr(void)
+{
+ __asm__ __volatile__("mrs r0, cpsr\nbx lr");
+}
+#endif
+/* make sure printk is end, if not maybe some messy code in SERIAL1 output */
+#define UART_TRANSFER_REALLY_OVER (0x1UL << 15)
+#define UART_STS0 (SPRD_UART1_BASE + 0x08)
+#define UART_STS1 (SPRD_UART1_BASE + 0x0c)
+
+static __used void wait_until_uart1_tx_done(void)
+{
+ u32 tx_fifo_val;
+ u32 really_done = 0;
+ u32 timeout = 2000;
+
+ tx_fifo_val = __raw_readl(UART_STS1);
+ tx_fifo_val >>= 8;
+ tx_fifo_val &= 0xff;
+ while(tx_fifo_val != 0) {
+ if (timeout <= 0) break;
+ udelay(100);
+ tx_fifo_val = __raw_readl(UART_STS1);
+ tx_fifo_val >>= 8;
+ tx_fifo_val &= 0xff;
+ timeout--;
+ }
+
+ timeout = 30;
+ really_done = __raw_readl(UART_STS0);
+ while(!(really_done & UART_TRANSFER_REALLY_OVER)) {
+ if (timeout <= 0) break;
+ udelay(100);
+ really_done = __raw_readl(UART_STS0);
+ timeout--;
+ }
+}
+#define SAVE_GLOBAL_REG do{ \
+ bak_restore_apb(1); \
+ bak_ap_clk_reg(1); \
+ bak_restore_ahb(1); \
+ bak_restore_aon(1); \
+ bak_restore_pub(1); \
+ bak_restore_ap_intc(1);\
+ }while(0)
+#define RESTORE_GLOBAL_REG do{ \
+ bak_restore_apb(0); \
+ bak_ap_clk_reg(0); \
+ bak_restore_aon(0); \
+ bak_restore_ahb(0); \
+ bak_restore_pub(0); \
+ bak_restore_ap_intc(0);\
+ }while(0)
+
+/* arm core sleep*/
+static void arm_sleep(void)
+{
+ cpu_do_idle();
+ hard_irq_set();
+}
+
+/* arm core + arm sys */
+static void mcu_sleep(void)
+{
+ SAVE_GLOBAL_REG;
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_SYS_SLEEP_EN);
+ cpu_do_idle();
+ sci_glb_clr(REG_AP_AHB_MCU_PAUSE, BIT_MCU_SYS_SLEEP_EN);
+ hard_irq_set();
+ RESTORE_GLOBAL_REG;
+}
+
+static void light_sleep(void)
+{
+ sci_glb_set(REG_AP_AHB_MCU_PAUSE, BIT_MCU_LIGHT_SLEEP_EN);
+ cpu_do_idle();
+ sci_glb_clr(REG_AP_AHB_MCU_PAUSE, BIT_MCU_LIGHT_SLEEP_EN);
+}
+void int_work_round(void)
+{
+ //sci_glb_set(SPRD_AONAPB_BASE + 0x8, (0x1<<30 | 1<<8 /*| 1<<1*/));
+ //sci_glb_clr(SPRD_LPDDR2_PHY_BASE + 0x2c, BIT(4));
+ //sci_glb_set(SPRD_LPDDR2_PHY_BASE + 0x2c, BIT(4));
+ //sci_glb_write(SPRD_LPDDR2_BASE + 0x30, 0, -1UL);
+ //sci_glb_set(SPRD_PMU_BASE + 0xa8, 1<<1);
+ //sci_adi_clr(ANA_EIC_BASE + 0x18, 0x20);
+}
+void show_deep_reg_status(void)
+{
+ printk("PWR_STATUS0_DBG 0x%08x\n", sci_glb_read(REG_PMU_APB_PWR_STATUS0_DBG, -1UL));
+ printk("PWR_STATUS1_DBG 0x%08x\n", sci_glb_read(REG_PMU_APB_PWR_STATUS1_DBG, -1UL));
+ printk("PWR_STATUS2_DBG 0x%08x\n", sci_glb_read(REG_PMU_APB_PWR_STATUS2_DBG, -1UL));
+#if !defined(CONFIG_ARCH_SCX35L)
+ printk("PWR_STATUS3_DBG 0x%08x\n", sci_glb_read(REG_PMU_APB_PWR_STATUS3_DBG, -1UL));
+#endif /* CONFIG_ARCH_SCX35L */
+}
+
+
+#if defined(CONFIG_MACH_SC9620OPENPHONE)
+void cp0_sys_power_domain_close(void)
+{
+ sci_glb_set(REG_PMU_APB_PD_CP0_SYS_CFG, BIT_CP0_FORCE_DEEP_SLEEP);//enable cp0 force sleep
+}
+
+void cp0_sys_power_domain_open(void)
+{
+ sci_glb_set(REG_PMU_APB_CP_SOFT_RST, BIT_CP0_SOFT_RST);//reset cp0
+ sci_glb_clr(REG_PMU_APB_PD_CP0_SYS_CFG, BIT_CP0_FORCE_DEEP_SLEEP);//close cp0 force sleep
+ mdelay(2);
+ sci_glb_clr(REG_PMU_APB_CP_SOFT_RST, BIT_CP0_SOFT_RST);//release cp0
+}
+#endif
+
+extern void pm_debug_set_wakeup_timer(void);
+extern void pm_debug_set_apwdt(void);
+typedef u32 (*iram_standby_entry_ptr)(u32,u32);
+static int sc_sleep_call(unsigned long flag)
+{
+ u32 ret = 0;
+ struct mm_struct *mm = current->active_mm;
+
+ iram_standby_entry_ptr func_ptr;
+ cpu_switch_mm(init_mm.pgd, &init_mm);
+ func_ptr = (iram_standby_entry_ptr)(SLEEP_RESUME_CODE_PHYS + (u32)sp_pm_collapse - (u32)sc8830_standby_iram);
+ ret = (func_ptr)(0, flag);
+ cpu_switch_mm(mm->pgd, mm);
+
+ return ret;
+}
+
+int deep_sleep(int from_idle)
+{
+ int ret = 0;
+ static unsigned int cnt = 0;
+
+ if(!from_idle){
+ SAVE_GLOBAL_REG;
+ /* some prepare here */
+#if defined(CONFIG_ARCH_SCX15)
+ bak_restore_mm_scx15(1);
+#endif
+ show_pin_reg();
+ enable_mcu_deep_sleep();
+ configure_for_deepsleep(0);
+ disable_ahb_module();
+ //disable_pmu_ddr_module();
+
+ //sci_glb_set(SPRD_PMU_BASE+0x00F4, 0x3FF);
+
+ disable_dma();
+ //disable_mm();
+ //disable_ana_module();
+ disable_aon_module();
+ show_reg_status();
+ bak_last_reg();
+ print_last_reg();
+ print_int_status();
+ //wait_until_uart1_tx_done();
+ int_work_round();
+ //pm_debug_set_apwdt();
+ disable_apb_module();
+ //pm_debug_set_wakeup_timer();
+ //force_mcu_core_sleep();
+ //bak_last_reg();
+
+#if defined(CONFIG_ARCH_SCX20L)
+ __raw_writel(0x20, REG_ARM7_AHB_RF_AP_COMM_CTL);
+ /*for pikeL, AP can't read/write ARM7 register when ARM7 sleep.
+ * so, disable ARM7 BUS sleep when AP wake, enable when AP sleep*/
+ sci_glb_set(REG_AON_APB_ARM7_CFG_BUS, BIT_ARM7_CFG_BUS_SLEEP);
+#else
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ __raw_writel(0x0, REG_PMU_APB_CA7_C0_CFG);
+#endif
+#endif
+ show_deep_reg_status();
+ } else {
+ /* __raw_writel(0x0, REG_PMU_APB_CA7_C0_CFG); */
+ }
+ /*
+ * sp_pm_collapse(param0, param1)
+ * param0, param1 are not used before
+ * so we use second param to distinguish idle deep or real deep
+ */
+#define dmc_retention_func (SPRD_IRAM1_BASE + 0x1800)
+#define dmc_retention_para_vaddr (SPRD_IRAM1_BASE + 0x2400)
+
+#ifdef CONFIG_ARCH_SCX20
+ /* set auto-self refresh mode */
+ sci_glb_clr(SPRD_LPDDR2_BASE+0x124, BIT(0)| BIT(1));
+ sci_glb_set(SPRD_LPDDR2_BASE+0X124, BIT(2));
+#else
+#if defined(CONFIG_ARCH_SCX30G) || defined(CONFIG_ARCH_SCX35L) || defined(CONFIG_ARCH_SCX35L64) || defined(CONFIG_ARCH_SCX35LT8)
+ /* set auto-self refresh mode */
+ sci_glb_clr(SPRD_LPDDR2_BASE+0x30, BIT(1));
+ sci_glb_set(SPRD_LPDDR2_BASE+0x30, BIT(0));
+#if defined(CONFIG_ARCH_SCX30G)
+ *(volatile unsigned int*)(SPRD_IRAM1_BASE+0x1800 + 0xc00 + 0x0c) = SPRD_PUB_BASE;
+ *(volatile unsigned int*)(SPRD_IRAM1_BASE+0x1800 + 0xc00 + 0x10) = SPRD_LPDDR2_BASE;
+ *(volatile unsigned int*)(SPRD_IRAM1_BASE+0x1800 + 0xc00 + 0x14) = SPRD_LPDDR2_PHY_BASE;
+ ((void (*)(unsigned long,unsigned long))(dmc_retention_func))(1,dmc_retention_para_vaddr);
+#endif
+#endif
+#endif
+#if defined(CONFIG_MACH_SC9620OPENPHONE)
+ cp0_sys_power_domain_close();
+#endif
+#if defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8)
+ ret = cpu_suspend(5);
+ ret = (ret ? 0 : 1);
+#else
+ ret = sc_sleep_call(from_idle);
+#endif
+#if defined(CONFIG_MACH_SC9620OPENPHONE)
+ cp0_sys_power_domain_open();
+#endif
+
+#if defined(CONFIG_ARCH_SCX20L)
+ sci_glb_clr(REG_AON_APB_ARM7_CFG_BUS, BIT_ARM7_CFG_BUS_SLEEP);
+#endif
+
+#ifdef CONFIG_ARCH_SCX20
+ /* set auto powerdown mode */
+ sci_glb_set(SPRD_LPDDR2_BASE+0x124, BIT(0)| BIT(1));
+ sci_glb_clr(SPRD_LPDDR2_BASE+0x124, BIT(2));
+#else
+#if defined(CONFIG_ARCH_SCX30G) || defined(CONFIG_ARCH_SCX35L) || defined(CONFIG_ARCH_SCX35L64) || defined(CONFIG_ARCH_SCX35LT8)
+ /* set auto powerdown mode */
+ sci_glb_set(SPRD_LPDDR2_BASE+0x30, BIT(1));
+ sci_glb_clr(SPRD_LPDDR2_BASE+0x30, BIT(0));
+#endif
+#endif
+
+ udelay(50);
+
+
+ if(!from_idle){
+#if defined(CONFIG_ARCH_SCX20L)
+ __raw_writel(0x30, REG_ARM7_AHB_RF_AP_COMM_CTL);
+#else
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ __raw_writel(0x1, REG_PMU_APB_CA7_C0_CFG);
+#endif
+#endif
+ printk("ret %d not from idle\n", ret);
+ if(ret){
+#if defined(CONFIG_DDR_VALIDITY_TEST) && defined(CONFIG_ARCH_SCX30G)
+ printk("DDR test: read times: %ld\n", *(vtest + 1));
+#endif
+ printk("deep sleep %u times\n", cnt);
+ cnt++;
+ }
+ sci_glb_set(REG_AP_APB_APB_EB, 0xf<<19);
+ hard_irq_set();
+ sci_glb_clr(REG_AP_APB_APB_EB, 0xf<<19);
+ disable_mcu_deep_sleep();
+ configure_for_deepsleep(1);
+ //sci_glb_clr(SPRD_PMU_BASE+0x00F4, 0x3FF);
+ RESTORE_GLOBAL_REG;
+#if defined(CONFIG_ARCH_SCX15)
+ bak_restore_mm_scx15(0);
+#endif
+ } else {
+ /* __raw_writel(0x1, REG_PMU_APB_CA7_C0_CFG); */
+ pr_debug("ret %d from idle\n", ret);
+ }
+
+ udelay(5);
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ if (ret) cpu_init();
+#endif
+
+ if (soc_is_scx35_v0())
+ //sci_glb_clr(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG,BIT_CA7_CORE_AUTO_GATE_EN);
+#if defined(CONFIG_ARCH_SCX35LT8)
+ sci_glb_clr(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG,BIT_CA53_CORE_AUTO_GATE_EN);
+#else
+ sci_glb_clr(REG_AP_AHB_AP_SYS_AUTO_SLEEP_CFG,BIT_CA7_CORE_AUTO_GATE_EN);
+#endif
+
+ return ret;
+}
+
+#define DEVICE_AHB (0x1UL << 20)
+#define DEVICE_APB (0x1UL << 21)
+#define DEVICE_VIR (0x1UL << 22)
+#define DEVICE_AWAKE (0x1UL << 23)
+#define LIGHT_SLEEP (0x1UL << 24)
+#define DEVICE_TEYP_MASK (DEVICE_AHB | DEVICE_APB | DEVICE_VIR | DEVICE_AWAKE | LIGHT_SLEEP)
+
+int sprd_cpu_deep_sleep(unsigned int cpu)
+{
+ int status, ret = 0;
+ unsigned long flags, time;
+
+#ifdef CONFIG_SPRD_PM_DEBUG
+ __raw_writel(0xfdffbfff, SPRD_INTC0_BASE + 0xc);//intc0
+ __raw_writel(0x02004000, SPRD_INTC0_BASE + 0x8);//intc0
+ __raw_writel(0xffffffff, SPRD_INTC0_BASE + 0x100c);//intc1
+#endif
+
+ time = get_sys_cnt();
+ if (!hw_irqs_disabled()) {
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ flags = read_cpsr();
+#endif
+ printk("##: Error(%s): IRQ is enabled(%08lx)!\n",
+ "wakelock_suspend", flags);
+ }
+ /*TODO:
+ * we need to known clock status in modem side
+ */
+#ifdef FORCE_DISABLE_DSP
+ status = 0;
+#else
+ /*
+ * TODO: get clock status in native version, force deep sleep now
+ */
+ status = 0;
+#endif
+ if (status & DEVICE_AHB) {
+ printk("###### %s, DEVICE_AHB ###\n", __func__ );
+ set_sleep_mode(SLP_MODE_ARM);
+ arm_sleep();
+ } else if (status & DEVICE_APB) {
+ printk("###### %s, DEVICE_APB ###\n", __func__ );
+ set_sleep_mode(SLP_MODE_MCU);
+ mcu_sleep();
+ } else if (status & LIGHT_SLEEP) {
+ printk("###### %s, DEVICE_APB ###\n", __func__ );
+ set_sleep_mode(SLP_MODE_LIT);
+ light_sleep();
+ } else {
+ /*printk("###### %s, DEEP ###\n", __func__ );*/
+ set_sleep_mode(SLP_MODE_DEP);
+#if 1
+
+ ret = deep_sleep(0);
+#else
+ //pm_debug_set_wakeup_timer();
+ ret = 0;
+ arm_sleep();
+#endif
+ flush_cache_all();
+ }
+
+ time_add(get_sys_cnt() - time, ret);
+ print_hard_irq_inloop(ret);
+
+ return ret;
+}
+static void init_gr(void){}
+void sc_default_idle(void)
+{
+ cpu_do_idle();
+ local_irq_enable();
+ return;
+}
+
+/*config dcdc core deep sleep voltage*/
+static void dcdc_core_ds_config(void)
+{
+ u32 dcdc_core_ctl_adi = 0;
+ u32 val = 0;
+ u32 dcdc_core_ctl_ds = -1;
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+#ifdef CONFIG_ARCH_SCX30G
+ static struct dcdc_core_ds_step_info step_info[5]={
+ {0, 0,0, 0},
+ {0, 3,0, 5},
+ {0, 6,0,10},
+ {0, 9,0, 0},
+ {0,12,0, 5}
+ };
+ step_info[0].ctl_reg = ANA_REG_GLB_MP_PWR_CTRL1;
+ step_info[1].ctl_reg = ANA_REG_GLB_MP_PWR_CTRL1;
+ step_info[2].ctl_reg = ANA_REG_GLB_MP_PWR_CTRL1;
+ step_info[3].ctl_reg = ANA_REG_GLB_MP_PWR_CTRL1;
+ step_info[4].ctl_reg = ANA_REG_GLB_MP_PWR_CTRL1;
+ step_info[0].cal_reg = ANA_REG_GLB_MP_PWR_CTRL2;
+ step_info[1].cal_reg = ANA_REG_GLB_MP_PWR_CTRL2;
+ step_info[2].cal_reg = ANA_REG_GLB_MP_PWR_CTRL2;
+ step_info[3].cal_reg = ANA_REG_GLB_MP_PWR_CTRL3;
+ step_info[4].cal_reg = ANA_REG_GLB_MP_PWR_CTRL3;
+
+ static u8 dcdc_core_down_volt[]={4,1,1,2,3,5,0,6};
+ static u8 dcdc_core_up_volt[]={6,2,3,4,0,1,7,7};
+ u32 dcdc_core_cal_adi,i;
+ /*1100,700,800,900,1000,650,1200,1300*/
+ static u32 step_ratio[]={10,10,6,3,3};
+ dcdc_core_ctl_adi = (sci_adi_read(ANA_REG_GLB_MP_MISC_CTRL) >> 3) & 0x7;
+ if((ana_chip_id == 0x2713ca00)||(ana_chip_id == 0x2723a000)) {
+ dcdc_core_ctl_ds = dcdc_core_ctl_adi;
+ } else {
+ dcdc_core_ctl_ds = dcdc_core_down_volt[dcdc_core_ctl_adi];
+ }
+ printk("ana_chip_id:%x, dcdc_core_ctl_adi = %d, dcdc_core_ctl_ds = %d\n"
+ ,ana_chip_id, dcdc_core_ctl_adi, dcdc_core_ctl_ds);
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL0);
+#endif
+ val &= ~0x7;
+ val |= dcdc_core_ctl_ds;
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL, val, 0xffff);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL0, val, 0xffff);
+#endif
+
+ if(dcdc_core_ctl_ds < dcdc_core_ctl_adi){
+ dcdc_core_cal_adi = sci_adi_read(ANA_REG_GLB_DCDC_CORE_ADI) & 0x1F;
+ /*last step must equel function mode */
+ sci_adi_write(step_info[4].ctl_reg,dcdc_core_ctl_adi<<step_info[4].ctl_sht,0x07 << step_info[4].ctl_sht);
+ sci_adi_write(step_info[4].cal_reg,dcdc_core_cal_adi<<step_info[4].cal_sht,0x1F << step_info[4].cal_sht);
+
+ for(i=0;i<4;i++) {
+ val = dcdc_core_cal_adi + step_ratio[i];
+ if(val <= 0x1F) {
+ sci_adi_write(step_info[i].ctl_reg,dcdc_core_ctl_ds<<step_info[i].ctl_sht,0x07<<step_info[i].ctl_sht);
+ sci_adi_write(step_info[i].cal_reg,val<<step_info[i].cal_sht,0x1F << step_info[i].cal_sht);
+ dcdc_core_cal_adi = val;
+ } else {
+ sci_adi_write(step_info[i].ctl_reg,dcdc_core_up_volt[dcdc_core_ctl_ds]<<step_info[i].ctl_sht,
+ 0x07 << step_info[i].ctl_sht);
+ sci_adi_write(step_info[i].cal_reg,(val-0x1F)<<step_info[i].cal_sht,0x1F << step_info[i].cal_sht);
+ dcdc_core_ctl_ds = dcdc_core_up_volt[dcdc_core_ctl_ds];
+ dcdc_core_cal_adi = val - 0x1F;
+ }
+ }
+ } else {
+ dcdc_core_cal_adi = sci_adi_read(ANA_REG_GLB_DCDC_CORE_ADI) & 0x1F;
+ for(i=0;i<5;i++){
+ sci_adi_write(step_info[i].ctl_reg,dcdc_core_ctl_adi<<step_info[i].ctl_sht,0x07<<step_info[i].ctl_sht);
+ sci_adi_write(step_info[i].cal_reg,dcdc_core_cal_adi<<step_info[i].cal_sht,0x1F<<step_info[i].cal_sht);
+ }
+ }
+#else
+ dcdc_core_ctl_adi = sci_adi_read(ANA_REG_GLB_DCDC_CORE_ADI);
+ dcdc_core_ctl_adi = dcdc_core_ctl_adi >> 0x5;
+ dcdc_core_ctl_adi = dcdc_core_ctl_adi & 0x7;
+ /*only support dcdc_core_ctl_adi 0.9v,1.0v, 1.1v, 1.2v, 1.3v*/
+ switch(dcdc_core_ctl_adi) {
+ case 0://1.1v
+ dcdc_core_ctl_ds = 0x4; //1.0v
+ break;
+ case 4: //1.0v
+ dcdc_core_ctl_ds = 0x3;//0.9v
+ break;
+ case 6: //1.2v
+ dcdc_core_ctl_ds = 0x0;//1.1v
+ break;
+ case 7: //1.3v
+ dcdc_core_ctl_ds = 0x6;//1.2v
+ break;
+ case 3: //0.9v
+ dcdc_core_ctl_ds = 0x2;//0.8v
+ break;
+ case 1: //0.7v
+ case 2: //0.8v
+ case 5: //0.65v
+ //unvalid value
+ break;
+ }
+ printk("dcdc_core_ctl_adi = %d, dcdc_core_ctl_ds = %d\n", dcdc_core_ctl_adi, dcdc_core_ctl_ds);
+ /*valid value*/
+ if(dcdc_core_ctl_ds != -1) {
+#ifndef CONFIG_ARCH_SCX15
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL);
+ val &= ~(0x7);
+ val |= dcdc_core_ctl_ds;
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL, val, 0xffff);
+#endif
+#if defined(CONFIG_ADIE_SC2723S)
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL0);
+ val &= ~(0x7);
+ val |= dcdc_core_ctl_ds;
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL0, val, 0xffff);
+#endif
+#if defined(CONFIG_ADIE_SC2723)
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL1);
+ val &= ~(0xF);
+ val |= dcdc_core_ctl_ds;
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL1, val, 0xffff);
+#endif
+#else
+ val = sci_adi_read(ANA_REG_GLB_DCDC_SLP_CTRL0);
+ val &= ~(0x7 << 4);
+ val |= (dcdc_core_ctl_ds << 4);
+ sci_adi_write(ANA_REG_GLB_DCDC_SLP_CTRL0, val, 0xffff);
+#endif
+ }
+#endif
+#endif
+}
+
+void pm_ana_ldo_config(void)
+{
+#ifdef CONFIG_ARCH_SCX30G
+ ana_chip_id = (sci_adi_read(ANA_REG_GLB_CHIP_ID_HIGH) & 0xFFFF) << 16;
+ ana_chip_id |= (sci_adi_read(ANA_REG_GLB_CHIP_ID_LOW) & 0xFFFF);
+#endif
+
+#if defined(CONFIG_ARCH_SCX15) || defined(CONFIG_ADIE_SC2723)
+ dcdc_core_ds_config();
+#else
+ /*set vddcore deep sleep voltage to 0.9v*/
+ //sci_adi_set(ANA_REG_GLB_DCDC_SLP_CTRL, BITS_DCDC_CORE_CTL_DS(3));
+ dcdc_core_ds_config();
+ /*open vddcore lp VDDMEM, DCDCGEN mode*/
+ //sci_adi_set(ANA_REG_GLB_LDO_SLP_CTRL2, BIT_SLP_DCDCCORE_LP_EN | BIT_SLP_DCDCMEM_LP_EN | BIT_SLP_DCDCGEN_LP_EN);
+ /*open vdd28, vdd18 lp mode*/
+ //sci_adi_set(ANA_REG_GLB_LDO_SLP_CTRL3, BIT_SLP_LDOVDD28_LP_EN | BIT_SLP_LDOVDD18_LP_EN);
+ /*ddr2_buf quiesent curretn set to 4-5uA in deep sleep mode*/
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ sci_adi_clr(ANA_REG_GLB_DDR2_CTRL, BITS_DDR2_BUF_S_DS(0x3));
+#endif
+#endif
+}
+static void init_led(void){}
+
+void sprd_pbint_7s_reset_disable(void)
+{
+ sci_adi_set(ANA_REG_GLB_POR_7S_CTRL, BIT_PBINT_7S_RST_DISABLE);
+}
+
+#ifdef CONFIG_SPRD_EXT_IC_POWER
+// EXT IC should disable otg mode when power off
+ extern void sprd_extic_otg_power(int enable);
+#endif
+
+static void sc8830_power_off(void)
+{
+ u32 reg_val;
+ /*turn off all modules's ldo*/
+
+#ifdef CONFIG_SPRD_EXT_IC_POWER
+ sprd_extic_otg_power(0);
+#endif
+ sci_adi_raw_write(ANA_REG_GLB_LDO_PD_CTRL, 0x1fff);
+
+#if defined(CONFIG_ARCH_SCX15) || defined(CONFIG_ADIE_SC2723) || defined(CONFIG_ADIE_SC2723S)
+ sci_adi_raw_write(ANA_REG_GLB_PWR_WR_PROT_VALUE,BITS_PWR_WR_PROT_VALUE(0x6e7f));
+ do{
+ reg_val = (sci_adi_read(ANA_REG_GLB_PWR_WR_PROT_VALUE) & BIT_PWR_WR_PROT);
+ }while(reg_val == 0);
+ sci_adi_raw_write(ANA_REG_GLB_LDO_PD_CTRL,0xfff);
+ sci_adi_raw_write(ANA_REG_GLB_LDO_DCDC_PD,0x7fff);
+#endif
+
+#if !defined(CONFIG_64BIT)
+#if defined(CONFIG_ADIE_SC2713S) || defined(CONFIG_ADIE_SC2713)
+ /*turn off system core's ldo*/
+ sci_adi_raw_write(ANA_REG_GLB_LDO_DCDC_PD_RTCCLR, 0x0);
+ sci_adi_raw_write(ANA_REG_GLB_LDO_DCDC_PD_RTCSET, 0X7fff);
+#endif
+#endif
+
+}
+
+
+static void sc8830_machine_restart(char mode, const char *cmd)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ arch_reset(mode, cmd);
+
+ mdelay(1000);
+
+ printk("reboot failed!\n");
+
+ while (1);
+}
+void resume_code_remap(void)
+{
+ int ret;
+ ret = ioremap_page_range(SPRD_IRAM0_PHYS, SPRD_IRAM0_PHYS+SZ_8K, SPRD_IRAM0_PHYS, PAGE_KERNEL_EXEC);
+ if(ret){
+ printk("resume_code_remap err %d\n", ret);
+ BUG();
+ }
+}
+void __init sc_pm_init(void)
+{
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ init_reset_vector();
+ resume_code_remap();
+#endif
+ pm_power_off = sc8830_power_off;
+ arm_pm_restart = sc8830_machine_restart;
+ pr_info("power off %pf, restart %pf\n", pm_power_off, arm_pm_restart);
+ init_gr();
+ setup_autopd_mode();
+ pm_ana_ldo_config();
+ init_led();
+ /* disable all sleep mode */
+ sci_glb_clr(REG_AP_AHB_MCU_PAUSE, BIT_MCU_DEEP_SLEEP_EN | BIT_MCU_LIGHT_SLEEP_EN | \
+ BIT_MCU_SYS_SLEEP_EN | BIT_MCU_CORE_SLEEP);
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ set_reset_vector();
+#endif
+#ifdef CONFIG_DDR_VALIDITY_TEST
+ test_memory();
+#endif
+#ifndef CONFIG_SPRD_PM_DEBUG
+ pm_debug_init();
+#endif
+
+ /* enable arm clock auto gating*/
+ //sci_glb_set(REG_AHB_AHB_CTL1, BIT_ARM_AUTO_GATE_EN);
+#ifdef CONFIG_CPU_IDLE
+#ifndef CONFIG_64BIT
+ /* Used to armv7 */
+ sc_cpuidle_init();
+#endif
+#endif
+/*
+ wake_lock_init(&pm_debug_lock, WAKE_LOCK_SUSPEND, "pm_not_ready");
+ wake_lock(&pm_debug_lock);
+*/
+#if defined(CONFIG_SPRD_DEBUG)
+#if !(defined(CONFIG_ARCH_SCX35L64)||defined(CONFIG_ARCH_SCX35LT8))
+ sprd_debug_init();
+#endif
+#endif
+}