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.
26 #include "nouveau_drv.h"
27 #include "nouveau_bios.h"
28 #include "nouveau_pm.h"
30 /* This is actually a lot more complex than it appears here, but hopefully
31 * this should be able to deal with what the VBIOS leaves for us..
33 * If not, well, I'll jump off that bridge when I come to it.
36 struct nva3_pm_state
{
48 nva3_pm_pll_offset(u32 id
)
50 static const u32 pll_map
[] = {
56 const u32
*map
= pll_map
;
68 nva3_pm_clock_get(struct drm_device
*dev
, u32 id
)
70 u32 src0
, src1
, ctrl
, coef
;
75 ret
= get_pll_limits(dev
, id
, &pll
);
79 off
= nva3_pm_pll_offset(id
);
83 src0
= nv_rd32(dev
, 0x4120 + (off
* 4));
84 src1
= nv_rd32(dev
, 0x4160 + (off
* 4));
85 ctrl
= nv_rd32(dev
, pll
.reg
+ 0);
86 coef
= nv_rd32(dev
, pll
.reg
+ 4);
87 NV_DEBUG(dev
, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
88 id
, src0
, src1
, ctrl
, coef
);
90 if (ctrl
& 0x00000008) {
91 u32 div
= ((src1
& 0x003c0000) >> 18) + 1;
92 return (pll
.refclk
* 2) / div
;
95 P
= (coef
& 0x003f0000) >> 16;
96 N
= (coef
& 0x0000ff00) >> 8;
97 M
= (coef
& 0x000000ff);
98 return pll
.refclk
* N
/ M
/ P
;
102 nva3_pm_clock_pre(struct drm_device
*dev
, struct nouveau_pm_level
*perflvl
,
105 struct nva3_pm_state
*pll
;
106 struct pll_lims limits
;
110 ret
= get_pll_limits(dev
, id
, &limits
);
112 return (ret
== -ENOENT
) ? NULL
: ERR_PTR(ret
);
114 off
= nva3_pm_pll_offset(id
);
116 return ERR_PTR(-EINVAL
);
119 pll
= kzalloc(sizeof(*pll
), GFP_KERNEL
);
121 return ERR_PTR(-ENOMEM
);
123 pll
->src0
= 0x004120 + (off
* 4);
124 pll
->src1
= 0x004160 + (off
* 4);
125 pll
->ctrl
= limits
.reg
+ 0;
126 pll
->coef
= limits
.reg
+ 4;
128 /* If target clock is within [-2, 3) MHz of a divisor, we'll
129 * use that instead of calculating MNP values
131 pll
->new_div
= min((limits
.refclk
* 2) / (khz
- 2999), 16);
133 diff
= khz
- ((limits
.refclk
* 2) / pll
->new_div
);
134 if (diff
< -2000 || diff
>= 3000)
139 ret
= nva3_calc_pll(dev
, &limits
, khz
, &N
, NULL
, &M
, &P
);
143 pll
->new_pnm
= (P
<< 16) | (N
<< 8) | M
;
144 pll
->new_div
= 2 - 1;
150 if ((nv_rd32(dev
, pll
->src1
) & 0x00000101) != 0x00000101)
151 pll
->old_pnm
= nv_rd32(dev
, pll
->coef
);
156 nva3_pm_clock_set(struct drm_device
*dev
, void *pre_state
)
158 struct nva3_pm_state
*pll
= pre_state
;
161 /* For the memory clock, NVIDIA will build a "script" describing
162 * the reclocking process and ask PDAEMON to execute it.
164 if (pll
->type
== PLL_MEMORY
) {
165 nv_wr32(dev
, 0x100210, 0);
166 nv_wr32(dev
, 0x1002dc, 1);
167 nv_wr32(dev
, 0x004018, 0x00001000);
171 if (pll
->old_pnm
|| !pll
->new_pnm
) {
172 nv_mask(dev
, pll
->src1
, 0x003c0101, 0x00000101 |
173 (pll
->new_div
<< 18));
174 nv_wr32(dev
, pll
->ctrl
, 0x0001001d | ctrl
);
175 nv_mask(dev
, pll
->ctrl
, 0x00000001, 0x00000000);
179 nv_mask(dev
, pll
->src0
, 0x00000101, 0x00000101);
180 nv_wr32(dev
, pll
->coef
, pll
->new_pnm
);
181 nv_wr32(dev
, pll
->ctrl
, 0x0001001d | ctrl
);
182 nv_mask(dev
, pll
->ctrl
, 0x00000010, 0x00000000);
183 nv_mask(dev
, pll
->ctrl
, 0x00020010, 0x00020010);
184 nv_wr32(dev
, pll
->ctrl
, 0x00010015 | ctrl
);
185 nv_mask(dev
, pll
->src1
, 0x00000100, 0x00000000);
186 nv_mask(dev
, pll
->src1
, 0x00000001, 0x00000000);
187 if (pll
->type
== PLL_MEMORY
)
188 nv_wr32(dev
, 0x4018, 0x10005000);
190 nv_mask(dev
, pll
->ctrl
, 0x00000001, 0x00000000);
191 nv_mask(dev
, pll
->src0
, 0x00000100, 0x00000000);
192 nv_mask(dev
, pll
->src0
, 0x00000001, 0x00000000);
193 if (pll
->type
== PLL_MEMORY
)
194 nv_wr32(dev
, 0x4018, 0x1000d000);
197 if (pll
->type
== PLL_MEMORY
) {
198 nv_wr32(dev
, 0x1002dc, 0);
199 nv_wr32(dev
, 0x100210, 0x80000000);