aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Zhong <zyw@rock-chips.com>2014-11-07 08:49:33 -0500
committerHeiko Stuebner <heiko@sntech.de>2014-11-10 14:56:42 -0500
commit33aa59c232adf9eb9be2936b9f5dc76850a050c1 (patch)
tree96e20139b650a8cc4eb87580d5c2e89eb55580f3
parentd1f931be7cfb5458d90a4642fda8b4da6b266a84 (diff)
clk: rockchip: rk3288: add suspend and resume
save and restore some clks, which might be changed in suspend. Signed-off-by: Tony Xie <xxx@rock-chips.com> Signed-off-by: Chris Zhong <zyw@rock-chips.com> Reviewed-by: Doug Anderson <dianders@chromium.org> Tested-by: Doug Anderson <dianders@chromium.org> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
-rw-r--r--drivers/clk/rockchip/clk-rk3288.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index bd9534a00737..1a9d03cf2b00 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -16,6 +16,7 @@
16#include <linux/clk-provider.h> 16#include <linux/clk-provider.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/syscore_ops.h>
19#include <dt-bindings/clock/rk3288-cru.h> 20#include <dt-bindings/clock/rk3288-cru.h>
20#include "clk.h" 21#include "clk.h"
21 22
@@ -764,6 +765,64 @@ static const char *rk3288_critical_clocks[] __initconst = {
764 "hclk_peri", 765 "hclk_peri",
765}; 766};
766 767
768#ifdef CONFIG_PM_SLEEP
769static void __iomem *rk3288_cru_base;
770
771/* Some CRU registers will be reset in maskrom when the system
772 * wakes up from fastboot.
773 * So save them before suspend, restore them after resume.
774 */
775static const int rk3288_saved_cru_reg_ids[] = {
776 RK3288_MODE_CON,
777 RK3288_CLKSEL_CON(0),
778 RK3288_CLKSEL_CON(1),
779 RK3288_CLKSEL_CON(10),
780 RK3288_CLKSEL_CON(33),
781 RK3288_CLKSEL_CON(37),
782};
783
784static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)];
785
786static int rk3288_clk_suspend(void)
787{
788 int i, reg_id;
789
790 for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) {
791 reg_id = rk3288_saved_cru_reg_ids[i];
792
793 rk3288_saved_cru_regs[i] =
794 readl_relaxed(rk3288_cru_base + reg_id);
795 }
796 return 0;
797}
798
799static void rk3288_clk_resume(void)
800{
801 int i, reg_id;
802
803 for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) {
804 reg_id = rk3288_saved_cru_reg_ids[i];
805
806 writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000,
807 rk3288_cru_base + reg_id);
808 }
809}
810
811static struct syscore_ops rk3288_clk_syscore_ops = {
812 .suspend = rk3288_clk_suspend,
813 .resume = rk3288_clk_resume,
814};
815
816static void rk3288_clk_sleep_init(void __iomem *reg_base)
817{
818 rk3288_cru_base = reg_base;
819 register_syscore_ops(&rk3288_clk_syscore_ops);
820}
821
822#else /* CONFIG_PM_SLEEP */
823static void rk3288_clk_sleep_init(void __iomem *reg_base) {}
824#endif
825
767static void __init rk3288_clk_init(struct device_node *np) 826static void __init rk3288_clk_init(struct device_node *np)
768{ 827{
769 void __iomem *reg_base; 828 void __iomem *reg_base;
@@ -812,5 +871,6 @@ static void __init rk3288_clk_init(struct device_node *np)
812 ROCKCHIP_SOFTRST_HIWORD_MASK); 871 ROCKCHIP_SOFTRST_HIWORD_MASK);
813 872
814 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); 873 rockchip_register_restart_notifier(RK3288_GLB_SRST_FST);
874 rk3288_clk_sleep_init(reg_base);
815} 875}
816CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); 876CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);