import OT_8063_20170412 mali driver
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / gpu / mt8127 / mali / mali / platform / platform_pmm.c
1
2 #include <linux/mali/mali_utgard.h>
3 #include "mali_kernel_common.h"
4 #include "mali_osk.h"
5 #include "platform_pmm.h"
6 #include <linux/kernel.h>
7 #include <asm/atomic.h>
8 #include "arm_core_scaling.h"
9 #include <linux/clk.h>
10 #include <linux/io.h>
11 #include <linux/regulator/consumer.h>
12
13 #if defined(CONFIG_MALI400_PROFILING)
14 #include "mali_osk_profiling.h"
15 #endif
16
17 #ifdef CONFIG_MALI_DT
18 #include <linux/module.h>
19 #include <linux/clk.h>
20 #include <linux/clk-private.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/of.h>
23 #include <linux/of_address.h>
24 #include <linux/of_platform.h>
25 #include <linux/init.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/platform_device.h>
28 #include <linux/of_irq.h>
29 #include "mt-plat/mt_smi.h"
30 #include <linux/proc_fs.h>
31 #else
32 #include "mach/mt_gpufreq.h"
33 #endif
34
35 /*
36 extern unsigned long (*mtk_thermal_get_gpu_loading_fp) (void);
37 extern unsigned long (*mtk_get_gpu_loading_fp) (void);
38 */
39
40 static int bPoweroff;
41 unsigned int current_sample_utilization;
42
43 extern u32 get_devinfo_with_index(u32 index);
44 static int _need_univpll;
45
46 #ifdef CONFIG_MALI_DT
47
48 /* MFG begin
49 * GPU controller.
50 *
51 * If GPU power domain needs to be enabled after disp, we will break flow
52 * of mfg_enable_gpu to be 2 functions like mfg_prepare/mfg_enable.
53 *
54 * Currently no lock for mfg, Mali driver will take .
55 */
56
57 #define MFG_CG_CON 0x0
58 #define MFG_CG_SET 0x4
59 #define MFG_CG_CLR 0x8
60 #define MFG_DEBUG_SEL 0x180
61 #define MFG_DEBUG_STAT 0x184
62 #define MFG_SPD_MASK 0x80000
63 #define MFG_GPU_QUAL_MASK 0x3
64
65 #define MFG_READ32(r) __raw_readl((void __iomem *)((unsigned long)mfg_start + (r)))
66 #define MFG_WRITE32(v, r) __raw_writel((v), (void __iomem *)((unsigned long)mfg_start + (r)))
67
68 static struct platform_device *mfg_dev;
69 static void __iomem *mfg_start;
70 static void __iomem * scp_start;
71
72 #ifdef CONFIG_OF
73 static const struct of_device_id mfg_dt_ids[] = {
74 {.compatible = "mediatek,mt8127-mfg"},
75 { /* sentinel */ }
76 };
77
78 MODULE_DEVICE_TABLE(of, mfg_dt_ids);
79 #endif
80
81 static int mfg_device_probe(struct platform_device *pdev)
82 {
83
84 /* Make sure disp pm is ready to operate .. */
85 if(!mtk_smi_larb_get_base(0)) {
86 pr_warn("MFG is defer for disp domain ready\n");
87 mfg_dev = NULL;
88 return -EPROBE_DEFER;
89 }else
90 pr_info("MFG domain ready\n");
91
92 mfg_start = of_iomap(pdev->dev.of_node, 0);
93 if (IS_ERR_OR_NULL(mfg_start)) {
94 mfg_start = NULL;
95 goto error_out;
96 }
97 pr_info("MFG start is mapped %p\n", mfg_start);
98
99 pm_runtime_set_autosuspend_delay(&(pdev->dev), 300);
100 pm_runtime_use_autosuspend(&(pdev->dev));
101
102 pm_runtime_enable(&pdev->dev);
103
104 {
105 struct device_node * node;
106 static const struct of_device_id scp_ids[] = {
107 {.compatible = "mediatek,mt8127-scpsys"},
108 { /* sentinel */ }
109 };
110 node = of_find_matching_node(NULL, scp_ids);
111 if (node)
112 scp_start = of_iomap(node, 0);
113 pr_info("MFG scp_start is mapped %p\n", scp_ids);
114 }
115 mfg_dev = pdev;
116 pr_info("MFG device probed done\n");
117 return 0;
118 error_out:
119 if (mfg_start)
120 iounmap(mfg_start);
121 if(scp_start)
122 iounmap(scp_start);
123
124 return -1;
125 }
126
127 static int mfg_device_remove(struct platform_device *pdev)
128 {
129 pm_runtime_disable(&pdev->dev);
130
131 if (mfg_start)
132 iounmap(mfg_start);
133 if(scp_start)
134 iounmap(scp_start);
135
136 return 0;
137 }
138
139 static struct platform_driver mtk_mfg_driver = {
140 .probe = mfg_device_probe,
141 .remove = mfg_device_remove,
142 .driver = {
143 .name = "mfg",
144 .owner = THIS_MODULE,
145 .of_match_table = of_match_ptr(mfg_dt_ids),
146 },
147 };
148
149 #define MFG_DUMP_FOR(base, off) \
150 do {\
151 u32 val;\
152 val = __raw_readl(base + off);\
153 pr_info("pwr_dump %s [%#x]: 0x%x\n", #base, (u32)off, val); \
154 }while(0)
155
156 #define DEBUG_MFG_STAT \
157 do {\
158 u32 con = 0xDEAC;\
159 con = MFG_READ32(MFG_CG_CON);\
160 pr_debug("MFG %s #%d CON: 0x%x\n", __func__, __LINE__, con); \
161 } while (0)
162
163 static int mfg_enable_gpu(void)
164 {
165 int ret = -1, i = 10;
166 u32 con;
167 if (mfg_start == NULL)
168 return ret;
169 ret = pm_runtime_get_sync(&mfg_dev->dev);
170 if (ret < 0){
171 /*
172 pm_runtime_enable(&mfg_dev->dev);
173 ret = pm_runtime_get_sync(&mfg_dev->dev);
174 */
175 pr_warn("MFG %s #%d get DISP[%d] \n", __func__, __LINE__, ret);
176 }
177 ret = mtk_smi_larb_clock_on(0, false);
178
179 i = 10;
180 DEBUG_MFG_STAT;
181 do{
182 MFG_WRITE32(0x1, MFG_CG_CLR);
183 con = MFG_READ32(MFG_CG_CON);
184 if (con == 0)
185 break;
186 else
187 pr_warn("MFG MFG_CG_CON[0x%x]", con);
188 }while(i--);
189 DEBUG_MFG_STAT;
190
191 return ret;
192 }
193
194 static void mfg_disable_gpu(void)
195 {
196 if (mfg_start == NULL)
197 return;
198
199 DEBUG_MFG_STAT;
200 MFG_WRITE32(0x1, MFG_CG_SET);
201 DEBUG_MFG_STAT;
202 mtk_smi_larb_clock_off(0, false);
203 pm_runtime_mark_last_busy(&mfg_dev->dev);
204 pm_runtime_put_autosuspend(&mfg_dev->dev);
205 }
206
207 static int __init mfg_driver_init(void)
208 {
209 int ret;
210
211 ret = platform_driver_register(&mtk_mfg_driver);
212 return ret;
213 }
214
215 bool mtk_mfg_is_ready(void)
216 {
217 return (mfg_dev !=NULL && mfg_start != NULL);
218 }
219
220 /* We need make mfg probed before GPU */
221 late_initcall(mfg_driver_init);
222
223 /* MFG end */
224
225 struct _mfg_base
226 {
227 void __iomem *g3d_base;
228 struct clk *mm_smi;
229 struct clk *mfg_pll;
230 struct clk *mfg_sel;
231 /*struct regulator *vdd_g3d;*/
232 };
233
234 static struct _mfg_base mfg_base;
235
236 #define REG_MFG_G3D BIT(0)
237
238 #define REG_MFG_CG_STA 0x00
239 #define REG_MFG_CG_SET 0x04
240 #define REG_MFG_CG_CLR 0x08
241
242 int mali_mfgsys_init(struct platform_device *device)
243 {
244 int err = 0;
245 struct clk *parent;
246 unsigned long freq;
247
248 mfg_base.g3d_base = mfg_start;
249
250 mfg_base.mm_smi = devm_clk_get(&device->dev, "mm_smi");
251 if (IS_ERR(mfg_base.mm_smi)) {
252 err = PTR_ERR(mfg_base.mm_smi);
253 dev_err(&device->dev, "devm_clk_get mm_smi failed\n");
254 goto err_iounmap_reg_base;
255 }
256 if(!_need_univpll){
257 mfg_base.mfg_pll = devm_clk_get(&device->dev, "mfg_pll");
258 if (IS_ERR(mfg_base.mfg_pll)) {
259 err = PTR_ERR(mfg_base.mfg_pll);
260 dev_err(&device->dev, "devm_clk_get mfg_pll failed\n");
261 goto err_iounmap_reg_base;
262 }
263 }else{
264 mfg_base.mfg_pll = devm_clk_get(&device->dev, "mfg_pll_univ");
265 if (IS_ERR(mfg_base.mfg_pll)) {
266 err = PTR_ERR(mfg_base.mfg_pll);
267 dev_err(&device->dev, "devm_clk_get mfg_pll_univ failed\n");
268 goto err_iounmap_reg_base;
269 }
270 }
271 mfg_base.mfg_sel = devm_clk_get(&device->dev, "mfg_sel");
272 if (IS_ERR(mfg_base.mfg_sel)) {
273 err = PTR_ERR(mfg_base.mfg_sel);
274 dev_err(&device->dev, "devm_clk_get mfg_sel failed\n");
275 goto err_iounmap_reg_base;
276 }
277 clk_prepare_enable(mfg_base.mfg_sel);
278
279 err = clk_set_parent(mfg_base.mfg_sel, mfg_base.mfg_pll);
280 if (err != 0) {
281 dev_err(&device->dev, "failed to clk_set_parent\n");
282 goto err_iounmap_reg_base;
283 }
284 parent = clk_get_parent(mfg_base.mfg_sel);
285 if (!IS_ERR_OR_NULL(parent)) {
286 pr_info("0MFG is now selected to %s\n", parent->name);
287 freq = clk_get_rate(parent);
288 pr_info("MFG parent rate %lu\n", freq);
289 /* Don't set rate here, gpufreq will do this */
290 } else {
291 pr_err("Failed to select mfg\n");
292 }
293
294 /*
295 clk_disable_unprepare(mfg_base.mfg_sel);
296
297 mfg_base.vdd_g3d = devm_regulator_get(&device->dev, "vdd_g3d");
298 if (IS_ERR(mfg_base.vdd_g3d)) {
299 err = PTR_ERR(mfg_base.vdd_g3d);
300 goto err_iounmap_reg_base;
301 }
302
303 err = regulator_enable(mfg_base.vdd_g3d);
304 if (err != 0) {
305 dev_err(&device->dev, "failed to enable regulator vdd_g3d\n");
306 goto err_iounmap_reg_base;
307 }
308 */
309
310 return 0;
311
312 err_iounmap_reg_base:
313
314 return err;
315 }
316
317 void mali_mfgsys_deinit(struct platform_device *device)
318 {
319 MALI_IGNORE(device);
320 pm_runtime_disable(&device->dev);
321 /*regulator_disable(mfg_base.vdd_g3d);*/
322 }
323 void dump_clk_state(void)
324 {
325 MALI_DEBUG_PRINT(2, ("mali platform_mmt dump_clk_state smi_ref[%d], smi_enabled[%d]\n",
326 __clk_get_enable_count(mfg_base.mm_smi), __clk_is_enabled(mfg_base.mm_smi)));
327 MALI_DEBUG_PRINT(2, ("MFG %s #%d MFG_DEBUG_SEL: 0x%x\n", __func__, __LINE__, MFG_READ32(MFG_DEBUG_SEL)));
328 MALI_DEBUG_PRINT(2, ("MFG %s #%d MFG_DEBUG_CON: %x\n", __func__, __LINE__, MFG_READ32(MFG_CG_CON)));
329 if(scp_start) {
330 MFG_DUMP_FOR(scp_start, 0x060c); /*SPM_PWR_STATUS*/
331 MFG_DUMP_FOR(scp_start, 0x0610); /*SPM_PWR_STATUS_2ND*/
332 }
333 mali_platform_power_mode_change(NULL, MALI_POWER_MODE_ON);
334 }
335 int mali_clk_enable(struct device *device)
336 {
337 int ret;
338 /*clk_prepare_enable(mfg_base.mfg_sel);*/
339
340 ret = mfg_enable_gpu();
341
342 MALI_DEBUG_PRINT(3, ("MFG %s #%d MFG_DEBUG_SEL: 0x%x\n", __func__, __LINE__, MFG_READ32(MFG_DEBUG_SEL)));
343 MALI_DEBUG_PRINT(3, ("MFG %s #%d MFG_DEBUG_CON: %x\n", __func__, __LINE__, MFG_READ32(MFG_CG_CON)));
344 MALI_DEBUG_PRINT(2, ("mali_clk_enable![%d]\n", ret));
345
346 return 0;
347 }
348
349 int mali_clk_disable(struct device *device)
350 {
351 mfg_disable_gpu();
352 /*clk_disable_unprepare(mfg_base.mfg_sel);*/
353 MALI_DEBUG_PRINT(2, ("mali_clk_disable done\n"));
354
355 return 0;
356 }
357 #endif
358
359 int mali_pmm_init(struct platform_device *device)
360 {
361 int err = 0;
362 u32 idx = 0;
363 MALI_DEBUG_PRINT(1, ("%s\n", __FUNCTION__));
364 idx = get_devinfo_with_index(3);
365 if (idx & MFG_SPD_MASK)
366 _need_univpll = 1;
367 else
368 _need_univpll = 0;
369 MALI_DEBUG_PRINT(2, ("need univ src pll idx0x%d %d\n", idx, _need_univpll));
370
371 /* Because clkmgr may do 'default on' for some clock.
372 We check the clock state on init and set power state atomic.
373 */
374
375 MALI_DEBUG_PRINT(1, ("MFG G3D init enable if it is on0621\n"));
376 #ifndef CONFIG_MALI_DT
377 mtk_thermal_get_gpu_loading_fp = gpu_get_current_utilization;
378 mtk_get_gpu_loading_fp = gpu_get_current_utilization;
379 if (clock_is_on(MT_CG_MFG_G3D)) {
380 MALI_DEBUG_PRINT(1, ("MFG G3D default on\n"));
381 atomic_set((atomic_t *) & bPoweroff, 0);
382 /* Need call enable first for 'default on' clocks.
383 * Canbe removed if clkmgr remove this requirement.
384 */
385 enable_clock(MT_CG_DISP0_SMI_COMMON, "MFG");
386 enable_clock(MT_CG_MFG_G3D, "MFG");
387 } else {
388 MALI_DEBUG_PRINT(1, ("MFG G3D init default off\n"));
389 atomic_set((atomic_t *) & bPoweroff, 1);
390 }
391 #else
392 err = mali_mfgsys_init(device);
393 if (err)
394 return err;
395 atomic_set((atomic_t *) & bPoweroff, 1);
396 #endif
397 mali_platform_power_mode_change(&(device->dev), MALI_POWER_MODE_ON);
398
399 return err;
400 }
401
402 void mali_pmm_deinit(struct platform_device *device)
403 {
404 MALI_DEBUG_PRINT(1, ("%s\n", __FUNCTION__));
405
406 mali_platform_power_mode_change(&device->dev, MALI_POWER_MODE_DEEP_SLEEP);
407 mali_mfgsys_deinit(device);
408 }
409
410 unsigned int gpu_get_current_utilization(void)
411 {
412 return (current_sample_utilization * 100) / 256;
413 }
414
415 void mali_platform_power_mode_change(struct device *device,
416 mali_power_mode power_mode)
417 {
418 switch (power_mode) {
419 case MALI_POWER_MODE_ON:
420 MALI_DEBUG_PRINT(3,
421 ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
422 atomic_read((atomic_t *) & bPoweroff) ?
423 "powering on" : "already on"));
424 if (atomic_read((atomic_t *) & bPoweroff) == 1) {
425 /*Leave this to undepend ref count of clkmgr */
426 #ifndef CONFIG_MALI_DT
427 if (!clock_is_on(MT_CG_MFG_G3D)) {
428 MALI_DEBUG_PRINT(3, ("MFG enable_clock \n"));
429 if (_need_univpll) {
430 enable_pll(UNIVPLL, "GPU");
431 }
432 enable_clock(MT_CG_DISP0_SMI_COMMON, "MFG");
433 enable_clock(MT_CG_MFG_G3D, "MFG");
434 if (_need_univpll) {
435 clkmux_sel(MT_MUX_MFG, 6, "GPU");
436 }
437 atomic_set((atomic_t *) & bPoweroff, 0);
438 }
439 #else
440 if (!mali_clk_enable(device))
441 atomic_set((atomic_t *) & bPoweroff, 0);
442 #endif
443 #if defined(CONFIG_MALI400_PROFILING)
444 _mali_osk_profiling_add_event
445 (MALI_PROFILING_EVENT_TYPE_SINGLE |
446 MALI_PROFILING_EVENT_CHANNEL_GPU |
447 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
448 500, 1200 / 1000, 0, 0, 0);
449
450 #endif
451 }
452 break;
453 case MALI_POWER_MODE_LIGHT_SLEEP:
454 case MALI_POWER_MODE_DEEP_SLEEP:
455 MALI_DEBUG_PRINT(3,
456 ("Mali platform: Got %s event, %s\n",
457 power_mode ==
458 MALI_POWER_MODE_LIGHT_SLEEP ?
459 "MALI_POWER_MODE_LIGHT_SLEEP" :
460 "MALI_POWER_MODE_DEEP_SLEEP",
461 atomic_read((atomic_t *) & bPoweroff) ?
462 "already off" : "powering off"));
463
464 if (atomic_read((atomic_t *) & bPoweroff) == 0) {
465 #ifndef CONFIG_MALI_DT
466 if (clock_is_on(MT_CG_MFG_G3D)) {
467 MALI_DEBUG_PRINT(3, ("MFG disable_clock \n"));
468 disable_clock(MT_CG_MFG_G3D, "MFG");
469 disable_clock(MT_CG_DISP0_SMI_COMMON, "MFG");
470 if (_need_univpll) {
471 disable_pll(UNIVPLL, "GPU");
472 }
473 atomic_set((atomic_t *) & bPoweroff, 1);
474 }
475 #else
476 if (!mali_clk_disable(device))
477 atomic_set((atomic_t *) & bPoweroff, 1);
478 #endif
479 #if defined(CONFIG_MALI400_PROFILING)
480 _mali_osk_profiling_add_event
481 (MALI_PROFILING_EVENT_TYPE_SINGLE |
482 MALI_PROFILING_EVENT_CHANNEL_GPU |
483 MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
484 0, 0, 0, 0, 0);
485 #endif
486 }
487 break;
488 }
489 }