• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010, 2012-2017 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10 
11 /**
12  * @file juno_opp.c
13  * Example: Set up opp table
14  * Using ARM64 juno specific SCPI_PROTOCOL get frequence inform
15  * Customer need implement your own platform releated logic
16  */
17 #ifdef CONFIG_ARCH_VEXPRESS
18 #ifdef CONFIG_MALI_DEVFREQ
19 #ifdef CONFIG_ARM64
20 #ifdef CONFIG_ARM_SCPI_PROTOCOL
21 #include <linux/module.h>
22 #include <linux/of_platform.h>
23 #include <linux/platform_device.h>
24 #include <linux/scpi_protocol.h>
25 #include <linux/version.h>
26 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
27 #include <linux/pm_opp.h>
28 #else /* Linux >= 3.13 */
29 /* In 3.13 the OPP include header file, types, and functions were all
30  * renamed. Use the old filename for the include, and define the new names to
31  * the old, when an old kernel is detected.
32  */
33 #include <linux/opp.h>
34 #define dev_pm_opp_add opp_add
35 #define dev_pm_opp_remove opp_remove
36 #endif /* Linux >= 3.13 */
37 
38 #include "mali_kernel_common.h"
39 
init_juno_opps_from_scpi(struct device * dev)40 static int init_juno_opps_from_scpi(struct device *dev)
41 {
42 	struct scpi_dvfs_info *sinfo;
43 	struct scpi_ops *sops;
44 
45 	int i;
46 
47 	sops = get_scpi_ops();
48 	if (NULL == sops) {
49 		MALI_DEBUG_PRINT(2, ("Mali didn't get any scpi ops \n"));
50 		return -1;
51 	}
52 
53 	/* Hard coded for Juno. 2 is GPU domain */
54 	sinfo = sops->dvfs_get_info(2);
55 	if (IS_ERR_OR_NULL(sinfo))
56 		return PTR_ERR(sinfo);
57 
58 	for (i = 0; i < sinfo->count; i++) {
59 		struct scpi_opp *e = &sinfo->opps[i];
60 
61 		MALI_DEBUG_PRINT(2, ("Mali OPP from SCPI: %u Hz @ %u mV\n", e->freq, e->m_volt));
62 
63 		dev_pm_opp_add(dev, e->freq, e->m_volt * 1000);
64 	}
65 
66 	return 0;
67 }
68 
setup_opps(void)69 int setup_opps(void)
70 {
71 	struct device_node *np;
72 	struct platform_device *pdev;
73 	int err;
74 
75 	np = of_find_node_by_name(NULL, "gpu");
76 	if (!np) {
77 		pr_err("Failed to find DT entry for Mali\n");
78 		return -EFAULT;
79 	}
80 
81 	pdev = of_find_device_by_node(np);
82 	if (!pdev) {
83 		pr_err("Failed to find device for Mali\n");
84 		of_node_put(np);
85 		return -EFAULT;
86 	}
87 
88 	err = init_juno_opps_from_scpi(&pdev->dev);
89 
90 	of_node_put(np);
91 
92 	return err;
93 }
94 
term_opps(struct device * dev)95 int term_opps(struct device *dev)
96 {
97 	struct scpi_dvfs_info *sinfo;
98 	struct scpi_ops *sops;
99 
100 	int i;
101 
102 	sops = get_scpi_ops();
103 	if (NULL == sops) {
104 		MALI_DEBUG_PRINT(2, ("Mali didn't get any scpi ops \n"));
105 		return -1;
106 	}
107 
108 	/* Hard coded for Juno. 2 is GPU domain */
109 	sinfo = sops->dvfs_get_info(2);
110 	if (IS_ERR_OR_NULL(sinfo))
111 		return PTR_ERR(sinfo);
112 
113 	for (i = 0; i < sinfo->count; i++) {
114 		struct scpi_opp *e = &sinfo->opps[i];
115 
116 		MALI_DEBUG_PRINT(2, ("Mali Remove OPP: %u Hz \n", e->freq));
117 
118 		dev_pm_opp_remove(dev, e->freq);
119 	}
120 
121 	return 0;
122 
123 }
124 #endif
125 #endif
126 #endif
127 #endif
128