Rev 5078 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5078 | Rev 6104 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright 2011 Advanced Micro Devices, Inc. |
2 | * Copyright 2011 Advanced Micro Devices, Inc. |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
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 |
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: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice shall be included in |
11 | * The above copyright notice and this permission notice shall be included in |
12 | * all copies or substantial portions of the Software. |
12 | * all copies or substantial portions of the Software. |
13 | * |
13 | * |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
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, |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
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 |
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, |
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 |
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
20 | * OTHER DEALINGS IN THE SOFTWARE. |
21 | * |
21 | * |
22 | * Authors: Alex Deucher |
22 | * Authors: Alex Deucher |
23 | */ |
23 | */ |
24 | 24 | ||
25 | #include "drmP.h" |
25 | #include "drmP.h" |
26 | #include "radeon.h" |
26 | #include "radeon.h" |
27 | #include "rv730d.h" |
27 | #include "rv730d.h" |
28 | #include "r600_dpm.h" |
28 | #include "r600_dpm.h" |
29 | #include "rv770_dpm.h" |
29 | #include "rv770_dpm.h" |
30 | #include "atom.h" |
30 | #include "atom.h" |
31 | 31 | ||
32 | #define MC_CG_ARB_FREQ_F0 0x0a |
32 | #define MC_CG_ARB_FREQ_F0 0x0a |
33 | #define MC_CG_ARB_FREQ_F1 0x0b |
33 | #define MC_CG_ARB_FREQ_F1 0x0b |
34 | #define MC_CG_ARB_FREQ_F2 0x0c |
34 | #define MC_CG_ARB_FREQ_F2 0x0c |
35 | #define MC_CG_ARB_FREQ_F3 0x0d |
35 | #define MC_CG_ARB_FREQ_F3 0x0d |
36 | 36 | ||
37 | struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); |
37 | struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); |
38 | struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); |
38 | struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); |
39 | 39 | ||
40 | int rv730_populate_sclk_value(struct radeon_device *rdev, |
40 | int rv730_populate_sclk_value(struct radeon_device *rdev, |
41 | u32 engine_clock, |
41 | u32 engine_clock, |
42 | RV770_SMC_SCLK_VALUE *sclk) |
42 | RV770_SMC_SCLK_VALUE *sclk) |
43 | { |
43 | { |
44 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
44 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
45 | struct atom_clock_dividers dividers; |
45 | struct atom_clock_dividers dividers; |
46 | u32 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl; |
46 | u32 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl; |
47 | u32 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2; |
47 | u32 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2; |
48 | u32 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3; |
48 | u32 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3; |
49 | u32 cg_spll_spread_spectrum = pi->clk_regs.rv730.cg_spll_spread_spectrum; |
49 | u32 cg_spll_spread_spectrum = pi->clk_regs.rv730.cg_spll_spread_spectrum; |
50 | u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv730.cg_spll_spread_spectrum_2; |
50 | u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv730.cg_spll_spread_spectrum_2; |
51 | u64 tmp; |
51 | u64 tmp; |
52 | u32 reference_clock = rdev->clock.spll.reference_freq; |
52 | u32 reference_clock = rdev->clock.spll.reference_freq; |
53 | u32 reference_divider, post_divider; |
53 | u32 reference_divider, post_divider; |
54 | u32 fbdiv; |
54 | u32 fbdiv; |
55 | int ret; |
55 | int ret; |
56 | 56 | ||
57 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, |
57 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, |
58 | engine_clock, false, ÷rs); |
58 | engine_clock, false, ÷rs); |
59 | if (ret) |
59 | if (ret) |
60 | return ret; |
60 | return ret; |
61 | 61 | ||
62 | reference_divider = 1 + dividers.ref_div; |
62 | reference_divider = 1 + dividers.ref_div; |
63 | 63 | ||
64 | if (dividers.enable_post_div) |
64 | if (dividers.enable_post_div) |
65 | post_divider = ((dividers.post_div >> 4) & 0xf) + |
65 | post_divider = ((dividers.post_div >> 4) & 0xf) + |
66 | (dividers.post_div & 0xf) + 2; |
66 | (dividers.post_div & 0xf) + 2; |
67 | else |
67 | else |
68 | post_divider = 1; |
68 | post_divider = 1; |
69 | 69 | ||
70 | tmp = (u64) engine_clock * reference_divider * post_divider * 16384; |
70 | tmp = (u64) engine_clock * reference_divider * post_divider * 16384; |
71 | do_div(tmp, reference_clock); |
71 | do_div(tmp, reference_clock); |
72 | fbdiv = (u32) tmp; |
72 | fbdiv = (u32) tmp; |
73 | 73 | ||
74 | /* set up registers */ |
74 | /* set up registers */ |
75 | if (dividers.enable_post_div) |
75 | if (dividers.enable_post_div) |
76 | spll_func_cntl |= SPLL_DIVEN; |
76 | spll_func_cntl |= SPLL_DIVEN; |
77 | else |
77 | else |
78 | spll_func_cntl &= ~SPLL_DIVEN; |
78 | spll_func_cntl &= ~SPLL_DIVEN; |
79 | spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK); |
79 | spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK); |
80 | spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div); |
80 | spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div); |
81 | spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf); |
81 | spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf); |
82 | spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf); |
82 | spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf); |
83 | 83 | ||
84 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
84 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
85 | spll_func_cntl_2 |= SCLK_MUX_SEL(2); |
85 | spll_func_cntl_2 |= SCLK_MUX_SEL(2); |
86 | 86 | ||
87 | spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK; |
87 | spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK; |
88 | spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv); |
88 | spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv); |
89 | spll_func_cntl_3 |= SPLL_DITHEN; |
89 | spll_func_cntl_3 |= SPLL_DITHEN; |
90 | 90 | ||
91 | if (pi->sclk_ss) { |
91 | if (pi->sclk_ss) { |
92 | struct radeon_atom_ss ss; |
92 | struct radeon_atom_ss ss; |
93 | u32 vco_freq = engine_clock * post_divider; |
93 | u32 vco_freq = engine_clock * post_divider; |
94 | 94 | ||
95 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
95 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
96 | ASIC_INTERNAL_ENGINE_SS, vco_freq)) { |
96 | ASIC_INTERNAL_ENGINE_SS, vco_freq)) { |
97 | u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate); |
97 | u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate); |
98 | u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000); |
98 | u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000); |
99 | 99 | ||
100 | cg_spll_spread_spectrum &= ~CLK_S_MASK; |
100 | cg_spll_spread_spectrum &= ~CLK_S_MASK; |
101 | cg_spll_spread_spectrum |= CLK_S(clk_s); |
101 | cg_spll_spread_spectrum |= CLK_S(clk_s); |
102 | cg_spll_spread_spectrum |= SSEN; |
102 | cg_spll_spread_spectrum |= SSEN; |
103 | 103 | ||
104 | cg_spll_spread_spectrum_2 &= ~CLK_V_MASK; |
104 | cg_spll_spread_spectrum_2 &= ~CLK_V_MASK; |
105 | cg_spll_spread_spectrum_2 |= CLK_V(clk_v); |
105 | cg_spll_spread_spectrum_2 |= CLK_V(clk_v); |
106 | } |
106 | } |
107 | } |
107 | } |
108 | 108 | ||
109 | sclk->sclk_value = cpu_to_be32(engine_clock); |
109 | sclk->sclk_value = cpu_to_be32(engine_clock); |
110 | sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
110 | sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
111 | sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
111 | sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
112 | sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
112 | sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
113 | sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum); |
113 | sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum); |
114 | sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2); |
114 | sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2); |
115 | 115 | ||
116 | return 0; |
116 | return 0; |
117 | } |
117 | } |
118 | 118 | ||
119 | int rv730_populate_mclk_value(struct radeon_device *rdev, |
119 | int rv730_populate_mclk_value(struct radeon_device *rdev, |
120 | u32 engine_clock, u32 memory_clock, |
120 | u32 engine_clock, u32 memory_clock, |
121 | LPRV7XX_SMC_MCLK_VALUE mclk) |
121 | LPRV7XX_SMC_MCLK_VALUE mclk) |
122 | { |
122 | { |
123 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
123 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
124 | u32 mclk_pwrmgt_cntl = pi->clk_regs.rv730.mclk_pwrmgt_cntl; |
124 | u32 mclk_pwrmgt_cntl = pi->clk_regs.rv730.mclk_pwrmgt_cntl; |
125 | u32 dll_cntl = pi->clk_regs.rv730.dll_cntl; |
125 | u32 dll_cntl = pi->clk_regs.rv730.dll_cntl; |
126 | u32 mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl; |
126 | u32 mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl; |
127 | u32 mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2; |
127 | u32 mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2; |
128 | u32 mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3; |
128 | u32 mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3; |
129 | u32 mpll_ss = pi->clk_regs.rv730.mpll_ss; |
129 | u32 mpll_ss = pi->clk_regs.rv730.mpll_ss; |
130 | u32 mpll_ss2 = pi->clk_regs.rv730.mpll_ss2; |
130 | u32 mpll_ss2 = pi->clk_regs.rv730.mpll_ss2; |
131 | struct atom_clock_dividers dividers; |
131 | struct atom_clock_dividers dividers; |
132 | u32 post_divider, reference_divider; |
132 | u32 post_divider, reference_divider; |
133 | int ret; |
133 | int ret; |
134 | 134 | ||
135 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM, |
135 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM, |
136 | memory_clock, false, ÷rs); |
136 | memory_clock, false, ÷rs); |
137 | if (ret) |
137 | if (ret) |
138 | return ret; |
138 | return ret; |
139 | 139 | ||
140 | reference_divider = dividers.ref_div + 1; |
140 | reference_divider = dividers.ref_div + 1; |
141 | 141 | ||
142 | if (dividers.enable_post_div) |
142 | if (dividers.enable_post_div) |
143 | post_divider = ((dividers.post_div >> 4) & 0xf) + |
143 | post_divider = ((dividers.post_div >> 4) & 0xf) + |
144 | (dividers.post_div & 0xf) + 2; |
144 | (dividers.post_div & 0xf) + 2; |
145 | else |
145 | else |
146 | post_divider = 1; |
146 | post_divider = 1; |
147 | 147 | ||
148 | /* setup the registers */ |
148 | /* setup the registers */ |
149 | if (dividers.enable_post_div) |
149 | if (dividers.enable_post_div) |
150 | mpll_func_cntl |= MPLL_DIVEN; |
150 | mpll_func_cntl |= MPLL_DIVEN; |
151 | else |
151 | else |
152 | mpll_func_cntl &= ~MPLL_DIVEN; |
152 | mpll_func_cntl &= ~MPLL_DIVEN; |
153 | 153 | ||
154 | mpll_func_cntl &= ~(MPLL_REF_DIV_MASK | MPLL_HILEN_MASK | MPLL_LOLEN_MASK); |
154 | mpll_func_cntl &= ~(MPLL_REF_DIV_MASK | MPLL_HILEN_MASK | MPLL_LOLEN_MASK); |
155 | mpll_func_cntl |= MPLL_REF_DIV(dividers.ref_div); |
155 | mpll_func_cntl |= MPLL_REF_DIV(dividers.ref_div); |
156 | mpll_func_cntl |= MPLL_HILEN((dividers.post_div >> 4) & 0xf); |
156 | mpll_func_cntl |= MPLL_HILEN((dividers.post_div >> 4) & 0xf); |
157 | mpll_func_cntl |= MPLL_LOLEN(dividers.post_div & 0xf); |
157 | mpll_func_cntl |= MPLL_LOLEN(dividers.post_div & 0xf); |
158 | 158 | ||
159 | mpll_func_cntl_3 &= ~MPLL_FB_DIV_MASK; |
159 | mpll_func_cntl_3 &= ~MPLL_FB_DIV_MASK; |
160 | mpll_func_cntl_3 |= MPLL_FB_DIV(dividers.fb_div); |
160 | mpll_func_cntl_3 |= MPLL_FB_DIV(dividers.fb_div); |
161 | if (dividers.enable_dithen) |
161 | if (dividers.enable_dithen) |
162 | mpll_func_cntl_3 |= MPLL_DITHEN; |
162 | mpll_func_cntl_3 |= MPLL_DITHEN; |
163 | else |
163 | else |
164 | mpll_func_cntl_3 &= ~MPLL_DITHEN; |
164 | mpll_func_cntl_3 &= ~MPLL_DITHEN; |
165 | 165 | ||
166 | if (pi->mclk_ss) { |
166 | if (pi->mclk_ss) { |
167 | struct radeon_atom_ss ss; |
167 | struct radeon_atom_ss ss; |
168 | u32 vco_freq = memory_clock * post_divider; |
168 | u32 vco_freq = memory_clock * post_divider; |
169 | 169 | ||
170 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
170 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, |
171 | ASIC_INTERNAL_MEMORY_SS, vco_freq)) { |
171 | ASIC_INTERNAL_MEMORY_SS, vco_freq)) { |
172 | u32 reference_clock = rdev->clock.mpll.reference_freq; |
172 | u32 reference_clock = rdev->clock.mpll.reference_freq; |
173 | u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate); |
173 | u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate); |
174 | u32 clk_v = ss.percentage * dividers.fb_div / (clk_s * 10000); |
174 | u32 clk_v = ss.percentage * dividers.fb_div / (clk_s * 10000); |
175 | 175 | ||
176 | mpll_ss &= ~CLK_S_MASK; |
176 | mpll_ss &= ~CLK_S_MASK; |
177 | mpll_ss |= CLK_S(clk_s); |
177 | mpll_ss |= CLK_S(clk_s); |
178 | mpll_ss |= SSEN; |
178 | mpll_ss |= SSEN; |
179 | 179 | ||
180 | mpll_ss2 &= ~CLK_V_MASK; |
180 | mpll_ss2 &= ~CLK_V_MASK; |
181 | mpll_ss |= CLK_V(clk_v); |
181 | mpll_ss |= CLK_V(clk_v); |
182 | } |
182 | } |
183 | } |
183 | } |
184 | 184 | ||
185 | 185 | ||
186 | mclk->mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
186 | mclk->mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
187 | mclk->mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl); |
187 | mclk->mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl); |
188 | mclk->mclk730.mclk_value = cpu_to_be32(memory_clock); |
188 | mclk->mclk730.mclk_value = cpu_to_be32(memory_clock); |
189 | mclk->mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl); |
189 | mclk->mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl); |
190 | mclk->mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2); |
190 | mclk->mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2); |
191 | mclk->mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3); |
191 | mclk->mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3); |
192 | mclk->mclk730.vMPLL_SS = cpu_to_be32(mpll_ss); |
192 | mclk->mclk730.vMPLL_SS = cpu_to_be32(mpll_ss); |
193 | mclk->mclk730.vMPLL_SS2 = cpu_to_be32(mpll_ss2); |
193 | mclk->mclk730.vMPLL_SS2 = cpu_to_be32(mpll_ss2); |
194 | 194 | ||
195 | return 0; |
195 | return 0; |
196 | } |
196 | } |
197 | 197 | ||
198 | void rv730_read_clock_registers(struct radeon_device *rdev) |
198 | void rv730_read_clock_registers(struct radeon_device *rdev) |
199 | { |
199 | { |
200 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
200 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
201 | 201 | ||
202 | pi->clk_regs.rv730.cg_spll_func_cntl = |
202 | pi->clk_regs.rv730.cg_spll_func_cntl = |
203 | RREG32(CG_SPLL_FUNC_CNTL); |
203 | RREG32(CG_SPLL_FUNC_CNTL); |
204 | pi->clk_regs.rv730.cg_spll_func_cntl_2 = |
204 | pi->clk_regs.rv730.cg_spll_func_cntl_2 = |
205 | RREG32(CG_SPLL_FUNC_CNTL_2); |
205 | RREG32(CG_SPLL_FUNC_CNTL_2); |
206 | pi->clk_regs.rv730.cg_spll_func_cntl_3 = |
206 | pi->clk_regs.rv730.cg_spll_func_cntl_3 = |
207 | RREG32(CG_SPLL_FUNC_CNTL_3); |
207 | RREG32(CG_SPLL_FUNC_CNTL_3); |
208 | pi->clk_regs.rv730.cg_spll_spread_spectrum = |
208 | pi->clk_regs.rv730.cg_spll_spread_spectrum = |
209 | RREG32(CG_SPLL_SPREAD_SPECTRUM); |
209 | RREG32(CG_SPLL_SPREAD_SPECTRUM); |
210 | pi->clk_regs.rv730.cg_spll_spread_spectrum_2 = |
210 | pi->clk_regs.rv730.cg_spll_spread_spectrum_2 = |
211 | RREG32(CG_SPLL_SPREAD_SPECTRUM_2); |
211 | RREG32(CG_SPLL_SPREAD_SPECTRUM_2); |
212 | 212 | ||
213 | pi->clk_regs.rv730.mclk_pwrmgt_cntl = |
213 | pi->clk_regs.rv730.mclk_pwrmgt_cntl = |
214 | RREG32(TCI_MCLK_PWRMGT_CNTL); |
214 | RREG32(TCI_MCLK_PWRMGT_CNTL); |
215 | pi->clk_regs.rv730.dll_cntl = |
215 | pi->clk_regs.rv730.dll_cntl = |
216 | RREG32(TCI_DLL_CNTL); |
216 | RREG32(TCI_DLL_CNTL); |
217 | pi->clk_regs.rv730.mpll_func_cntl = |
217 | pi->clk_regs.rv730.mpll_func_cntl = |
218 | RREG32(CG_MPLL_FUNC_CNTL); |
218 | RREG32(CG_MPLL_FUNC_CNTL); |
219 | pi->clk_regs.rv730.mpll_func_cntl2 = |
219 | pi->clk_regs.rv730.mpll_func_cntl2 = |
220 | RREG32(CG_MPLL_FUNC_CNTL_2); |
220 | RREG32(CG_MPLL_FUNC_CNTL_2); |
221 | pi->clk_regs.rv730.mpll_func_cntl3 = |
221 | pi->clk_regs.rv730.mpll_func_cntl3 = |
222 | RREG32(CG_MPLL_FUNC_CNTL_3); |
222 | RREG32(CG_MPLL_FUNC_CNTL_3); |
223 | pi->clk_regs.rv730.mpll_ss = |
223 | pi->clk_regs.rv730.mpll_ss = |
224 | RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM); |
224 | RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM); |
225 | pi->clk_regs.rv730.mpll_ss2 = |
225 | pi->clk_regs.rv730.mpll_ss2 = |
226 | RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM_2); |
226 | RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM_2); |
227 | } |
227 | } |
228 | 228 | ||
229 | int rv730_populate_smc_acpi_state(struct radeon_device *rdev, |
229 | int rv730_populate_smc_acpi_state(struct radeon_device *rdev, |
230 | RV770_SMC_STATETABLE *table) |
230 | RV770_SMC_STATETABLE *table) |
231 | { |
231 | { |
232 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
232 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
233 | u32 mpll_func_cntl = 0; |
233 | u32 mpll_func_cntl = 0; |
234 | u32 mpll_func_cntl_2 = 0 ; |
234 | u32 mpll_func_cntl_2 = 0 ; |
235 | u32 mpll_func_cntl_3 = 0; |
235 | u32 mpll_func_cntl_3 = 0; |
236 | u32 mclk_pwrmgt_cntl; |
236 | u32 mclk_pwrmgt_cntl; |
237 | u32 dll_cntl; |
237 | u32 dll_cntl; |
238 | u32 spll_func_cntl; |
238 | u32 spll_func_cntl; |
239 | u32 spll_func_cntl_2; |
239 | u32 spll_func_cntl_2; |
240 | u32 spll_func_cntl_3; |
240 | u32 spll_func_cntl_3; |
241 | 241 | ||
242 | table->ACPIState = table->initialState; |
242 | table->ACPIState = table->initialState; |
243 | table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC; |
243 | table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC; |
244 | 244 | ||
245 | if (pi->acpi_vddc) { |
245 | if (pi->acpi_vddc) { |
246 | rv770_populate_vddc_value(rdev, pi->acpi_vddc, |
246 | rv770_populate_vddc_value(rdev, pi->acpi_vddc, |
247 | &table->ACPIState.levels[0].vddc); |
247 | &table->ACPIState.levels[0].vddc); |
248 | table->ACPIState.levels[0].gen2PCIE = pi->pcie_gen2 ? |
248 | table->ACPIState.levels[0].gen2PCIE = pi->pcie_gen2 ? |
249 | pi->acpi_pcie_gen2 : 0; |
249 | pi->acpi_pcie_gen2 : 0; |
250 | table->ACPIState.levels[0].gen2XSP = |
250 | table->ACPIState.levels[0].gen2XSP = |
251 | pi->acpi_pcie_gen2; |
251 | pi->acpi_pcie_gen2; |
252 | } else { |
252 | } else { |
253 | rv770_populate_vddc_value(rdev, pi->min_vddc_in_table, |
253 | rv770_populate_vddc_value(rdev, pi->min_vddc_in_table, |
254 | &table->ACPIState.levels[0].vddc); |
254 | &table->ACPIState.levels[0].vddc); |
255 | table->ACPIState.levels[0].gen2PCIE = 0; |
255 | table->ACPIState.levels[0].gen2PCIE = 0; |
256 | } |
256 | } |
257 | 257 | ||
258 | mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl; |
258 | mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl; |
259 | mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2; |
259 | mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2; |
260 | mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3; |
260 | mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3; |
261 | 261 | ||
262 | mpll_func_cntl |= MPLL_RESET | MPLL_BYPASS_EN; |
262 | mpll_func_cntl |= MPLL_RESET | MPLL_BYPASS_EN; |
263 | mpll_func_cntl &= ~MPLL_SLEEP; |
263 | mpll_func_cntl &= ~MPLL_SLEEP; |
264 | 264 | ||
265 | mpll_func_cntl_2 &= ~MCLK_MUX_SEL_MASK; |
265 | mpll_func_cntl_2 &= ~MCLK_MUX_SEL_MASK; |
266 | mpll_func_cntl_2 |= MCLK_MUX_SEL(1); |
266 | mpll_func_cntl_2 |= MCLK_MUX_SEL(1); |
267 | 267 | ||
268 | mclk_pwrmgt_cntl = (MRDCKA_RESET | |
268 | mclk_pwrmgt_cntl = (MRDCKA_RESET | |
269 | MRDCKB_RESET | |
269 | MRDCKB_RESET | |
270 | MRDCKC_RESET | |
270 | MRDCKC_RESET | |
271 | MRDCKD_RESET | |
271 | MRDCKD_RESET | |
272 | MRDCKE_RESET | |
272 | MRDCKE_RESET | |
273 | MRDCKF_RESET | |
273 | MRDCKF_RESET | |
274 | MRDCKG_RESET | |
274 | MRDCKG_RESET | |
275 | MRDCKH_RESET | |
275 | MRDCKH_RESET | |
276 | MRDCKA_SLEEP | |
276 | MRDCKA_SLEEP | |
277 | MRDCKB_SLEEP | |
277 | MRDCKB_SLEEP | |
278 | MRDCKC_SLEEP | |
278 | MRDCKC_SLEEP | |
279 | MRDCKD_SLEEP | |
279 | MRDCKD_SLEEP | |
280 | MRDCKE_SLEEP | |
280 | MRDCKE_SLEEP | |
281 | MRDCKF_SLEEP | |
281 | MRDCKF_SLEEP | |
282 | MRDCKG_SLEEP | |
282 | MRDCKG_SLEEP | |
283 | MRDCKH_SLEEP); |
283 | MRDCKH_SLEEP); |
284 | 284 | ||
285 | dll_cntl = 0xff000000; |
285 | dll_cntl = 0xff000000; |
286 | 286 | ||
287 | spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl; |
287 | spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl; |
288 | spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2; |
288 | spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2; |
289 | spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3; |
289 | spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3; |
290 | 290 | ||
291 | spll_func_cntl |= SPLL_RESET | SPLL_BYPASS_EN; |
291 | spll_func_cntl |= SPLL_RESET | SPLL_BYPASS_EN; |
292 | spll_func_cntl &= ~SPLL_SLEEP; |
292 | spll_func_cntl &= ~SPLL_SLEEP; |
293 | 293 | ||
294 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
294 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; |
295 | spll_func_cntl_2 |= SCLK_MUX_SEL(4); |
295 | spll_func_cntl_2 |= SCLK_MUX_SEL(4); |
296 | 296 | ||
297 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl); |
297 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl); |
298 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2); |
298 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2); |
299 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3); |
299 | table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3); |
300 | table->ACPIState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
300 | table->ACPIState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); |
301 | table->ACPIState.levels[0].mclk.mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl); |
301 | table->ACPIState.levels[0].mclk.mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl); |
302 | 302 | ||
303 | table->ACPIState.levels[0].mclk.mclk730.mclk_value = 0; |
303 | table->ACPIState.levels[0].mclk.mclk730.mclk_value = 0; |
304 | 304 | ||
305 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
305 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl); |
306 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
306 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2); |
307 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
307 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3); |
308 | 308 | ||
309 | table->ACPIState.levels[0].sclk.sclk_value = 0; |
309 | table->ACPIState.levels[0].sclk.sclk_value = 0; |
310 | 310 | ||
311 | rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd); |
311 | rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd); |
312 | 312 | ||
313 | table->ACPIState.levels[1] = table->ACPIState.levels[0]; |
313 | table->ACPIState.levels[1] = table->ACPIState.levels[0]; |
314 | table->ACPIState.levels[2] = table->ACPIState.levels[0]; |
314 | table->ACPIState.levels[2] = table->ACPIState.levels[0]; |
315 | 315 | ||
316 | return 0; |
316 | return 0; |
317 | } |
317 | } |
318 | 318 | ||
319 | int rv730_populate_smc_initial_state(struct radeon_device *rdev, |
319 | int rv730_populate_smc_initial_state(struct radeon_device *rdev, |
320 | struct radeon_ps *radeon_state, |
320 | struct radeon_ps *radeon_state, |
321 | RV770_SMC_STATETABLE *table) |
321 | RV770_SMC_STATETABLE *table) |
322 | { |
322 | { |
323 | struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state); |
323 | struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state); |
324 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
324 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
325 | u32 a_t; |
325 | u32 a_t; |
326 | 326 | ||
327 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = |
327 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = |
328 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl); |
328 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl); |
329 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = |
329 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = |
330 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl2); |
330 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl2); |
331 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = |
331 | table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = |
332 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl3); |
332 | cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl3); |
333 | table->initialState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = |
333 | table->initialState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = |
334 | cpu_to_be32(pi->clk_regs.rv730.mclk_pwrmgt_cntl); |
334 | cpu_to_be32(pi->clk_regs.rv730.mclk_pwrmgt_cntl); |
335 | table->initialState.levels[0].mclk.mclk730.vDLL_CNTL = |
335 | table->initialState.levels[0].mclk.mclk730.vDLL_CNTL = |
336 | cpu_to_be32(pi->clk_regs.rv730.dll_cntl); |
336 | cpu_to_be32(pi->clk_regs.rv730.dll_cntl); |
337 | table->initialState.levels[0].mclk.mclk730.vMPLL_SS = |
337 | table->initialState.levels[0].mclk.mclk730.vMPLL_SS = |
338 | cpu_to_be32(pi->clk_regs.rv730.mpll_ss); |
338 | cpu_to_be32(pi->clk_regs.rv730.mpll_ss); |
339 | table->initialState.levels[0].mclk.mclk730.vMPLL_SS2 = |
339 | table->initialState.levels[0].mclk.mclk730.vMPLL_SS2 = |
340 | cpu_to_be32(pi->clk_regs.rv730.mpll_ss2); |
340 | cpu_to_be32(pi->clk_regs.rv730.mpll_ss2); |
341 | 341 | ||
342 | table->initialState.levels[0].mclk.mclk730.mclk_value = |
342 | table->initialState.levels[0].mclk.mclk730.mclk_value = |
343 | cpu_to_be32(initial_state->low.mclk); |
343 | cpu_to_be32(initial_state->low.mclk); |
344 | 344 | ||
345 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = |
345 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = |
346 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl); |
346 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl); |
347 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = |
347 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = |
348 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_2); |
348 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_2); |
349 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = |
349 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = |
350 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_3); |
350 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_3); |
351 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM = |
351 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM = |
352 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum); |
352 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum); |
353 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 = |
353 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 = |
354 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum_2); |
354 | cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum_2); |
355 | 355 | ||
356 | table->initialState.levels[0].sclk.sclk_value = |
356 | table->initialState.levels[0].sclk.sclk_value = |
357 | cpu_to_be32(initial_state->low.sclk); |
357 | cpu_to_be32(initial_state->low.sclk); |
358 | 358 | ||
359 | table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0; |
359 | table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0; |
360 | 360 | ||
361 | table->initialState.levels[0].seqValue = |
361 | table->initialState.levels[0].seqValue = |
362 | rv770_get_seq_value(rdev, &initial_state->low); |
362 | rv770_get_seq_value(rdev, &initial_state->low); |
363 | 363 | ||
364 | rv770_populate_vddc_value(rdev, |
364 | rv770_populate_vddc_value(rdev, |
365 | initial_state->low.vddc, |
365 | initial_state->low.vddc, |
366 | &table->initialState.levels[0].vddc); |
366 | &table->initialState.levels[0].vddc); |
367 | rv770_populate_initial_mvdd_value(rdev, |
367 | rv770_populate_initial_mvdd_value(rdev, |
368 | &table->initialState.levels[0].mvdd); |
368 | &table->initialState.levels[0].mvdd); |
369 | 369 | ||
370 | a_t = CG_R(0xffff) | CG_L(0); |
370 | a_t = CG_R(0xffff) | CG_L(0); |
371 | 371 | ||
372 | table->initialState.levels[0].aT = cpu_to_be32(a_t); |
372 | table->initialState.levels[0].aT = cpu_to_be32(a_t); |
373 | 373 | ||
374 | table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp); |
374 | table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp); |
375 | 375 | ||
376 | if (pi->boot_in_gen2) |
376 | if (pi->boot_in_gen2) |
377 | table->initialState.levels[0].gen2PCIE = 1; |
377 | table->initialState.levels[0].gen2PCIE = 1; |
378 | else |
378 | else |
379 | table->initialState.levels[0].gen2PCIE = 0; |
379 | table->initialState.levels[0].gen2PCIE = 0; |
380 | if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) |
380 | if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) |
381 | table->initialState.levels[0].gen2XSP = 1; |
381 | table->initialState.levels[0].gen2XSP = 1; |
382 | else |
382 | else |
383 | table->initialState.levels[0].gen2XSP = 0; |
383 | table->initialState.levels[0].gen2XSP = 0; |
384 | 384 | ||
385 | table->initialState.levels[1] = table->initialState.levels[0]; |
385 | table->initialState.levels[1] = table->initialState.levels[0]; |
386 | table->initialState.levels[2] = table->initialState.levels[0]; |
386 | table->initialState.levels[2] = table->initialState.levels[0]; |
387 | 387 | ||
388 | table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC; |
388 | table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC; |
389 | 389 | ||
390 | return 0; |
390 | return 0; |
391 | } |
391 | } |
392 | 392 | ||
393 | void rv730_program_memory_timing_parameters(struct radeon_device *rdev, |
393 | void rv730_program_memory_timing_parameters(struct radeon_device *rdev, |
394 | struct radeon_ps *radeon_state) |
394 | struct radeon_ps *radeon_state) |
395 | { |
395 | { |
396 | struct rv7xx_ps *state = rv770_get_ps(radeon_state); |
396 | struct rv7xx_ps *state = rv770_get_ps(radeon_state); |
397 | u32 arb_refresh_rate = 0; |
397 | u32 arb_refresh_rate = 0; |
398 | u32 dram_timing = 0; |
398 | u32 dram_timing = 0; |
399 | u32 dram_timing2 = 0; |
399 | u32 dram_timing2 = 0; |
400 | u32 old_dram_timing = 0; |
400 | u32 old_dram_timing = 0; |
401 | u32 old_dram_timing2 = 0; |
401 | u32 old_dram_timing2 = 0; |
402 | 402 | ||
403 | arb_refresh_rate = RREG32(MC_ARB_RFSH_RATE) & |
403 | arb_refresh_rate = RREG32(MC_ARB_RFSH_RATE) & |
404 | ~(POWERMODE1_MASK | POWERMODE2_MASK | POWERMODE3_MASK); |
404 | ~(POWERMODE1_MASK | POWERMODE2_MASK | POWERMODE3_MASK); |
405 | arb_refresh_rate |= |
405 | arb_refresh_rate |= |
406 | (POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) | |
406 | (POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) | |
407 | POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) | |
407 | POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) | |
408 | POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk))); |
408 | POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk))); |
409 | WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate); |
409 | WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate); |
410 | 410 | ||
411 | /* save the boot dram timings */ |
411 | /* save the boot dram timings */ |
412 | old_dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
412 | old_dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
413 | old_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
413 | old_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
414 | 414 | ||
415 | radeon_atom_set_engine_dram_timings(rdev, |
415 | radeon_atom_set_engine_dram_timings(rdev, |
416 | state->high.sclk, |
416 | state->high.sclk, |
417 | state->high.mclk); |
417 | state->high.mclk); |
418 | 418 | ||
419 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
419 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
420 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
420 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
421 | 421 | ||
422 | WREG32(MC_ARB_DRAM_TIMING_3, dram_timing); |
422 | WREG32(MC_ARB_DRAM_TIMING_3, dram_timing); |
423 | WREG32(MC_ARB_DRAM_TIMING2_3, dram_timing2); |
423 | WREG32(MC_ARB_DRAM_TIMING2_3, dram_timing2); |
424 | 424 | ||
425 | radeon_atom_set_engine_dram_timings(rdev, |
425 | radeon_atom_set_engine_dram_timings(rdev, |
426 | state->medium.sclk, |
426 | state->medium.sclk, |
427 | state->medium.mclk); |
427 | state->medium.mclk); |
428 | 428 | ||
429 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
429 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
430 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
430 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
431 | 431 | ||
432 | WREG32(MC_ARB_DRAM_TIMING_2, dram_timing); |
432 | WREG32(MC_ARB_DRAM_TIMING_2, dram_timing); |
433 | WREG32(MC_ARB_DRAM_TIMING2_2, dram_timing2); |
433 | WREG32(MC_ARB_DRAM_TIMING2_2, dram_timing2); |
434 | 434 | ||
435 | radeon_atom_set_engine_dram_timings(rdev, |
435 | radeon_atom_set_engine_dram_timings(rdev, |
436 | state->low.sclk, |
436 | state->low.sclk, |
437 | state->low.mclk); |
437 | state->low.mclk); |
438 | 438 | ||
439 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
439 | dram_timing = RREG32(MC_ARB_DRAM_TIMING); |
440 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
440 | dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2); |
441 | 441 | ||
442 | WREG32(MC_ARB_DRAM_TIMING_1, dram_timing); |
442 | WREG32(MC_ARB_DRAM_TIMING_1, dram_timing); |
443 | WREG32(MC_ARB_DRAM_TIMING2_1, dram_timing2); |
443 | WREG32(MC_ARB_DRAM_TIMING2_1, dram_timing2); |
444 | 444 | ||
445 | /* restore the boot dram timings */ |
445 | /* restore the boot dram timings */ |
446 | WREG32(MC_ARB_DRAM_TIMING, old_dram_timing); |
446 | WREG32(MC_ARB_DRAM_TIMING, old_dram_timing); |
447 | WREG32(MC_ARB_DRAM_TIMING2, old_dram_timing2); |
447 | WREG32(MC_ARB_DRAM_TIMING2, old_dram_timing2); |
448 | 448 | ||
449 | } |
449 | } |
450 | 450 | ||
451 | void rv730_start_dpm(struct radeon_device *rdev) |
451 | void rv730_start_dpm(struct radeon_device *rdev) |
452 | { |
452 | { |
453 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF); |
453 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF); |
454 | 454 | ||
455 | WREG32_P(TCI_MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF); |
455 | WREG32_P(TCI_MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF); |
456 | 456 | ||
457 | WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN); |
457 | WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN); |
458 | } |
458 | } |
459 | 459 | ||
460 | void rv730_stop_dpm(struct radeon_device *rdev) |
460 | void rv730_stop_dpm(struct radeon_device *rdev) |
461 | { |
461 | { |
462 | PPSMC_Result result; |
462 | PPSMC_Result result; |
463 | 463 | ||
464 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); |
464 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled); |
465 | 465 | ||
466 | if (result != PPSMC_Result_OK) |
466 | if (result != PPSMC_Result_OK) |
467 | DRM_ERROR("Could not force DPM to low\n"); |
467 | DRM_DEBUG("Could not force DPM to low\n"); |
468 | 468 | ||
469 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); |
469 | WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN); |
470 | 470 | ||
471 | WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF); |
471 | WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF); |
472 | 472 | ||
473 | WREG32_P(TCI_MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF); |
473 | WREG32_P(TCI_MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF); |
474 | } |
474 | } |
475 | 475 | ||
476 | void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt) |
476 | void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt) |
477 | { |
477 | { |
478 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
478 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
479 | u32 i = use_dcodt ? 0 : 1; |
479 | u32 i = use_dcodt ? 0 : 1; |
480 | u32 mc4_io_pad_cntl; |
480 | u32 mc4_io_pad_cntl; |
481 | 481 | ||
482 | mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0); |
482 | mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0); |
483 | mc4_io_pad_cntl &= 0xFFFFFF00; |
483 | mc4_io_pad_cntl &= 0xFFFFFF00; |
484 | mc4_io_pad_cntl |= pi->odt_value_0[i]; |
484 | mc4_io_pad_cntl |= pi->odt_value_0[i]; |
485 | WREG32(MC4_IO_DQ_PAD_CNTL_D0_I0, mc4_io_pad_cntl); |
485 | WREG32(MC4_IO_DQ_PAD_CNTL_D0_I0, mc4_io_pad_cntl); |
486 | WREG32(MC4_IO_DQ_PAD_CNTL_D0_I1, mc4_io_pad_cntl); |
486 | WREG32(MC4_IO_DQ_PAD_CNTL_D0_I1, mc4_io_pad_cntl); |
487 | 487 | ||
488 | mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0); |
488 | mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0); |
489 | mc4_io_pad_cntl &= 0xFFFFFF00; |
489 | mc4_io_pad_cntl &= 0xFFFFFF00; |
490 | mc4_io_pad_cntl |= pi->odt_value_1[i]; |
490 | mc4_io_pad_cntl |= pi->odt_value_1[i]; |
491 | WREG32(MC4_IO_QS_PAD_CNTL_D0_I0, mc4_io_pad_cntl); |
491 | WREG32(MC4_IO_QS_PAD_CNTL_D0_I0, mc4_io_pad_cntl); |
492 | WREG32(MC4_IO_QS_PAD_CNTL_D0_I1, mc4_io_pad_cntl); |
492 | WREG32(MC4_IO_QS_PAD_CNTL_D0_I1, mc4_io_pad_cntl); |
493 | } |
493 | } |
494 | 494 | ||
495 | void rv730_get_odt_values(struct radeon_device *rdev) |
495 | void rv730_get_odt_values(struct radeon_device *rdev) |
496 | { |
496 | { |
497 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
497 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
498 | u32 mc4_io_pad_cntl; |
498 | u32 mc4_io_pad_cntl; |
499 | 499 | ||
500 | pi->odt_value_0[0] = (u8)0; |
500 | pi->odt_value_0[0] = (u8)0; |
501 | pi->odt_value_1[0] = (u8)0x80; |
501 | pi->odt_value_1[0] = (u8)0x80; |
502 | 502 | ||
503 | mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0); |
503 | mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0); |
504 | pi->odt_value_0[1] = (u8)(mc4_io_pad_cntl & 0xff); |
504 | pi->odt_value_0[1] = (u8)(mc4_io_pad_cntl & 0xff); |
505 | 505 | ||
506 | mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0); |
506 | mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0); |
507 | pi->odt_value_1[1] = (u8)(mc4_io_pad_cntl & 0xff); |
507 | pi->odt_value_1[1] = (u8)(mc4_io_pad_cntl & 0xff); |
508 | } |
508 | } |