suspend: rockchip: set the suspend config to ATF
[firefly-linux-kernel-4.4.55.git] / drivers / soc / rockchip / rockchip_pm_config.c
1 /*
2  * Rockchip Generic power configuration support.
3  *
4  * Copyright (c) 2017 ROCKCHIP, Co. Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/arm-smccc.h>
12 #include <linux/bitops.h>
13 #include <linux/cpu.h>
14 #include <linux/of_gpio.h>
15 #include <linux/platform_device.h>
16 #include <linux/regulator/machine.h>
17 #include <linux/rockchip/rockchip_sip.h>
18 #include <linux/suspend.h>
19
20 #define PM_INVALID_GPIO 0xffff
21
22 static const struct of_device_id pm_match_table[] = {
23         { .compatible = "rockchip,pm-rk3399",},
24         { },
25 };
26
27 static int __init pm_config_init(struct platform_device *pdev)
28 {
29         const struct of_device_id *match_id;
30         struct device_node *node;
31         u32 mode_config = 0;
32         u32 wakeup_config = 0;
33         u32 pwm_regulator_config = 0;
34         int gpio_temp[10];
35         u32 sleep_debug_en = 0;
36         u32 apios_suspend = 0;
37         enum of_gpio_flags flags;
38         int i = 0;
39         int length;
40
41         match_id = of_match_node(pm_match_table, pdev->dev.of_node);
42         if (!match_id)
43                 return -ENODEV;
44
45         node = of_find_node_by_name(NULL, "rockchip-suspend");
46
47         if (IS_ERR_OR_NULL(node)) {
48                 dev_err(&pdev->dev, "%s dev node err\n",  __func__);
49                 return -ENODEV;
50         }
51
52         if (of_property_read_u32_array(node,
53                                        "rockchip,sleep-mode-config",
54                                        &mode_config, 1))
55                 dev_warn(&pdev->dev, "not set sleep mode config\n");
56         else
57                 sip_smc_set_suspend_mode(SUSPEND_MODE_CONFIG, mode_config, 0);
58
59         if (of_property_read_u32_array(node,
60                                        "rockchip,wakeup-config",
61                                        &wakeup_config, 1))
62                 dev_warn(&pdev->dev, "not set wakeup-config\n");
63         else
64                 sip_smc_set_suspend_mode(WKUP_SOURCE_CONFIG, wakeup_config, 0);
65
66         if (of_property_read_u32_array(node,
67                                        "rockchip,pwm-regulator-config",
68                                        &pwm_regulator_config, 1))
69                 dev_warn(&pdev->dev, "not set pwm-regulator-config\n");
70         else
71                 sip_smc_set_suspend_mode(PWM_REGULATOR_CONFIG,
72                                          pwm_regulator_config,
73                                          0);
74
75         length = of_gpio_named_count(node, "rockchip,power-ctrl");
76
77         if (length > 0 && length < 10) {
78                 for (i = 0; i < length; i++) {
79                         gpio_temp[i] = of_get_named_gpio_flags(node,
80                                                              "rockchip,power-ctrl",
81                                                              i,
82                                                              &flags);
83                         if (!gpio_is_valid(gpio_temp[i]))
84                                 break;
85                         sip_smc_set_suspend_mode(GPIO_POWER_CONFIG,
86                                                  i,
87                                                  gpio_temp[i]);
88                 }
89         }
90         sip_smc_set_suspend_mode(GPIO_POWER_CONFIG, i, PM_INVALID_GPIO);
91
92         if (!of_property_read_u32_array(node,
93                                         "rockchip,sleep-debug-en",
94                                         &sleep_debug_en, 1))
95                 sip_smc_set_suspend_mode(SUSPEND_DEBUG_ENABLE,
96                                          sleep_debug_en,
97                                          0);
98
99         if (!of_property_read_u32_array(node,
100                                         "rockchip,apios-suspend",
101                                         &apios_suspend, 1))
102                 sip_smc_set_suspend_mode(APIOS_SUSPEND_CONFIG,
103                                          apios_suspend,
104                                          0);
105
106         return 0;
107 }
108
109 static struct platform_driver pm_driver = {
110         .driver = {
111                 .name = "rockchip-pm",
112                 .of_match_table = pm_match_table,
113         },
114 };
115
116 static int __init rockchip_pm_drv_register(void)
117 {
118         return platform_driver_probe(&pm_driver, pm_config_init);
119 }
120 subsys_initcall(rockchip_pm_drv_register);