MALI: rockchip: upgrade to DDK r7p0-02rel0.
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / platform / juno_soc / mali_kbase_config_juno_soc.c
1 /*
2  *
3  * (C) COPYRIGHT 2011-2015 ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * A copy of the licence is included with the program, and can also be obtained
11  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12  * Boston, MA  02110-1301, USA.
13  *
14  */
15
16
17
18 #include <linux/ioport.h>
19 #ifdef CONFIG_DEVFREQ_THERMAL
20 #include <linux/devfreq_cooling.h>
21 #endif
22 #include <linux/thermal.h>
23 #include <mali_kbase.h>
24 #include <mali_kbase_defs.h>
25 #include <mali_kbase_config.h>
26 #include <mali_kbase_smc.h>
27
28 /* Versatile Express (VE) Juno Development Platform */
29
30 #define HARD_RESET_AT_POWER_OFF 0
31
32 #ifndef CONFIG_OF
33 static struct kbase_io_resources io_resources = {
34         .job_irq_number = 65,
35         .mmu_irq_number = 66,
36         .gpu_irq_number = 64,
37         .io_memory_region = {
38                              .start = 0x2D000000,
39                              .end = 0x2D000000 + (4096 * 4) - 1}
40 };
41 #endif
42
43 static int pm_callback_power_on(struct kbase_device *kbdev)
44 {
45         /* Nothing is needed on VExpress, but we may have destroyed GPU state (if the below HARD_RESET code is active) */
46         return 1;
47 }
48
49 static void pm_callback_power_off(struct kbase_device *kbdev)
50 {
51 #if HARD_RESET_AT_POWER_OFF
52         /* Cause a GPU hard reset to test whether we have actually idled the GPU
53          * and that we properly reconfigure the GPU on power up.
54          * Usually this would be dangerous, but if the GPU is working correctly it should
55          * be completely safe as the GPU should not be active at this point.
56          * However this is disabled normally because it will most likely interfere with
57          * bus logging etc.
58          */
59         KBASE_TRACE_ADD(kbdev, CORE_GPU_HARD_RESET, NULL, NULL, 0u, 0);
60         kbase_os_reg_write(kbdev, GPU_CONTROL_REG(GPU_COMMAND), GPU_COMMAND_HARD_RESET);
61 #endif
62 }
63
64 struct kbase_pm_callback_conf pm_callbacks = {
65         .power_on_callback = pm_callback_power_on,
66         .power_off_callback = pm_callback_power_off,
67         .power_suspend_callback  = NULL,
68         .power_resume_callback = NULL
69 };
70
71 #ifdef CONFIG_DEVFREQ_THERMAL
72
73 #define FALLBACK_STATIC_TEMPERATURE 55000
74
75 static unsigned long juno_model_static_power(unsigned long voltage)
76 {
77         struct thermal_zone_device *tz;
78         unsigned long temperature, temp;
79         unsigned long temp_squared, temp_cubed, temp_scaling_factor;
80         const unsigned long coefficient = (410UL << 20) / (729000000UL >> 10);
81         const unsigned long voltage_cubed = (voltage * voltage * voltage) >> 10;
82
83         tz = thermal_zone_get_zone_by_name("gpu");
84         if (IS_ERR(tz)) {
85                 pr_warn_ratelimited("Error getting gpu thermal zone (%ld), not yet ready?\n",
86                                 PTR_ERR(tz));
87                 temperature = FALLBACK_STATIC_TEMPERATURE;
88         } else {
89                 int ret;
90
91                 ret = tz->ops->get_temp(tz, &temperature);
92                 if (ret) {
93                         pr_warn_ratelimited("Error reading temperature for gpu thermal zone: %d\n",
94                                         ret);
95                         temperature = FALLBACK_STATIC_TEMPERATURE;
96                 }
97         }
98
99         /* Calculate the temperature scaling factor. To be applied to the
100          * voltage scaled power.
101          */
102         temp = temperature / 1000;
103         temp_squared = temp * temp;
104         temp_cubed = temp_squared * temp;
105         temp_scaling_factor =
106                         (2 * temp_cubed)
107                         - (80 * temp_squared)
108                         + (4700 * temp)
109                         + 32000;
110
111         return (((coefficient * voltage_cubed) >> 20)
112                         * temp_scaling_factor)
113                                 / 1000000;
114 }
115
116 static unsigned long juno_model_dynamic_power(unsigned long freq,
117                 unsigned long voltage)
118 {
119         /* The inputs: freq (f) is in Hz, and voltage (v) in mV.
120          * The coefficient (c) is in mW/(MHz mV mV).
121          *
122          * This function calculates the dynamic power after this formula:
123          * Pdyn (mW) = c (mW/(MHz*mV*mV)) * v (mV) * v (mV) * f (MHz)
124          */
125         const unsigned long v2 = (voltage * voltage) / 1000; /* m*(V*V) */
126         const unsigned long f_mhz = freq / 1000000; /* MHz */
127         const unsigned long coefficient = 3600; /* mW/(MHz*mV*mV) */
128
129         return (coefficient * v2 * f_mhz) / 1000000; /* mW */
130 }
131
132 struct devfreq_cooling_ops juno_model_ops = {
133         .get_static_power = juno_model_static_power,
134         .get_dynamic_power = juno_model_dynamic_power,
135 };
136
137 #endif /* CONFIG_DEVFREQ_THERMAL */
138
139 /*
140  * Juno Secure Mode integration
141  */
142
143 /* SMC Function Numbers */
144 #define JUNO_SMC_SECURE_ENABLE_FUNC  0xff06
145 #define JUNO_SMC_SECURE_DISABLE_FUNC 0xff07
146
147 static int juno_secure_mode_enable(struct kbase_device *kbdev)
148 {
149         u32 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
150
151         if (gpu_id == GPU_ID_MAKE(GPU_ID_PI_T62X, 0, 1, 0) &&
152                         kbdev->reg_start == 0x2d000000) {
153                 /* T62X in SoC detected */
154                 u64 ret = kbase_invoke_smc(SMC_OEN_SIP,
155                         JUNO_SMC_SECURE_ENABLE_FUNC, false,
156                         0, 0, 0);
157                 return ret;
158         }
159
160         return -EINVAL; /* Not supported */
161 }
162
163 static int juno_secure_mode_disable(struct kbase_device *kbdev)
164 {
165         u32 gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
166
167         if (gpu_id == GPU_ID_MAKE(GPU_ID_PI_T62X, 0, 1, 0) &&
168                         kbdev->reg_start == 0x2d000000) {
169                 /* T62X in SoC detected */
170                 u64 ret = kbase_invoke_smc(SMC_OEN_SIP,
171                         JUNO_SMC_SECURE_DISABLE_FUNC, false,
172                         0, 0, 0);
173                 return ret;
174         }
175
176         return -EINVAL; /* Not supported */
177 }
178
179 struct kbase_secure_ops juno_secure_ops = {
180         .secure_mode_enable = juno_secure_mode_enable,
181         .secure_mode_disable = juno_secure_mode_disable,
182 };
183
184 static struct kbase_platform_config versatile_platform_config = {
185 #ifndef CONFIG_OF
186         .io_resources = &io_resources
187 #endif
188 };
189
190 struct kbase_platform_config *kbase_get_platform_config(void)
191 {
192         return &versatile_platform_config;
193 }
194
195 int kbase_platform_early_init(void)
196 {
197         /* Nothing needed at this stage */
198         return 0;
199 }