2 * Copyright 2010 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
25 #ifndef __NOUVEAU_PM_H__
26 #define __NOUVEAU_PM_H__
28 #include <subdev/bios/pll.h>
29 #include <subdev/clock.h>
31 struct nouveau_pm_voltage_level
{
32 u32 voltage
; /* microvolts */
36 struct nouveau_pm_voltage
{
41 struct nouveau_pm_voltage_level
*level
;
45 /* Exclusive upper limits */
46 #define NV_MEM_CL_DDR2_MAX 8
47 #define NV_MEM_WR_DDR2_MAX 9
48 #define NV_MEM_CL_DDR3_MAX 17
49 #define NV_MEM_WR_DDR3_MAX 17
50 #define NV_MEM_CL_GDDR3_MAX 16
51 #define NV_MEM_WR_GDDR3_MAX 18
52 #define NV_MEM_CL_GDDR5_MAX 21
53 #define NV_MEM_WR_GDDR5_MAX 20
55 struct nouveau_pm_memtiming
{
67 struct nouveau_pm_tbl_header
{
74 struct nouveau_pm_tbl_entry
{
89 u8 RAM_FT1
; /* 14, a bitmask of random RAM features */
98 struct nouveau_pm_profile
;
99 struct nouveau_pm_profile_func
{
100 void (*destroy
)(struct nouveau_pm_profile
*);
101 void (*init
)(struct nouveau_pm_profile
*);
102 void (*fini
)(struct nouveau_pm_profile
*);
103 struct nouveau_pm_level
*(*select
)(struct nouveau_pm_profile
*);
106 struct nouveau_pm_profile
{
107 const struct nouveau_pm_profile_func
*func
;
108 struct list_head head
;
112 #define NOUVEAU_PM_MAX_LEVEL 8
113 struct nouveau_pm_level
{
114 struct nouveau_pm_profile profile
;
115 struct device_attribute dev_attr
;
119 struct nouveau_pm_memtiming timing
;
130 u32 unka0
; /* nva3:nvc0 */
131 u32 hub01
; /* nvc0- */
132 u32 hub06
; /* nvc0- */
133 u32 hub07
; /* nvc0- */
135 u32 volt_min
; /* microvolts */
140 struct nouveau_pm_temp_sensor_constants
{
148 struct nouveau_pm_threshold_temp
{
154 struct drm_device
*dev
;
156 struct nouveau_pm_voltage voltage
;
157 struct nouveau_pm_level perflvl
[NOUVEAU_PM_MAX_LEVEL
];
159 struct nouveau_pm_temp_sensor_constants sensor_constants
;
160 struct nouveau_pm_threshold_temp threshold_temp
;
162 struct nouveau_pm_profile
*profile_ac
;
163 struct nouveau_pm_profile
*profile_dc
;
164 struct nouveau_pm_profile
*profile
;
165 struct list_head profiles
;
167 struct nouveau_pm_level boot
;
168 struct nouveau_pm_level
*cur
;
170 struct device
*hwmon
;
171 struct notifier_block acpi_nb
;
173 int (*clocks_get
)(struct drm_device
*, struct nouveau_pm_level
*);
174 void *(*clocks_pre
)(struct drm_device
*, struct nouveau_pm_level
*);
175 int (*clocks_set
)(struct drm_device
*, void *);
177 int (*voltage_get
)(struct drm_device
*);
178 int (*voltage_set
)(struct drm_device
*, int voltage
);
181 static inline struct nouveau_pm
*
182 nouveau_pm(struct drm_device
*dev
)
184 return nouveau_drm(dev
)->pm
;
187 struct nouveau_mem_exec_func
{
188 struct drm_device
*dev
;
189 void (*precharge
)(struct nouveau_mem_exec_func
*);
190 void (*refresh
)(struct nouveau_mem_exec_func
*);
191 void (*refresh_auto
)(struct nouveau_mem_exec_func
*, bool);
192 void (*refresh_self
)(struct nouveau_mem_exec_func
*, bool);
193 void (*wait
)(struct nouveau_mem_exec_func
*, u32 nsec
);
194 u32 (*mrg
)(struct nouveau_mem_exec_func
*, int mr
);
195 void (*mrs
)(struct nouveau_mem_exec_func
*, int mr
, u32 data
);
196 void (*clock_set
)(struct nouveau_mem_exec_func
*);
197 void (*timing_set
)(struct nouveau_mem_exec_func
*);
202 int nouveau_mem_exec(struct nouveau_mem_exec_func
*,
203 struct nouveau_pm_level
*);
206 int nouveau_pm_init(struct drm_device
*dev
);
207 void nouveau_pm_fini(struct drm_device
*dev
);
208 void nouveau_pm_resume(struct drm_device
*dev
);
209 extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func
;
210 void nouveau_pm_trigger(struct drm_device
*dev
);
213 void nouveau_volt_init(struct drm_device
*);
214 void nouveau_volt_fini(struct drm_device
*);
215 int nouveau_volt_vid_lookup(struct drm_device
*, int voltage
);
216 int nouveau_volt_lvl_lookup(struct drm_device
*, int vid
);
217 int nouveau_voltage_gpio_get(struct drm_device
*);
218 int nouveau_voltage_gpio_set(struct drm_device
*, int voltage
);
221 void nouveau_perf_init(struct drm_device
*);
222 void nouveau_perf_fini(struct drm_device
*);
223 u8
*nouveau_perf_rammap(struct drm_device
*, u32 freq
, u8
*ver
,
224 u8
*hdr
, u8
*cnt
, u8
*len
);
225 u8
*nouveau_perf_ramcfg(struct drm_device
*, u32 freq
, u8
*ver
, u8
*len
);
226 u8
*nouveau_perf_timing(struct drm_device
*, u32 freq
, u8
*ver
, u8
*len
);
229 void nouveau_mem_timing_init(struct drm_device
*);
230 void nouveau_mem_timing_fini(struct drm_device
*);
233 int nv04_pm_clocks_get(struct drm_device
*, struct nouveau_pm_level
*);
234 void *nv04_pm_clocks_pre(struct drm_device
*, struct nouveau_pm_level
*);
235 int nv04_pm_clocks_set(struct drm_device
*, void *);
238 int nv40_pm_clocks_get(struct drm_device
*, struct nouveau_pm_level
*);
239 void *nv40_pm_clocks_pre(struct drm_device
*, struct nouveau_pm_level
*);
240 int nv40_pm_clocks_set(struct drm_device
*, void *);
241 int nv40_pm_pwm_get(struct drm_device
*, int, u32
*, u32
*);
242 int nv40_pm_pwm_set(struct drm_device
*, int, u32
, u32
);
245 int nv50_pm_clocks_get(struct drm_device
*, struct nouveau_pm_level
*);
246 void *nv50_pm_clocks_pre(struct drm_device
*, struct nouveau_pm_level
*);
247 int nv50_pm_clocks_set(struct drm_device
*, void *);
248 int nv50_pm_pwm_get(struct drm_device
*, int, u32
*, u32
*);
249 int nv50_pm_pwm_set(struct drm_device
*, int, u32
, u32
);
252 int nva3_pm_clocks_get(struct drm_device
*, struct nouveau_pm_level
*);
253 void *nva3_pm_clocks_pre(struct drm_device
*, struct nouveau_pm_level
*);
254 int nva3_pm_clocks_set(struct drm_device
*, void *);
257 int nvc0_pm_clocks_get(struct drm_device
*, struct nouveau_pm_level
*);
258 void *nvc0_pm_clocks_pre(struct drm_device
*, struct nouveau_pm_level
*);
259 int nvc0_pm_clocks_set(struct drm_device
*, void *);
262 int nouveau_mem_timing_calc(struct drm_device
*, u32 freq
,
263 struct nouveau_pm_memtiming
*);
264 void nouveau_mem_timing_read(struct drm_device
*,
265 struct nouveau_pm_memtiming
*);
268 nva3_calc_pll(struct drm_device
*dev
, struct nvbios_pll
*pll
, u32 freq
,
269 int *N
, int *fN
, int *M
, int *P
)
271 struct nouveau_device
*device
= nouveau_dev(dev
);
272 struct nouveau_clock
*clk
= nouveau_clock(device
);
273 struct nouveau_pll_vals pv
;
276 ret
= clk
->pll_calc(clk
, pll
, freq
, &pv
);