544b09d388bdd28c7cdde292b12a1de57108668e
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard / 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 <mali_kbase.h>
15 #include <mali_kbase_pm.h>
16 #include <mali_kbase_uku.h>
17 #include <mali_kbase_mem.h>
18 #include <mali_midg_regmap.h>
19 #include <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 <platform/rk/mali_kbase_platform.h>
40 #include <platform/rk/mali_kbase_dvfs.h>
41
42 #include <mali_kbase_gator.h>
43
44 #include <linux/rockchip/dvfs.h> 
45
46 #define MALI_T7XX_DEFAULT_CLOCK 100000
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 * MALI_KHZ);
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->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 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 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_MIDGARD_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         int i ;
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->mali_clk_node)
279         {
280                 printk("mali_clk_node not init\n");
281                 return -ENODEV;
282         }
283         clkrate = dvfs_clk_get_rate(platform->mali_clk_node);
284         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current clk mali = %dMhz", clkrate / 1000000);
285
286         /* To be revised  */
287         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings:");
288         for(i=0;i<MALI_DVFS_STEP;i++)
289                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
290                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
291
292         if (ret < PAGE_SIZE - 1)
293                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
294         else {
295                 buf[PAGE_SIZE - 2] = '\n';
296                 buf[PAGE_SIZE - 1] = '\0';
297                 ret = PAGE_SIZE - 1;
298         }
299
300         return ret;
301 }
302
303 static ssize_t set_clock(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
304 {
305         struct kbase_device *kbdev;
306         struct rk_context *platform;
307         unsigned int tmp = 0, freq = 0;
308         kbdev = dev_get_drvdata(dev);
309         tmp = 0;        
310         if (!kbdev)
311                 return -ENODEV;
312
313         platform = (struct rk_context *)kbdev->platform_context;
314         if (!platform)
315                 return -ENODEV;
316
317         if (!platform->mali_clk_node)
318                 return -ENODEV;
319 #if 0
320         if (sysfs_streq("500", buf)) {
321                 freq = 500;
322         } else if (sysfs_streq("400", buf)) {
323                 freq = 400;
324         } else if (sysfs_streq("350", buf)) {
325                 freq = 350;
326         } else if (sysfs_streq("266", buf)) {
327                 freq = 266;
328         } else if (sysfs_streq("160", buf)) {
329                 freq = 160;
330         } else if (sysfs_streq("100", buf)) {
331                 freq = 100;
332         } else {
333                 dev_err(dev, "set_clock: invalid value\n");
334                 return -ENOENT;
335         }
336 #endif
337         freq = simple_strtoul(buf, NULL, 10);
338
339         kbase_platform_dvfs_set_level(kbdev, kbase_platform_dvfs_get_level(freq));
340         return count;
341 }
342
343 static ssize_t show_fbdev(struct device *dev, struct device_attribute *attr, char *buf)
344 {
345         struct kbase_device *kbdev;
346         ssize_t ret = 0;
347         int i;
348
349         kbdev = dev_get_drvdata(dev);
350
351         if (!kbdev)
352                 return -ENODEV;
353
354         for (i = 0; i < num_registered_fb; i++)
355                 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);
356
357         if (ret < PAGE_SIZE - 1)
358                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
359         else {
360                 buf[PAGE_SIZE - 2] = '\n';
361                 buf[PAGE_SIZE - 1] = '\0';
362                 ret = PAGE_SIZE - 1;
363         }
364
365         return ret;
366 }
367
368 typedef enum {
369         L1_I_tag_RAM = 0x00,
370         L1_I_data_RAM = 0x01,
371         L1_I_BTB_RAM = 0x02,
372         L1_I_GHB_RAM = 0x03,
373         L1_I_TLB_RAM = 0x04,
374         L1_I_indirect_predictor_RAM = 0x05,
375         L1_D_tag_RAM = 0x08,
376         L1_D_data_RAM = 0x09,
377         L1_D_load_TLB_array = 0x0A,
378         L1_D_store_TLB_array = 0x0B,
379         L2_tag_RAM = 0x10,
380         L2_data_RAM = 0x11,
381         L2_snoop_tag_RAM = 0x12,
382         L2_data_ECC_RAM = 0x13,
383         L2_dirty_RAM = 0x14,
384         L2_TLB_RAM = 0x18
385 } RAMID_type;
386
387 static inline void asm_ramindex_mrc(u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3)
388 {
389         u32 val;
390
391         if (DL1Data0) {
392                 asm volatile ("mrc p15, 0, %0, c15, c1, 0" : "=r" (val));
393                 *DL1Data0 = val;
394         }
395         if (DL1Data1) {
396                 asm volatile ("mrc p15, 0, %0, c15, c1, 1" : "=r" (val));
397                 *DL1Data1 = val;
398         }
399         if (DL1Data2) {
400                 asm volatile ("mrc p15, 0, %0, c15, c1, 2" : "=r" (val));
401                 *DL1Data2 = val;
402         }
403         if (DL1Data3) {
404                 asm volatile ("mrc p15, 0, %0, c15, c1, 3" : "=r" (val));
405                 *DL1Data3 = val;
406         }
407 }
408
409 static inline void asm_ramindex_mcr(u32 val)
410 {
411         asm volatile ("mcr p15, 0, %0, c15, c4, 0" : : "r" (val));
412         asm volatile ("dsb");
413         asm volatile ("isb");
414 }
415
416 static void get_tlb_array(u32 val, u32 *DL1Data0, u32 *DL1Data1, u32 *DL1Data2, u32 *DL1Data3)
417 {
418         asm_ramindex_mcr(val);
419         asm_ramindex_mrc(DL1Data0, DL1Data1, DL1Data2, DL1Data3);
420 }
421
422 static RAMID_type ramindex = L1_D_load_TLB_array;
423 static ssize_t show_dtlb(struct device *dev, struct device_attribute *attr, char *buf)
424 {
425         struct kbase_device *kbdev;
426         ssize_t ret = 0;
427         int entries, ways;
428         u32 DL1Data0 = 0, DL1Data1 = 0, DL1Data2 = 0, DL1Data3 = 0;
429
430         kbdev = dev_get_drvdata(dev);
431
432         if (!kbdev)
433                 return -ENODEV;
434
435         /* L1-I tag RAM */
436         if (ramindex == L1_I_tag_RAM)
437                 printk(KERN_DEBUG "Not implemented yet\n");
438         /* L1-I data RAM */
439         else if (ramindex == L1_I_data_RAM)
440                 printk(KERN_DEBUG "Not implemented yet\n");
441         /* L1-I BTB RAM */
442         else if (ramindex == L1_I_BTB_RAM)
443                 printk(KERN_DEBUG "Not implemented yet\n");
444         /* L1-I GHB RAM */
445         else if (ramindex == L1_I_GHB_RAM)
446                 printk(KERN_DEBUG "Not implemented yet\n");
447         /* L1-I TLB RAM */
448         else if (ramindex == L1_I_TLB_RAM) {
449                 printk(KERN_DEBUG "L1-I TLB RAM\n");
450                 for (entries = 0; entries < 32; entries++) {
451                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, NULL);
452                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x DL1Data2=%08x\n", entries, DL1Data0, DL1Data1 & 0xffff, 0x0);
453                 }
454         }
455         /* L1-I indirect predictor RAM */
456         else if (ramindex == L1_I_indirect_predictor_RAM)
457                 printk(KERN_DEBUG "Not implemented yet\n");
458         /* L1-D tag RAM */
459         else if (ramindex == L1_D_tag_RAM)
460                 printk(KERN_DEBUG "Not implemented yet\n");
461         /* L1-D data RAM */
462         else if (ramindex == L1_D_data_RAM)
463                 printk(KERN_DEBUG "Not implemented yet\n");
464         /* L1-D load TLB array */
465         else if (ramindex == L1_D_load_TLB_array) {
466                 printk(KERN_DEBUG "L1-D load TLB array\n");
467                 for (entries = 0; entries < 32; entries++) {
468                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
469                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f);
470                 }
471         }
472         /* L1-D store TLB array */
473         else if (ramindex == L1_D_store_TLB_array) {
474                 printk(KERN_DEBUG "\nL1-D store TLB array\n");
475                 for (entries = 0; entries < 32; entries++) {
476                         get_tlb_array((((u8) ramindex) << 24) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
477                         printk(KERN_DEBUG "entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3 & 0x3f);
478                 }
479         }
480         /* L2 tag RAM */
481         else if (ramindex == L2_tag_RAM)
482                 printk(KERN_DEBUG "Not implemented yet\n");
483         /* L2 data RAM */
484         else if (ramindex == L2_data_RAM)
485                 printk(KERN_DEBUG "Not implemented yet\n");
486         /* L2 snoop tag RAM */
487         else if (ramindex == L2_snoop_tag_RAM)
488                 printk(KERN_DEBUG "Not implemented yet\n");
489         /* L2 data ECC RAM */
490         else if (ramindex == L2_data_ECC_RAM)
491                 printk(KERN_DEBUG "Not implemented yet\n");
492         /* L2 dirty RAM */
493         else if (ramindex == L2_dirty_RAM)
494                 printk(KERN_DEBUG "Not implemented yet\n");
495
496         /* L2 TLB array */
497         else if (ramindex == L2_TLB_RAM) {
498                 printk(KERN_DEBUG "\nL2 TLB array\n");
499                 for (ways = 0; ways < 4; ways++) {
500                         for (entries = 0; entries < 512; entries++) {
501                                 get_tlb_array((ramindex << 24) + (ways << 18) + entries, &DL1Data0, &DL1Data1, &DL1Data2, &DL1Data3);
502                                 printk(KERN_DEBUG "ways[%d]:entries[%d], DL1Data0=%08x, DL1Data1=%08x, DL1Data2=%08x, DL1Data3=%08x\n", ways, entries, DL1Data0, DL1Data1, DL1Data2, DL1Data3);
503                         }
504                 }
505         } else {
506         }
507
508         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Succeeded...\n");
509
510         if (ret < PAGE_SIZE - 1)
511                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
512         else {
513                 buf[PAGE_SIZE - 2] = '\n';
514                 buf[PAGE_SIZE - 1] = '\0';
515                 ret = PAGE_SIZE - 1;
516         }
517         return ret;
518 }
519
520 static ssize_t set_dtlb(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
521 {
522         struct kbase_device *kbdev;
523         kbdev = dev_get_drvdata(dev);
524
525         if (!kbdev)
526                 return -ENODEV;
527
528         if (sysfs_streq("L1_I_tag_RAM", buf)) {
529                 ramindex = L1_I_tag_RAM;
530         } else if (sysfs_streq("L1_I_data_RAM", buf)) {
531                 ramindex = L1_I_data_RAM;
532         } else if (sysfs_streq("L1_I_BTB_RAM", buf)) {
533                 ramindex = L1_I_BTB_RAM;
534         } else if (sysfs_streq("L1_I_GHB_RAM", buf)) {
535                 ramindex = L1_I_GHB_RAM;
536         } else if (sysfs_streq("L1_I_TLB_RAM", buf)) {
537                 ramindex = L1_I_TLB_RAM;
538         } else if (sysfs_streq("L1_I_indirect_predictor_RAM", buf)) {
539                 ramindex = L1_I_indirect_predictor_RAM;
540         } else if (sysfs_streq("L1_D_tag_RAM", buf)) {
541                 ramindex = L1_D_tag_RAM;
542         } else if (sysfs_streq("L1_D_data_RAM", buf)) {
543                 ramindex = L1_D_data_RAM;
544         } else if (sysfs_streq("L1_D_load_TLB_array", buf)) {
545                 ramindex = L1_D_load_TLB_array;
546         } else if (sysfs_streq("L1_D_store_TLB_array", buf)) {
547                 ramindex = L1_D_store_TLB_array;
548         } else if (sysfs_streq("L2_tag_RAM", buf)) {
549                 ramindex = L2_tag_RAM;
550         } else if (sysfs_streq("L2_data_RAM", buf)) {
551                 ramindex = L2_data_RAM;
552         } else if (sysfs_streq("L2_snoop_tag_RAM", buf)) {
553                 ramindex = L2_snoop_tag_RAM;
554         } else if (sysfs_streq("L2_data_ECC_RAM", buf)) {
555                 ramindex = L2_data_ECC_RAM;
556         } else if (sysfs_streq("L2_dirty_RAM", buf)) {
557                 ramindex = L2_dirty_RAM;
558         } else if (sysfs_streq("L2_TLB_RAM", buf)) {
559                 ramindex = L2_TLB_RAM;
560         } else {
561                 printk(KERN_DEBUG "Invalid value....\n\n");
562                 printk(KERN_DEBUG "Available options are one of below\n");
563                 printk(KERN_DEBUG "L1_I_tag_RAM, L1_I_data_RAM, L1_I_BTB_RAM\n");
564                 printk(KERN_DEBUG "L1_I_GHB_RAM, L1_I_TLB_RAM, L1_I_indirect_predictor_RAM\n");
565                 printk(KERN_DEBUG "L1_D_tag_RAM, L1_D_data_RAM, L1_D_load_TLB_array, L1_D_store_TLB_array\n");
566                 printk(KERN_DEBUG "L2_tag_RAM, L2_data_RAM, L2_snoop_tag_RAM, L2_data_ECC_RAM\n");
567                 printk(KERN_DEBUG "L2_dirty_RAM, L2_TLB_RAM\n");
568         }
569
570         return count;
571 }
572
573 static ssize_t show_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
574 {
575         struct kbase_device *kbdev;
576         ssize_t ret = 0;
577
578         kbdev = dev_get_drvdata(dev);
579
580         if (!kbdev)
581                 return -ENODEV;
582
583 #ifdef CONFIG_MALI_MIDGARD_DVFS
584         if (kbase_platform_dvfs_get_enable_status())
585                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is on\nutilisation:%d", kbase_platform_dvfs_get_utilisation());
586         else
587                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali  DVFS is off");
588 #else
589         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali  DVFS is disabled");
590 #endif
591
592         if (ret < PAGE_SIZE - 1)
593                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
594         else {
595                 buf[PAGE_SIZE - 2] = '\n';
596                 buf[PAGE_SIZE - 1] = '\0';
597                 ret = PAGE_SIZE - 1;
598         }
599
600         return ret;
601 }
602
603 static ssize_t set_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
604 {
605         struct kbase_device *kbdev = dev_get_drvdata(dev);
606 #ifdef CONFIG_MALI_MIDGARD_DVFS
607         struct rk_context *platform;
608 #endif
609
610         if (!kbdev)
611                 return -ENODEV;
612
613 #ifdef CONFIG_MALI_MIDGARD_DVFS
614         platform = (struct rk_context *)kbdev->platform_context;
615         if (sysfs_streq("off", buf)) {
616                 //kbase_platform_dvfs_enable(false, MALI_DVFS_BL_CONFIG_FREQ);
617                 kbase_platform_dvfs_enable(false, p_mali_dvfs_infotbl[MALI_DVFS_STEP-1].clock); 
618                 platform->dvfs_enabled = false;
619         } else if (sysfs_streq("on", buf)) {
620                 //kbase_platform_dvfs_enable(true, MALI_DVFS_START_FREQ);
621                 kbase_platform_dvfs_enable(true, p_mali_dvfs_infotbl[0].clock);
622                 platform->dvfs_enabled = true;
623         } else {
624                 printk(KERN_DEBUG "invalid val -only [on, off] is accepted\n");
625         }
626 #else
627         printk(KERN_DEBUG "mali  DVFS is disabled\n");
628 #endif
629         return count;
630 }
631
632 static ssize_t show_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
633 {
634         struct kbase_device *kbdev;
635         ssize_t ret = 0;
636         int i;
637 #ifdef CONFIG_MALI_MIDGARD_DVFS
638         int locked_level = -1;
639 #endif
640
641         kbdev = dev_get_drvdata(dev);
642
643         if (!kbdev)
644                 return -ENODEV;
645
646 #ifdef CONFIG_MALI_MIDGARD_DVFS
647         locked_level = mali_get_dvfs_upper_locked_freq();
648         if (locked_level > 0)
649                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Upper Lock Level = %dMhz", locked_level);
650         else
651                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the Upper Lock Level");
652         //ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 400, 350,266, 160, 100, If you want to unlock : 600 or off");
653         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings :");
654         for(i=0;i<MALI_DVFS_STEP;i++)
655                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
656         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
657         ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : off");
658
659 #else
660         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set");
661 #endif
662
663         if (ret < PAGE_SIZE - 1)
664                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
665         else {
666                 buf[PAGE_SIZE - 2] = '\n';
667                 buf[PAGE_SIZE - 1] = '\0';
668                 ret = PAGE_SIZE - 1;
669         }
670
671         return ret;
672 }
673
674 static ssize_t set_upper_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
675 {
676         struct kbase_device *kbdev;
677         int i;
678         unsigned int freq;
679         kbdev = dev_get_drvdata(dev);
680         freq = 0;
681
682         if (!kbdev)
683                 return -ENODEV;
684
685 freq = simple_strtoul(buf, NULL, 10);
686
687 #ifdef CONFIG_MALI_MIDGARD_DVFS
688         if (sysfs_streq("off", buf)) 
689         {
690                 mali_dvfs_freq_unlock();
691         } 
692         else 
693         {
694                 for(i=0;i<MALI_DVFS_STEP;i++)
695                 {
696                         if (p_mali_dvfs_infotbl[i].clock == freq) 
697                         {
698                                 mali_dvfs_freq_lock(i);
699                                 break;
700                         }
701                         if(i==MALI_DVFS_STEP)
702                         {
703                                 dev_err(dev, "set_clock: invalid value\n");
704                                 return -ENOENT;
705                         }
706                 }
707         }
708 #else                           /* CONFIG_MALI_MIDGARD_DVFS */
709         printk(KERN_DEBUG "mali DVFS is disabled. You can not set\n");
710 #endif
711
712         return count;
713 }
714
715 static ssize_t show_under_lock_dvfs(struct device *dev, struct device_attribute *attr, char *buf)
716 {
717         struct kbase_device *kbdev;
718         ssize_t ret = 0;
719         int i;
720 #ifdef CONFIG_MALI_MIDGARD_DVFS
721         int locked_level = -1;
722 #endif
723
724         kbdev = dev_get_drvdata(dev);
725
726         if (!kbdev)
727                 return -ENODEV;
728
729 #ifdef CONFIG_MALI_MIDGARD_DVFS
730         locked_level = mali_get_dvfs_under_locked_freq();
731         if (locked_level > 0)
732                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Current Under Lock Level = %dMhz", locked_level);
733         else
734                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "Unset the Under Lock Level");
735         //ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings : 600, 400, 350,266, 160, If you want to unlock : 100 or off");
736         ret += snprintf(buf + ret, PAGE_SIZE - ret, "\nPossible settings :");
737         for(i=0;i<MALI_DVFS_STEP;i++)
738                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d ",p_mali_dvfs_infotbl[i].clock/1000);
739         ret += snprintf(buf + ret, PAGE_SIZE - ret, "Mhz");
740         ret += snprintf(buf + ret, PAGE_SIZE - ret, ", If you want to unlock : off");
741
742 #else
743         ret += snprintf(buf + ret, PAGE_SIZE - ret, "mali DVFS is disabled. You can not set");
744 #endif
745
746         if (ret < PAGE_SIZE - 1)
747                 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
748         else {
749                 buf[PAGE_SIZE - 2] = '\n';
750                 buf[PAGE_SIZE - 1] = '\0';
751                 ret = PAGE_SIZE - 1;
752         }
753
754         return ret;
755 }
756
757 static ssize_t set_under_lock_dvfs(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
758 {
759         int i;
760         unsigned int freq;
761         struct kbase_device *kbdev;
762         kbdev = dev_get_drvdata(dev);
763         freq = 0;
764
765         if (!kbdev)
766                 return -ENODEV;
767
768 #ifdef CONFIG_MALI_MIDGARD_DVFS
769         if (sysfs_streq("off", buf)) 
770         {
771                 mali_dvfs_freq_unlock();
772         } 
773         else 
774         {
775                 for(i=0;i<MALI_DVFS_STEP;i++)
776                 {
777                         if (p_mali_dvfs_infotbl[i].clock == freq) 
778                         {
779                                 mali_dvfs_freq_lock(i);
780                                 break;
781                         }
782                         if(i==MALI_DVFS_STEP)
783                         {
784                                 dev_err(dev, "set_clock: invalid value\n");
785                                 return -ENOENT;
786                         }
787                 }
788         }
789 #else                           /* CONFIG_MALI_MIDGARD_DVFS */
790         printk(KERN_DEBUG "mali DVFS is disabled. You can not set\n");
791 #endif
792         return count;
793 }
794
795 /** The sysfs file @c clock, fbdev.
796  *
797  * This is used for obtaining information about the mali t6xx operating clock & framebuffer address,
798  */
799 DEVICE_ATTR(clock, S_IRUGO | S_IWUSR, show_clock, set_clock);
800 DEVICE_ATTR(fbdev, S_IRUGO, show_fbdev, NULL);
801 DEVICE_ATTR(dtlb, S_IRUGO | S_IWUSR, show_dtlb, set_dtlb);
802 DEVICE_ATTR(dvfs, S_IRUGO | S_IWUSR, show_dvfs, set_dvfs);
803 DEVICE_ATTR(dvfs_upper_lock, S_IRUGO | S_IWUSR, show_upper_lock_dvfs, set_upper_lock_dvfs);
804 DEVICE_ATTR(dvfs_under_lock, S_IRUGO | S_IWUSR, show_under_lock_dvfs, set_under_lock_dvfs);
805 DEVICE_ATTR(time_in_state, S_IRUGO | S_IWUSR, show_time_in_state, set_time_in_state);
806
807 int kbase_platform_create_sysfs_file(struct device *dev)
808 {
809         if (device_create_file(dev, &dev_attr_clock)) {
810                 dev_err(dev, "Couldn't create sysfs file [clock]\n");
811                 goto out;
812         }
813
814         if (device_create_file(dev, &dev_attr_fbdev)) {
815                 dev_err(dev, "Couldn't create sysfs file [fbdev]\n");
816                 goto out;
817         }
818
819         if (device_create_file(dev, &dev_attr_dtlb)) {
820                 dev_err(dev, "Couldn't create sysfs file [dtlb]\n");
821                 goto out;
822         }
823
824         if (device_create_file(dev, &dev_attr_dvfs)) {
825                 dev_err(dev, "Couldn't create sysfs file [dvfs]\n");
826                 goto out;
827         }
828
829         if (device_create_file(dev, &dev_attr_dvfs_upper_lock)) {
830                 dev_err(dev, "Couldn't create sysfs file [dvfs_upper_lock]\n");
831                 goto out;
832         }
833
834         if (device_create_file(dev, &dev_attr_dvfs_under_lock)) {
835                 dev_err(dev, "Couldn't create sysfs file [dvfs_under_lock]\n");
836                 goto out;
837         }
838
839         if (device_create_file(dev, &dev_attr_time_in_state)) {
840                 dev_err(dev, "Couldn't create sysfs file [time_in_state]\n");
841                 goto out;
842         }
843         return 0;
844  out:
845         return -ENOENT;
846 }
847
848 void kbase_platform_remove_sysfs_file(struct device *dev)
849 {
850         device_remove_file(dev, &dev_attr_clock);
851         device_remove_file(dev, &dev_attr_fbdev);
852         device_remove_file(dev, &dev_attr_dtlb);
853         device_remove_file(dev, &dev_attr_dvfs);
854         device_remove_file(dev, &dev_attr_dvfs_upper_lock);
855         device_remove_file(dev, &dev_attr_dvfs_under_lock);
856         device_remove_file(dev, &dev_attr_time_in_state);
857 }
858 #endif                          /* CONFIG_MALI_MIDGARD_DEBUG_SYS */
859
860 mali_error kbase_platform_init(struct kbase_device *kbdev)
861 {
862         struct rk_context *platform;
863
864         platform = kmalloc(sizeof(struct rk_context), GFP_KERNEL);
865
866         if (NULL == platform)
867                 return MALI_ERROR_OUT_OF_MEMORY;
868
869         kbdev->platform_context = (void *)platform;
870
871         platform->cmu_pmu_status = 0;
872 #ifdef CONFIG_MALI_MIDGARD_DVFS
873         platform->utilisation = 0;
874         platform->time_busy = 0;
875         platform->time_idle = 0;
876         platform->time_tick = 0;
877         platform->dvfs_enabled = true;
878 #endif
879
880         spin_lock_init(&platform->cmu_pmu_lock);
881
882         if (kbase_platform_power_clock_init(kbdev))
883                 goto clock_init_fail;
884
885 #ifdef CONFIG_MALI_MIDGARD_DVFS
886         kbase_platform_dvfs_init(kbdev);
887 #endif                          /* CONFIG_MALI_MIDGARD_DVFS */
888
889         /* Enable power */
890         kbase_platform_cmu_pmu_control(kbdev, 1);
891         return MALI_ERROR_NONE;
892
893  clock_init_fail:
894         kfree(platform);
895
896         return MALI_ERROR_FUNCTION_FAILED;
897 }
898
899 void kbase_platform_term(kbase_device *kbdev)
900 {
901         struct rk_context *platform;
902
903         platform = (struct rk_context *)kbdev->platform_context;
904
905 #ifdef CONFIG_MALI_MIDGARD_DVFS
906         kbase_platform_dvfs_term();
907 #endif                          /* CONFIG_MALI_MIDGARD_DVFS */
908
909         /* Disable power */
910         kbase_platform_cmu_pmu_control(kbdev, 0);
911         kfree(kbdev->platform_context);
912         kbdev->platform_context = 0;
913         return;
914 }