2 * linux/arch/arm/mach-omap2/resource34xx.c
3 * OMAP3 resource init/change_level/validate_level functions
5 * Copyright (C) 2007-2008 Texas Instruments, Inc.
6 * Rajendra Nayak <rnayak@ti.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 #include <linux/pm_qos_params.h>
21 #include <plat/powerdomain.h>
22 #include <plat/clockdomain.h>
24 #include "smartreflex.h"
25 #include "resource34xx.h"
29 * init_latency - Initializes the mpu/core latency resource.
30 * @resp: Latency resource to be initalized
34 void init_latency(struct shared_resource
*resp
)
36 resp
->no_of_users
= 0;
37 resp
->curr_level
= RES_DEFAULTLEVEL
;
38 *((u8
*)resp
->resource_data
) = 0;
43 * set_latency - Adds/Updates and removes the CPU_DMA_LATENCY in *pm_qos_params.
44 * @resp: resource pointer
45 * @latency: target latency to be set
47 * Returns 0 on success, or error values as returned by
48 * pm_qos_update_requirement/pm_qos_add_requirement.
50 int set_latency(struct shared_resource
*resp
, u32 latency
)
54 if (resp
->curr_level
== latency
)
57 /* Update the resources current level */
58 resp
->curr_level
= latency
;
60 pm_qos_req_added
= resp
->resource_data
;
61 if (latency
== RES_DEFAULTLEVEL
)
62 /* No more users left, remove the pm_qos_req if present */
63 if (*pm_qos_req_added
) {
64 pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY
,
66 *pm_qos_req_added
= 0;
70 if (*pm_qos_req_added
) {
71 return pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY
,
74 *pm_qos_req_added
= 1;
75 return pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY
,
81 * init_pd_latency - Initializes the power domain latency resource.
82 * @resp: Power Domain Latency resource to be initialized.
86 void init_pd_latency(struct shared_resource
*resp
)
88 struct pd_latency_db
*pd_lat_db
;
90 resp
->no_of_users
= 0;
92 resp
->curr_level
= PD_LATENCY_OFF
;
94 resp
->curr_level
= PD_LATENCY_RET
;
95 pd_lat_db
= resp
->resource_data
;
96 /* Populate the power domain associated with the latency resource */
97 pd_lat_db
->pd
= pwrdm_lookup(pd_lat_db
->pwrdm_name
);
98 set_pwrdm_state(pd_lat_db
->pd
, resp
->curr_level
);
103 * set_pd_latency - Updates the curr_level of the power domain resource.
104 * @resp: Power domain latency resource.
105 * @latency: New latency value acceptable.
107 * This function maps the latency in microsecs to the acceptable
108 * Power domain state using the latency DB.
109 * It then programs the power domain to enter the target state.
112 int set_pd_latency(struct shared_resource
*resp
, u32 latency
)
114 u32 pd_lat_level
, ind
;
115 struct pd_latency_db
*pd_lat_db
;
116 struct powerdomain
*pwrdm
;
118 pd_lat_db
= resp
->resource_data
;
119 pwrdm
= pd_lat_db
->pd
;
120 pd_lat_level
= PD_LATENCY_OFF
;
121 /* using the latency db map to the appropriate PD state */
122 for (ind
= 0; ind
< PD_LATENCY_MAXLEVEL
; ind
++) {
123 if (pd_lat_db
->latency
[ind
] < latency
) {
129 if (!enable_off_mode
&& pd_lat_level
== PD_LATENCY_OFF
)
130 pd_lat_level
= PD_LATENCY_RET
;
132 resp
->curr_level
= pd_lat_level
;
133 set_pwrdm_state(pwrdm
, pd_lat_level
);
137 static struct clk
*vdd1_clk
;
138 static struct clk
*vdd2_clk
;
139 static struct device dummy_srf_dev
;
142 * init_opp - Initialize the OPP resource
144 void init_opp(struct shared_resource
*resp
)
146 resp
->no_of_users
= 0;
147 /* Initialize the current level of the OPP resource
148 * to the opp set by u-boot.
150 if (strcmp(resp
->name
, "vdd1_opp") == 0) {
151 resp
->curr_level
= curr_vdd1_prcm_set
->opp_id
;
152 vdd1_clk
= clk_get(NULL
, "virt_vdd1_prcm_set");
153 } else if (strcmp(resp
->name
, "vdd2_opp") == 0) {
154 resp
->curr_level
= curr_vdd2_prcm_set
->opp_id
;
155 vdd2_clk
= clk_get(NULL
, "virt_vdd2_prcm_set");
160 int set_opp(struct shared_resource
*resp
, u32 target_level
)
162 unsigned long mpu_freq
;
164 if (resp
->curr_level
== target_level
)
167 if (strcmp(resp
->name
, "vdd1_opp") == 0) {
168 mpu_freq
= get_freq(mpu_opps
+ MAX_VDD1_OPP
,
170 if (resp
->curr_level
> target_level
) {
171 /* Scale Frequency and then voltage */
172 clk_set_rate(vdd1_clk
, mpu_freq
);
173 sr_voltagescale_vcbypass(PRCM_VDD1
,
174 mpu_opps
[target_level
-1].vsel
);
176 /* Scale Voltage and then frequency */
177 sr_voltagescale_vcbypass(PRCM_VDD1
,
178 mpu_opps
[target_level
-1].vsel
);
179 clk_set_rate(vdd1_clk
, mpu_freq
);
181 resp
->curr_level
= curr_vdd1_prcm_set
->opp_id
;
182 } else if (strcmp(resp
->name
, "vdd2_opp") == 0) {
183 /* Not supported yet */
189 * validate_opp - Validates if valid VDD1 OPP's are passed as the
191 * VDD2 OPP levels are passed as L3 throughput, which are then mapped
192 * to an appropriate OPP.
194 int validate_opp(struct shared_resource
*resp
, u32 target_level
)
200 * init_freq - Initialize the frequency resource.
202 void init_freq(struct shared_resource
*resp
)
204 char *linked_res_name
;
205 resp
->no_of_users
= 0;
207 linked_res_name
= (char *)resp
->resource_data
;
208 /* Initialize the current level of the Freq resource
209 * to the frequency set by u-boot.
211 if (strcmp(resp
->name
, "mpu_freq") == 0)
212 /* MPU freq in Mhz */
213 resp
->curr_level
= curr_vdd1_prcm_set
->rate
;
214 else if (strcmp(resp
->name
, "dsp_freq") == 0)
215 /* DSP freq in Mhz */
216 resp
->curr_level
= get_freq(dsp_opps
+ MAX_VDD2_OPP
,
217 curr_vdd1_prcm_set
->opp_id
);
221 int set_freq(struct shared_resource
*resp
, u32 target_level
)
223 unsigned int vdd1_opp
;
225 if (strcmp(resp
->name
, "mpu_freq") == 0)
226 vdd1_opp
= get_opp(mpu_opps
+ MAX_VDD1_OPP
, target_level
);
227 else if (strcmp(resp
->name
, "dsp_freq") == 0)
228 vdd1_opp
= get_opp(dsp_opps
+ MAX_VDD1_OPP
, target_level
);
230 if (vdd1_opp
== MIN_VDD1_OPP
)
231 resource_release("vdd1_opp", &dummy_srf_dev
);
233 resource_request("vdd1_opp", &dummy_srf_dev
, vdd1_opp
);
235 resp
->curr_level
= target_level
;
239 int validate_freq(struct shared_resource
*resp
, u32 target_level
)