linux os can config sleep mode
authorxxx <xxx@rock-chips.com>
Tue, 5 May 2015 03:37:20 +0000 (11:37 +0800)
committerxxx <xxx@rock-chips.com>
Tue, 5 May 2015 03:39:44 +0000 (11:39 +0800)
arch/arm64/boot/dts/rk3368.dtsi [changed mode: 0755->0644]
arch/arm64/mach-rockchip/Makefile
arch/arm64/mach-rockchip/pm-rk3368.c [new file with mode: 0644]
include/dt-bindings/suspend/rockchip-rk3368.h [new file with mode: 0644]

old mode 100755 (executable)
new mode 100644 (file)
index 5b51135..6a00feb
@@ -1,5 +1,5 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/suspend/rockchip-pm.h>
+#include <dt-bindings/suspend/rockchip-rk3368.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/sensor-dev.h>
        rockchip_suspend {
                rockchip,ctrbits = <
                        (0
-                        |RKPM_CTR_PWR_DMNS
-                        |RKPM_CTR_GTCLKS
-                        |RKPM_CTR_PLLS
-                        |RKPM_CTR_GPIOS
-                       /*
-                        |RKPM_CTR_SYSCLK_DIV
-                        |RKPM_CTR_IDLEAUTO_MD
-                        |RKPM_CTR_ARMOFF_LPMD
-                       */
-                        |RKPM_CTR_ARMOFF_LOGDP_LPMD
+                       | RKPM_SLP_ARMOFF
+                       | RKPM_SLP_PMU_PLLS_PWRDN
+                       /*| RKPM_SLP_PMU_PMUALIVE_32K
+                       | RKPM_SLP_SFT_PLLS_DEEP
+                       | RKPM_SLP_PMU_DIS_OSC */
+                       | RKPM_SLP_SFT_PD_NBSCUS
                        )
                        >;
-               rockchip,pmic-suspend_gpios = <
-                                /* RKPM_PINGPIO_BITS_OUTPUT(GPIO7_A1,RKPM_GPIO_OUT_H) */
-                       >;
-               rockchip,pmic-resume_gpios = <
-                               /* RKPM_PINGPIO_BITS_FUN(PWM1,RKPM_GPIO_PULL_DN) */
-                       >;
        };
 
        isp: isp@ff910000{
index a07df9bf13cc4827f4c7fb5f7fa44a93c8e1004a..3fab65b04aef05078057053561cbde037366d758 100644 (file)
@@ -4,7 +4,7 @@ obj-y += ../../arm/mach-rockchip/efuse.o
 obj-y += ../../arm/mach-rockchip/pvtm.o
 obj-y += ../../arm/mach-rockchip/rk_system_status.o
 obj-y += ../../arm/mach-rockchip/ddr_freq.o
-obj-$(CONFIG_PM) += ../../arm/mach-rockchip/rockchip_pm.o
+obj-$(CONFIG_PM) += ../../arm/mach-rockchip/rockchip_pm.o pm-rk3368.o
 obj-$(CONFIG_RK_LAST_LOG) += ../../arm/mach-rockchip/last_log.o
 obj-$(CONFIG_DVFS) += ../../arm/mach-rockchip/dvfs.o
 obj-$(CONFIG_BLOCK_RKNAND) += ../../arm/mach-rockchip/rknandbase.o
diff --git a/arch/arm64/mach-rockchip/pm-rk3368.c b/arch/arm64/mach-rockchip/pm-rk3368.c
new file mode 100644 (file)
index 0000000..38bee1d
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright (C) 2015, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony.Xie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <asm/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/compiler.h>
+
+#define PSCI_OS_SUSPEND_CTRBITS        (0xa600ffc0)
+
+#define SEC_REG_RW_SHT (0x0)
+#define SEC_REG_RD (0x0)
+#define SEC_REG_WR (0x1)
+
+#define SEC_REG_BITS_SHT (0x1)
+#define SEC_REG_32 (0x0)
+#define SEC_REG_64 (0x2)
+
+#define SEC_REG_RD_32 (SEC_REG_RD | SEC_REG_32)
+#define SEC_REG_RD_64 (SEC_REG_RD | SEC_REG_64)
+#define SEC_REG_WR_32 (SEC_REG_WR | SEC_REG_32)
+#define SEC_REG_WR_64 (SEC_REG_WR | SEC_REG_64)
+
+/*
+ * arg2: rd/wr control, bit[0] 0-rd 1-rt, bit[1] 0-32bit, 1-64bit
+ * arg1: base addr
+ * arg0: read or write val
+ * function_id: return fail/succes
+ */
+static noinline int __invoke_reg_pm_wr_fn_smc(u64 function_id, u64 arg0, u64 arg1,
+                                        u64 arg2)
+{
+       asm volatile(
+                       __asmeq("%0", "x0")
+                       __asmeq("%1", "x1")
+                       __asmeq("%2", "x2")
+                       __asmeq("%3", "x3")
+                       "smc    #0\n"
+               : "+r" (function_id) ,"+r" (arg0)
+               : "r" (arg1), "r" (arg2));
+
+       return function_id;
+}
+static noinline int __invoke_reg_pm_rd_fn_smc(u64 function_id, u64 arg0, u64 arg1,
+                                        u64 arg2, u64 *val)
+{
+       asm volatile(
+                       __asmeq("%0", "x0")
+                       __asmeq("%1", "x1")
+                       __asmeq("%2", "x2")
+                       __asmeq("%3", "x3")
+                       "smc    #0\n"
+               : "+r" (function_id) ,"+r" (arg0)
+               : "r" (arg1), "r" (arg2));
+
+               *val = arg0;
+
+       return function_id;
+}
+
+static int (*invoke_regs_pm_wr_fn)(u64, u64 , u64, u64) = __invoke_reg_pm_wr_fn_smc;
+static int (*invoke_regs_pm_rd_fn)(u64, u64 , u64, u64, u64 *) = __invoke_reg_pm_rd_fn_smc;
+
+static int pmu_ctlbits_rd_32(u32 *val)
+{
+       u64 val_64;
+       int ret;
+       ret = invoke_regs_pm_rd_fn(PSCI_OS_SUSPEND_CTRBITS, 0, 0, SEC_REG_RD, &val_64);
+       *val = val_64;
+
+       return ret;
+}
+
+static int pmu_ctlbits_wr_32(u32 val)
+{
+       u64 val_64 = val;
+       return invoke_regs_pm_wr_fn(PSCI_OS_SUSPEND_CTRBITS, val_64, 0, SEC_REG_WR);
+}
+
+static int __init  rk3688_suspend_init(void)
+{
+       struct device_node *parent;
+       u32 pm_ctrbits, rd_ctrbits = 0;
+
+       parent = of_find_node_by_name(NULL, "rockchip_suspend");
+
+       if (IS_ERR_OR_NULL(parent)) {
+               printk(KERN_ERR "%s dev node err\n", __func__);
+               return -1;
+       }
+
+       if(of_property_read_u32_array(parent,"rockchip,ctrbits",&pm_ctrbits,1)) {
+           printk(KERN_ERR "%s:get pm ctr error\n",__func__);
+           return -1;
+       }
+
+       pmu_ctlbits_wr_32(pm_ctrbits);
+       pmu_ctlbits_rd_32(&rd_ctrbits);
+
+       if (rd_ctrbits != pm_ctrbits) {
+               printk(KERN_ERR "%s read val error\n", __func__);
+               return 0;
+       }
+
+       printk(KERN_INFO "%s: pm_ctrbits =0x%x\n", __func__, pm_ctrbits);
+
+       return 0;
+}
+
+late_initcall_sync(rk3688_suspend_init);
diff --git a/include/dt-bindings/suspend/rockchip-rk3368.h b/include/dt-bindings/suspend/rockchip-rk3368.h
new file mode 100644 (file)
index 0000000..372ca26
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Header providing constants for Rockchip suspend bindings.
+ *
+ * Copyright (C) 2015, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony.Xie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+#ifndef __DT_BINDINGS_ROCKCHIP_PM_H__
+#define __DT_BINDINGS_ROCKCHIP_PM_H__
+/******************************bits ops************************************/
+
+#define RKPM_SLP_WFI                                   BIT(0)
+#define RKPM_SLP_ARMPD                         BIT(1)
+#define RKPM_SLP_ARMOFF                                BIT(2)
+#define RKPM_SLP_ARMOFF_LOGPD          BIT(3)
+#define RKPM_SLP_ARMOFF_LOGOFF         BIT(4)
+#define RKPM_RUNNING_ARMMODE           BIT(5)
+
+/* func ctrl by pmu auto ctr */
+#define RKPM_SLP_PMU_PLLS_PWRDN        BIT(8) /* all plls except ddr's pll*/
+#define RKPM_SLP_PMU_PMUALIVE_32K      BIT(9)
+#define RKPM_SLP_PMU_DIS_OSC           BIT(10)
+
+/* func ctrl by software set */
+#define RKPM_SLP_SFT_PLLS_DEEP         BIT(16) /* all plls except ddr's pll*/
+#define RKPM_SLP_SFT_32K_EXT           BIT(17)
+#define RKPM_SLP_SFT_PD_PERI           BIT(18)
+#define RKPM_SLP_SFT_PD_NBSCUS         BIT(19) /* noboot scus in muti-cluster */
+#endif