25874f7268041b08ee86924b13c4ed1037a0da17
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / t6xx / kbase / src / platform / rk / mali_kbase_platform.c
1 /* drivers/gpu/t6xx/kbase/src/platform/rk/mali_kbase_platform.c
2  *
3  * Rockchip SoC Mali-T764 platform-dependent codes
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software FoundatIon.
8  */
9
10 /**
11  * @file mali_kbase_platform.c
12  * Platform-dependent init.
13  */
14 #include <kbase/src/common/mali_kbase.h>
15 #include <kbase/src/common/mali_kbase_pm.h>
16 #include <kbase/src/common/mali_kbase_uku.h>
17 #include <kbase/src/common/mali_kbase_mem.h>
18 #include <kbase/src/common/mali_midg_regmap.h>
19 #include <kbase/src/linux/mali_kbase_mem_linux.h>
20
21 #include <linux/module.h>
22 #include <linux/init.h>
23 #include <linux/poll.h>
24 #include <linux/kernel.h>
25 #include <linux/errno.h>
26 #include <linux/platform_device.h>
27 #include <linux/pci.h>
28 #include <linux/miscdevice.h>
29 #include <linux/list.h>
30 #include <linux/semaphore.h>
31 #include <linux/fs.h>
32 #include <linux/uaccess.h>
33 #include <linux/interrupt.h>
34 #include <linux/io.h>
35
36 #include <linux/fb.h>
37 #include <linux/clk.h>
38 #include <linux/delay.h>
39 #include <kbase/src/platform/rk/mali_kbase_platform.h>
40 #include <kbase/src/platform/rk/mali_kbase_dvfs.h>
41
42 #include <kbase/src/common/mali_kbase_gator.h>
43
44 #include <linux/rockchip/dvfs.h> 
45
46 #define MALI_T7XX_DEFAULT_CLOCK 400000000
47
48
49 static int mali_clk_status = 0;
50 static int mali_pd_status = 0;
51
52 int mali_dvfs_clk_set(struct dvfs_node *node,unsigned long rate)
53 {
54         int ret = 0;
55         if(!node)
56         {
57                 printk("clk_get_dvfs_node error \r\n");
58                 ret = -1;
59         }
60         ret = dvfs_clk_set_rate(node,rate);
61         if(ret)
62         {
63                 printk("dvfs_clk_set_rate error \r\n");
64         }
65         return ret;
66 }
67 static int kbase_platform_power_clock_init(kbase_device *kbdev)
68 {
69         struct device *dev = kbdev->osdev.dev;
70         struct rk_context *platform;
71
72         platform = (struct rk_context *)kbdev->platform_context;
73         if (NULL == platform)
74                 panic("oops");
75         
76         /* enable mali t760 powerdomain*/       
77         platform->mali_pd_node = clk_get_dvfs_node("mali_pd");
78         if(IS_ERR_OR_NULL(platform->mali_pd_node))
79         {
80                 platform->mali_pd_node = NULL;
81                 printk(KERN_ERR "%s, %s(): failed to clk_get [platform->mali_pd_node]\n", __FILE__, __func__);
82                 //goto out;
83         }
84         else
85         {
86                 //dvfs_clk_prepare_enable(platform->mali_pd_node);
87                 printk("pd not enable\n");
88         }
89         mali_pd_status = 1;
90         
91         /* enable mali t760 clock */
92         platform->mali_clk_node = clk_get_dvfs_node("clk_gpu");
93         if (IS_ERR_OR_NULL(platform->mali_clk_node)) 
94         {
95                 platform->mali_clk_node = NULL;
96                 printk(KERN_ERR "%s, %s(): failed to clk_get [platform->mali_clk_node]\n", __FILE__, __func__);
97                 //goto out;
98         } 
99         else 
100         {
101                 dvfs_clk_prepare_enable(platform->mali_clk_node);
102                 printk("clk enabled\n");
103         }
104         mali_dvfs_clk_set(platform->mali_clk_node,MALI_T7XX_DEFAULT_CLOCK);
105         
106         mali_clk_status = 1;
107         return 0;
108         
109 out:
110         if(platform->mali_pd_node)
111                 clk_put_dvfs_node(platform->mali_pd_node);
112         
113         return -EPERM;
114
115 }
116 int kbase_platform_clock_off(struct kbase_device *kbdev)
117 {
118         struct rk_context *platform;
119         if (!kbdev)
120                 return -ENODEV;
121
122         platform = (struct rk_context *)kbdev->platform_context;
123         if (!platform)
124                 return -ENODEV;
125
126         if (mali_clk_status == 0)
127                 return 0;
128         
129         if((platform->mali_clk_node))
130                 dvfs_clk_disable_unprepare(platform->mali_clk_node);
131         
132         mali_clk_status = 0;
133
134         return 0;
135 }
136
137 int kbase_platform_clock_on(struct kbase_device *kbdev)
138 {
139         struct rk_context *platform;
140         if (!kbdev)
141                 return -ENODEV;
142
143         platform = (struct rk_context *)kbdev->platform_context;
144         if (!platform)
145                 return -ENODEV;
146
147         if (mali_clk_status == 1)
148                 return 0;
149         
150         if(platform->mali_clk_node)
151                 dvfs_clk_prepare_enable(platform->mali_clk_node);
152
153         mali_clk_status = 1;
154
155         return 0;
156 }
157 int kbase_platform_is_power_on(void)
158 {
159         return mali_pd_status;
160 }
161
162 /*turn on power domain*/
163 static int kbase_platform_power_on(struct kbase_device *kbdev)
164 {
165         struct rk_context *platform;
166         if (!kbdev)
167                 return -ENODEV;
168
169         platform = (struct rk_context *)kbdev->platform_context;
170         if (!platform)
171                 return -ENODEV;
172
173         if (mali_pd_status == 1)
174                 return 0;
175 #if 0   
176         if(platform->mali_pd_node)
177                 dvfs_clk_prepare_enable(platform->mali_pd_node);
178 #endif
179         mali_pd_status = 1;
180         KBASE_TIMELINE_GPU_POWER(kbdev, 1);
181
182         return 0;
183 }
184
185 /*turn off power domain*/
186 static int kbase_platform_power_off(struct kbase_device *kbdev)
187 {
188         struct rk_context *platform;
189         if (!kbdev)
190                 return -ENODEV;
191
192         platform = (struct rk_context *)kbdev->platform_context;
193         if (!platform)
194                 return -ENODEV;
195
196         if (mali_pd_status== 0)
197                 return 0;
198 #if 0
199         if(platform->mali_pd_node)
200                 dvfs_clk_disable_unprepare(platform->mali_pd_node);
201 #endif
202         mali_pd_status = 0;
203         KBASE_TIMELINE_GPU_POWER(kbdev, 0);
204
205         return 0;
206 }
207
208 int kbase_platform_cmu_pmu_control(struct kbase_device *kbdev, int control)
209 {
210         unsigned long flags;
211         struct rk_context *platform;
212         if (!kbdev)
213                 return -ENODEV;
214
215         platform = (struct rk_context *)kbdev->platform_context;
216         if (!platform)
217                 return -ENODEV;
218
219         spin_lock_irqsave(&platform->cmu_pmu_lock, flags);
220
221         /* off */
222         if (control == 0) 
223         {
224                 if (platform->cmu_pmu_status == 0) 
225                 {
226                         spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags);
227                         return 0;
228                 }
229
230                 if (kbase_platform_power_off(kbdev))
231                         panic("failed to turn off mali power domain\n");
232                 if (kbase_platform_clock_off(kbdev))
233                         panic("failed to turn off mali clock\n");
234
235                 platform->cmu_pmu_status = 0;
236                 printk("turn off mali power \n");
237         } 
238         else 
239         {
240                 /* on */
241                 if (platform->cmu_pmu_status == 1) 
242                 {
243                         spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags);
244                         return 0;
245                 }
246
247                 if (kbase_platform_power_on(kbdev))
248                         panic("failed to turn on mali power domain\n");
249                 if (kbase_platform_clock_on(kbdev))
250                         panic("failed to turn on mali clock\n");
251
252                 platform->cmu_pmu_status = 1;
253                 printk(KERN_ERR "turn on mali power\n");
254         }
255
256         spin_unlock_irqrestore(&platform->cmu_pmu_lock, flags);
257
258         return 0;
259 }
260
261 #ifdef CONFIG_MALI_T6XX_DEBUG_SYS
262 static ssize_t show_clock(struct device *dev, struct device_attribute *attr, char *buf)
263 {
264         struct kbase_device *kbdev;
265         struct rk_context *platform;
266         ssize_t ret = 0;
267         unsigned int clkrate;
268
269         kbdev = dev_get_drvdata(dev);
270
271         if (!kbdev)
272                 return -ENODEV;
273
274         platform = (struct rk_context *)kbdev->platform_context;
275         if (!platform)
276                 return -ENODEV;
277
278         if (!platform->clk_mali)
279                 return -ENODEV;
280
281         clkrate = dvfs_clk_get_rate(platform->mali_clk_node);
282         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current clk mali = %dMhz", clkrate / 1000000);
283
284         /* To be revised  */
285         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 533, 450, 400, 350, 266, 160, 100Mhz");
286
287         if (ret < PAGE_SIZE - 1)
288                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
289         else {
290                 buf[PAGE_SIZE - 2] = '\n';
291                 buf[PAGE_SIZE - 1] = '\0';
292                 ret = PAGE_SIZE - 1;
293         }
294
295         return ret;
296 }
297
298 static ssize_t set_clock(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
299 {
300         struct kbase_device *kbdev;
301         struct rk_context *platform;
302         unsigned int tmp = 0, freq = 0;
303         kbdev = dev_get_drvdata(dev);
304         tmp = 0;        
305         if (!kbdev)
306                 return -ENODEV;
307
308         platform = (struct rk_context *)kbdev->platform_context;
309         if (!platform)
310                 return -ENODEV;
311
312         if (!platform->mali_clk_node)
313                 return -ENODEV;
314
315         if (sysfs_streq("533", buf)) {
316                 freq = 533;
317         } else if (sysfs_streq("450", buf)) {
318                 freq = 450;
319         } else if (sysfs_streq("400", buf)) {
320                 freq = 400;
321         } else if (sysfs_streq("350", buf)) {
322                 freq = 350;
323         } else if (sysfs_streq("266", buf)) {
324                 freq = 266;
325         } else if (sysfs_streq("160", buf)) {
326                 freq = 160;
327         } else if (sysfs_streq("100", buf)) {
328                 freq = 100;
329         } else {
330                 dev_err(dev, "set_clock: invalid value\n");
331                 return -ENOENT;
332         }
333
334         kbase_platform_dvfs_set_level(kbdev, kbase_platform_dvfs_get_level(freq));
335         /* Waiting for clock is stable
336         do {
337                 tmp = __raw_readl(EXYNOS5_CLKDIV_STAT_TOP0);
338         } while (tmp & 0x1000000);
339         */
340
341         return count;
342 }
343
344 static ssize_t show_fbdev(struct device *dev, struct device_attribute *attr, char *buf)
345 {
346         struct kbase_device *kbdev;
347         ssize_t ret = 0;
348         int i;
349
350         kbdev = dev_get_drvdata(dev);
351
352         if (!kbdev)
353                 return -ENODEV;
354
355         for (i = 0; i < num_registered_fb; i++)
356                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "fb[%d] xres=%d, yres=%d, addr=0x%lx\n", i, registered_fb[i]->var.xres, registered_fb[i]->var.yres, registered_fb[i]->fix.smem_start);
357
358         if (ret < PAGE_SIZE - 1)
359                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
360         else {
361                 buf[PAGE_SIZE - 2] = '\n';
362                 buf[PAGE_SIZE - 1] = '\0';
363                 ret = PAGE_SIZE - 1;
364         }
365
366         return ret;
367 }
368
369 typedef enum {
370         L1_I_tag_RAM = 0x00,
371         L1_I_data_RAM = 0x01,
372         L1_I_BTB_RAM = 0x02,
373         L1_I_GHB_RAM = 0x03,
374         L1_I_TLB_RAM = 0x04,
375         L1_I_indirect_predictor_RAM = 0x05,
376         L1_D_tag_RAM = 0x08,
377         L1_D_data_RAM = 0x09,
378         L1_D_load_TLB_array = 0x0A,
379         L1_D_store_TLB_array = 0x0B,
380         L2_tag_RAM = 0x10,
381         L2_data_RAM = 0x11,
382         L2_snoop_tag_RAM = 0x12,
383         L2_data_ECC_RAM = 0x13,
384         L2_dirty_RAM = 0x14,
385         L2_TLB_RAM = 0x18
386 } RAMID_type;
387
388 static inline void asm_ramindex_mrc(u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3)
389 {
390         u32 val;
391
392         if (DL1Data0) {
393                 asm volatile ("mrc p15, 0, %0, c15, c1, 0" : "=r" (val));
394                 *DL1Data0 = val;
395         }
396         if (DL1Data1) {
397                 asm volatile ("mrc p15, 0, %0, c15, c1, 1" : "=r" (val));
398                 *DL1Data1 = val;
399         }
400         if (DL1Data2) {
401                 asm volatile ("mrc p15, 0, %0, c15, c1, 2" : "=r" (val));
402                 *DL1Data2 = val;
403         }
404         if (DL1Data3) {
405                 asm volatile ("mrc p15, 0, %0, c15, c1, 3" : "=r" (val));
406                 *DL1Data3 = val;
407         }
408 }
409
410 static inline void asm_ramindex_mcr(u32 val)
411 {
412         asm volatile ("mcr p15, 0, %0, c15, c4, 0" : : "r" (val));
413         asm volatile ("dsb");
414         asm volatile ("isb");
415 }
416
417 static void get_tlb_array(u32 val, u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3)
418 {
419         asm_ramindex_mcr(val);
420         asm_ramindex_mrc(DL1Data0, DL1Data1, DL1Data2, DL1Data3);
421 }
422
423 static RAMID_type ramindex = L1_D_load_TLB_array;
424 static ssize_t show_dtlb(struct device *dev, struct device_attribute *attr, char *buf)
425 {
426         struct kbase_device *kbdev;
427         ssize_t ret = 0;
428         int entries, ways;
429         u32 DL1Data0 = 0, DL1Data1 = 0, DL1Data2 = 0, DL1Data3 = 0;
430
431         kbdev = dev_get_drvdata(dev);
432
433         if (!kbdev)
434                 return -ENODEV;
435
436         /* L1-I tag RAM */
437         if (ramindex == L1_I_tag_RAM)
438                 printk(KERN_DEBUG "Not implemented yet\n");
439         /* L1-I data RAM */
440         else if (ramindex == L1_I_data_RAM)
441                 printk(KERN_DEBUG "Not implemented yet\n");
442         /* L1-I BTB RAM */
443         else if (ramindex == L1_I_BTB_RAM)
444                 printk(KERN_DEBUG "Not implemented yet\n");
445         /* L1-I GHB RAM */
446         else if (ramindex == L1_I_GHB_RAM)
447                 printk(KERN_DEBUG "Not implemented yet\n");
448         /* L1-I TLB RAM */
449         else if (ramindex == L1_I_TLB_RAM) {
450                 printk(KERN_DEBUG "L1-I TLB RAM\n");
451                 for (entries = 0; entries < 32; entries++) {
452                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, NULL);
453                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x DL1Data2=%08x\n", entries, DL1Data0, DL1Data1 & 0xffff, 0x0);
454                 }
455         }
456         /* L1-I indirect predictor RAM */
457         else if (ramindex == L1_I_indirect_predictor_RAM)
458                 printk(KERN_DEBUG "Not implemented yet\n");
459         /* L1-D tag RAM */
460         else if (ramindex == L1_D_tag_RAM)
461                 printk(KERN_DEBUG "Not implemented yet\n");
462         /* L1-D data RAM */
463         else if (ramindex == L1_D_data_RAM)
464                 printk(KERN_DEBUG "Not implemented yet\n");
465         /* L1-D load TLB array */
466         else if (ramindex == L1_D_load_TLB_array) {
467                 printk(KERN_DEBUG "L1-D load TLB array\n");
468                 for (entries = 0; entries < 32; entries++) {
469                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
470                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f);
471                 }
472         }
473         /* L1-D store TLB array */
474         else if (ramindex == L1_D_store_TLB_array) {
475                 printk(KERN_DEBUG "\nL1-D store TLB array\n");
476                 for (entries = 0; entries < 32; entries++) {
477                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
478                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f);
479                 }
480         }
481         /* L2 tag RAM */
482         else if (ramindex == L2_tag_RAM)
483                 printk(KERN_DEBUG "Not implemented yet\n");
484         /* L2 data RAM */
485         else if (ramindex == L2_data_RAM)
486                 printk(KERN_DEBUG "Not implemented yet\n");
487         /* L2 snoop tag RAM */
488         else if (ramindex == L2_snoop_tag_RAM)
489                 printk(KERN_DEBUG "Not implemented yet\n");
490         /* L2 data ECC RAM */
491         else if (ramindex == L2_data_ECC_RAM)
492                 printk(KERN_DEBUG "Not implemented yet\n");
493         /* L2 dirty RAM */
494         else if (ramindex == L2_dirty_RAM)
495                 printk(KERN_DEBUG "Not implemented yet\n");
496
497         /* L2 TLB array */
498         else if (ramindex == L2_TLB_RAM) {
499                 printk(KERN_DEBUG "\nL2 TLB array\n");
500                 for (ways = 0; ways < 4; ways++) {
501                         for (entries = 0; entries < 512; entries++) {
502                                 get_tlb_array((ramindex << 24) + (ways << 18) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
503                                 printk(KERN_DEBUG "ways[%d]:entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", ways, entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3);
504                         }
505                 }
506         } else {
507         }
508
509         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Succeeded...\n");
510
511         if (ret < PAGE_SIZE - 1)
512                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
513         else {
514                 buf[PAGE_SIZE - 2] = '\n';
515                 buf[PAGE_SIZE - 1] = '\0';
516                 ret = PAGE_SIZE - 1;
517         }
518         return ret;
519 }
520
521 static ssize_t set_dtlb(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
522 {
523         struct kbase_device *kbdev;
524         kbdev = dev_get_drvdata(dev);
525
526         if (!kbdev)
527                 return -ENODEV;
528
529         if (sysfs_streq("L1_I_tag_RAM", buf)) {
530                 ramindex = L1_I_tag_RAM;
531         } else if (sysfs_streq("L1_I_data_RAM", buf)) {
532                 ramindex = L1_I_data_RAM;
533         } else if (sysfs_streq("L1_I_BTB_RAM", buf)) {
534                 ramindex = L1_I_BTB_RAM;
535         } else if (sysfs_streq("L1_I_GHB_RAM", buf)) {
536                 ramindex = L1_I_GHB_RAM;
537         } else if (sysfs_streq("L1_I_TLB_RAM", buf)) {
538                 ramindex = L1_I_TLB_RAM;
539         } else if (sysfs_streq("L1_I_indirect_predictor_RAM", buf)) {
540                 ramindex = L1_I_indirect_predictor_RAM;
541         } else if (sysfs_streq("L1_D_tag_RAM", buf)) {
542                 ramindex = L1_D_tag_RAM;
543         } else if (sysfs_streq("L1_D_data_RAM", buf)) {
544                 ramindex = L1_D_data_RAM;
545         } else if (sysfs_streq("L1_D_load_TLB_array", buf)) {
546                 ramindex = L1_D_load_TLB_array;
547         } else if (sysfs_streq("L1_D_store_TLB_array", buf)) {
548                 ramindex = L1_D_store_TLB_array;
549         } else if (sysfs_streq("L2_tag_RAM", buf)) {
550                 ramindex = L2_tag_RAM;
551         } else if (sysfs_streq("L2_data_RAM", buf)) {
552                 ramindex = L2_data_RAM;
553         } else if (sysfs_streq("L2_snoop_tag_RAM", buf)) {
554                 ramindex = L2_snoop_tag_RAM;
555         } else if (sysfs_streq("L2_data_ECC_RAM", buf)) {
556                 ramindex = L2_data_ECC_RAM;
557         } else if (sysfs_streq("L2_dirty_RAM", buf)) {
558                 ramindex = L2_dirty_RAM;
559         } else if (sysfs_streq("L2_TLB_RAM", buf)) {
560                 ramindex = L2_TLB_RAM;
561         } else {
562                 printk(KERN_DEBUG "Invalid value....\n\n");
563                 printk(KERN_DEBUG "Available options are one of below\n");
564                 printk(KERN_DEBUG "L1_I_tag_RAM, L1_I_data_RAM, L1_I_BTB_RAM\n");
565                 printk(KERN_DEBUG "L1_I_GHB_RAM, L1_I_TLB_RAM, L1_I_indirect_predictor_RAM\n");
566                 printk(KERN_DEBUG "L1_D_tag_RAM, L1_D_data_RAM, L1_D_load_TLB_array, L1_D_store_TLB_array\n");
567                 printk(KERN_DEBUG "L2_tag_RAM, L2_data_RAM, L2_snoop_tag_RAM, L2_data_ECC_RAM\n");
568                 printk(KERN_DEBUG "L2_dirty_RAM, L2_TLB_RAM\n");
569         }
570
571         return count;
572 }
573
574 static ssize_t show_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
575 {
576         struct kbase_device *kbdev;
577         ssize_t ret = 0;
578
579         kbdev = dev_get_drvdata(dev);
580
581         if (!kbdev)
582                 return -ENODEV;
583
584 #ifdef CONFIG_MALI_T6XX_DVFS
585         if (kbase_platform_dvfs_get_enable_status())
586                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is on\nutilisation:%d", kbase_platform_dvfs_get_utilisation());
587         else
588                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali  DVFS is off");
589 #else
590         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali  DVFS is disabled");
591 #endif
592
593         if (ret < PAGE_SIZE - 1)
594                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
595         else {
596                 buf[PAGE_SIZE - 2] = '\n';
597                 buf[PAGE_SIZE - 1] = '\0';
598                 ret = PAGE_SIZE - 1;
599         }
600
601         return ret;
602 }
603
604 static ssize_t set_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
605 {
606         struct kbase_device *kbdev = dev_get_drvdata(dev);
607 #ifdef CONFIG_MALI_T6XX_DVFS
608         struct rk_context *platform;
609 #endif
610
611         if (!kbdev)
612                 return -ENODEV;
613
614 #ifdef CONFIG_MALI_T6XX_DVFS
615         platform = (struct rk_context *)kbdev->platform_context;
616         if (sysfs_streq("off", buf)) {
617                 kbase_platform_dvfs_enable(false, MALI_DVFS_BL_CONFIG_FREQ);
618                 platform->dvfs_enabled = false;
619         } else if (sysfs_streq("on", buf)) {
620                 kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ);
621                 platform->dvfs_enabled = true;
622         } else {
623                 printk(KERN_DEBUG "invalid val -only [on, off] is accepted\n");
624         }
625 #else
626         printk(KERN_DEBUG "mali  DVFS is disabled\n");
627 #endif
628         return count;
629 }
630
631 static ssize_t show_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
632 {
633         struct kbase_device *kbdev;
634         ssize_t ret = 0;
635 #ifdef CONFIG_MALI_T6XX_DVFS
636         int locked_level = -1;
637 #endif
638
639         kbdev = dev_get_drvdata(dev);
640
641         if (!kbdev)
642                 return -ENODEV;
643
644 #ifdef CONFIG_MALI_T6XX_DVFS
645         locked_level = mali_get_dvfs_upper_locked_freq();
646         if (locked_level > 0)
647                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Upper Lock Level = %dMhz", locked_level);
648         else
649                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the Upper Lock Level");
650         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 450, 400, 266, 160, 100, If you want to unlock : 533 or off");
651
652 #else
653         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set");
654 #endif
655
656         if (ret < PAGE_SIZE - 1)
657                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
658         else {
659                 buf[PAGE_SIZE - 2] = '\n';
660                 buf[PAGE_SIZE - 1] = '\0';
661                 ret = PAGE_SIZE - 1;
662         }
663
664         return ret;
665 }
666
667 static ssize_t set_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
668 {
669         struct kbase_device *kbdev;
670         kbdev = dev_get_drvdata(dev);
671
672         if (!kbdev)
673                 return -ENODEV;
674
675 #ifdef CONFIG_MALI_T6XX_DVFS
676         if (sysfs_streq("off", buf)) {
677                 mali_dvfs_freq_unlock();
678         } else if (sysfs_streq("533", buf)) {
679                 mali_dvfs_freq_unlock();
680         } else if (sysfs_streq("450", buf)) {
681                 mali_dvfs_freq_lock(5);
682         } else if (sysfs_streq("400", buf)) {
683                 mali_dvfs_freq_lock(4);
684         } else if (sysfs_streq("350", buf)) {
685                 mali_dvfs_freq_lock(3);
686         } else if (sysfs_streq("266", buf)) {
687                 mali_dvfs_freq_lock(2);
688         } else if (sysfs_streq("160", buf)) {
689                 mali_dvfs_freq_lock(1);
690         } else if (sysfs_streq("100", buf)) {
691                 mali_dvfs_freq_lock(0);
692         } else {
693                 dev_err(dev, "set_clock: invalid value\n");
694                 dev_err(dev, "Possible settings : 450, 400, 266, 160, 100, If you want to unlock : 533\n");
695                 return -ENOENT;
696         }
697 #else                           /* CONFIG_MALI_T6XX_DVFS */
698         printk(KERN_DEBUG "mali DVFS is disabled. You can not set\n");
699 #endif
700
701         return count;
702 }
703
704 static ssize_t show_under_lock_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
705 {
706         struct kbase_device *kbdev;
707         ssize_t ret = 0;
708 #ifdef CONFIG_MALI_T6XX_DVFS
709         int locked_level = -1;
710 #endif
711
712         kbdev = dev_get_drvdata(dev);
713
714         if (!kbdev)
715                 return -ENODEV;
716
717 #ifdef CONFIG_MALI_T6XX_DVFS
718         locked_level = mali_get_dvfs_under_locked_freq();
719         if (locked_level > 0)
720                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Under Lock Level = %dMhz", locked_level);
721         else
722                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the Under Lock Level");
723         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 533, 450, 400, 266, 160, If you want to unlock : 100 or off");
724
725 #else
726         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set");
727 #endif
728
729         if (ret < PAGE_SIZE - 1)
730                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
731         else {
732                 buf[PAGE_SIZE - 2] = '\n';
733                 buf[PAGE_SIZE - 1] = '\0';
734                 ret = PAGE_SIZE - 1;
735         }
736
737         return ret;
738 }
739
740 static ssize_t set_under_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
741 {
742         struct kbase_device *kbdev;
743         kbdev = dev_get_drvdata(dev);
744
745         if (!kbdev)
746                 return -ENODEV;
747
748 #ifdef CONFIG_MALI_T6XX_DVFS
749         if (sysfs_streq("off", buf)) {
750                 mali_dvfs_freq_under_unlock();
751         } else if (sysfs_streq("533", buf)) {
752                 mali_dvfs_freq_under_lock(6);
753         } else if (sysfs_streq("450", buf)) {
754                 mali_dvfs_freq_under_lock(5);
755         } else if (sysfs_streq("400", buf)) {
756                 mali_dvfs_freq_under_lock(4);
757         } else if (sysfs_streq("350", buf)) {
758                 mali_dvfs_freq_under_lock(3);
759         } else if (sysfs_streq("266", buf)) {
760                 mali_dvfs_freq_under_lock(2);
761         } else if (sysfs_streq("160", buf)) {
762                 mali_dvfs_freq_under_lock(1);
763         } else if (sysfs_streq("100", buf)) {
764                 mali_dvfs_freq_under_unlock();
765         } else {
766                 dev_err(dev, "set_clock: invalid value\n");
767                 dev_err(dev, "Possible settings : 533, 450, 400, 266, 160, If you want to unlock : 100 or off\n");
768                 return -ENOENT;
769         }
770 #else
771         printk(KERN_DEBUG "G3D DVFS is disabled. You can not set\n");
772 #endif /* CONFIG_MALI_T6XX_DVFS */
773
774         return count;
775 }
776
777 /** The sysfs file @c clock, fbdev.
778  *
779  * This is used for obtaining information about the mali t6xx operating clock & framebuffer address,
780  */
781 DEVICE_ATTR(clock, S_IRUGO | S_IWUSR, show_clock, set_clock);
782 DEVICE_ATTR(fbdev, S_IRUGO, show_fbdev, NULL);
783 DEVICE_ATTR(dtlb, S_IRUGO | S_IWUSR, show_dtlb, set_dtlb);
784 DEVICE_ATTR(dvfs, S_IRUGO | S_IWUSR, show_dvfs, set_dvfs);
785 DEVICE_ATTR(dvfs_upper_lock, S_IRUGO | S_IWUSR, show_upper_lock_dvfs, set_upper_lock_dvfs);
786 DEVICE_ATTR(dvfs_under_lock, S_IRUGO | S_IWUSR, show_under_lock_dvfs, set_under_lock_dvfs);
787 DEVICE_ATTR(time_in_state, S_IRUGO | S_IWUSR, show_time_in_state, set_time_in_state);
788
789 int kbase_platform_create_sysfs_file(struct device *dev)
790 {
791         if (device_create_file(dev, &dev_attr_clock)) {
792                 dev_err(dev, "Couldn't create sysfs file [clock]\n");
793                 goto out;
794         }
795
796         if (device_create_file(dev, &dev_attr_fbdev)) {
797                 dev_err(dev, "Couldn't create sysfs file [fbdev]\n");
798                 goto out;
799         }
800
801         if (device_create_file(dev, &dev_attr_dtlb)) {
802                 dev_err(dev, "Couldn't create sysfs file [dtlb]\n");
803                 goto out;
804         }
805
806         if (device_create_file(dev, &dev_attr_dvfs)) {
807                 dev_err(dev, "Couldn't create sysfs file [dvfs]\n");
808                 goto out;
809         }
810
811         if (device_create_file(dev, &dev_attr_dvfs_upper_lock)) {
812                 dev_err(dev, "Couldn't create sysfs file [dvfs_upper_lock]\n");
813                 goto out;
814         }
815
816         if (device_create_file(dev, &dev_attr_dvfs_under_lock)) {
817                 dev_err(dev, "Couldn't create sysfs file [dvfs_under_lock]\n");
818                 goto out;
819         }
820
821         if (device_create_file(dev, &dev_attr_time_in_state)) {
822                 dev_err(dev, "Couldn't create sysfs file [time_in_state]\n");
823                 goto out;
824         }
825         return 0;
826  out:
827         return -ENOENT;
828 }
829
830 void kbase_platform_remove_sysfs_file(struct device *dev)
831 {
832         device_remove_file(dev, &dev_attr_clock);
833         device_remove_file(dev, &dev_attr_fbdev);
834         device_remove_file(dev, &dev_attr_dtlb);
835         device_remove_file(dev, &dev_attr_dvfs);
836         device_remove_file(dev, &dev_attr_dvfs_upper_lock);
837         device_remove_file(dev, &dev_attr_dvfs_under_lock);
838         device_remove_file(dev, &dev_attr_time_in_state);
839 }
840 #endif                          /* CONFIG_MALI_T6XX_DEBUG_SYS */
841
842 mali_error kbase_platform_init(struct kbase_device *kbdev)
843 {
844         struct rk_context *platform;
845
846         platform = kmalloc(sizeof(struct rk_context), GFP_KERNEL);
847
848         if (NULL == platform)
849                 return MALI_ERROR_OUT_OF_MEMORY;
850
851         kbdev->platform_context = (void *)platform;
852
853         platform->cmu_pmu_status = 0;
854 #ifdef CONFIG_MALI_T6XX_DVFS
855         platform->utilisation = 0;
856         platform->time_busy = 0;
857         platform->time_idle = 0;
858         platform->time_tick = 0;
859         platform->dvfs_enabled = true;
860 #endif
861
862         spin_lock_init(&platform->cmu_pmu_lock);
863
864         if (kbase_platform_power_clock_init(kbdev))
865                 goto clock_init_fail;
866
867 #ifdef CONFIG_MALI_T6XX_DVFS
868         kbase_platform_dvfs_init(kbdev);
869 #endif                          /* CONFIG_MALI_T6XX_DVFS */
870
871         /* Enable power */
872         kbase_platform_cmu_pmu_control(kbdev, 1);
873         return MALI_ERROR_NONE;
874
875  clock_init_fail:
876         kfree(platform);
877
878         return MALI_ERROR_FUNCTION_FAILED;
879 }
880
881 void kbase_platform_term(kbase_device *kbdev)
882 {
883         struct rk_context *platform;
884
885         platform = (struct rk_context *)kbdev->platform_context;
886
887 #ifdef CONFIG_MALI_T6XX_DVFS
888         kbase_platform_dvfs_term();
889 #endif                          /* CONFIG_MALI_T6XX_DVFS */
890
891         /* Disable power */
892         kbase_platform_cmu_pmu_control(kbdev, 0);
893         kfree(kbdev->platform_context);
894         kbdev->platform_context = 0;
895         return;
896 }