3 #include <linux/console.h>
4 #include <linux/agp_backend.h>
7 * Currently, only PowerMac do D2 state
9 #define CONFIG_RADEON_HAS_D2 CONFIG_PPC_PMAC
11 #ifdef CONFIG_RADEON_HAS_D2
13 * On PowerMac, we assume any mobility chip based machine does D2
15 #ifdef CONFIG_PPC_PMAC
16 static inline int radeon_suspend_to_d2(struct radeonfb_info *rinfo, u32 state)
18 return rinfo->is_mobility;
21 static inline int radeon_suspend_to_d2(struct radeonfb_info *rinfo, u32 state)
27 #endif /* CONFIG_RADEON_HAS_D2 */
30 * Radeon M6, M7 and M9 Power Management code. This code currently
31 * only supports the mobile chips in D2 mode, that is typically what
32 * is used on Apple laptops, it's based from some informations provided
33 * by ATI along with hours of tracing of MacOS drivers.
35 * New version of this code almost totally rewritten by ATI, many thanks
39 void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
49 /* Mobility chips only, untested on M9+/M10/11 */
50 if (!rinfo->is_mobility)
52 if (rinfo->family > CHIP_FAMILY_RV250)
55 /* Force Core Clocks */
56 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
57 sclk_cntl |= SCLK_CNTL_M6__FORCE_CP|
58 SCLK_CNTL_M6__FORCE_HDP|
59 SCLK_CNTL_M6__FORCE_DISP1|
60 SCLK_CNTL_M6__FORCE_DISP2|
61 SCLK_CNTL_M6__FORCE_TOP|
62 SCLK_CNTL_M6__FORCE_E2|
63 SCLK_CNTL_M6__FORCE_SE|
64 SCLK_CNTL_M6__FORCE_IDCT|
65 SCLK_CNTL_M6__FORCE_VIP|
66 SCLK_CNTL_M6__FORCE_RE|
67 SCLK_CNTL_M6__FORCE_PB|
68 SCLK_CNTL_M6__FORCE_TAM|
69 SCLK_CNTL_M6__FORCE_TDM|
70 SCLK_CNTL_M6__FORCE_RB|
71 SCLK_CNTL_M6__FORCE_TV_SCLK|
72 SCLK_CNTL_M6__FORCE_SUBPIC|
73 SCLK_CNTL_M6__FORCE_OV0;
74 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
78 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
79 sclk_more_cntl |= SCLK_MORE_CNTL__FORCE_DISPREGS|
80 SCLK_MORE_CNTL__FORCE_MC_GUI|
81 SCLK_MORE_CNTL__FORCE_MC_HOST;
82 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
84 /* Force Display clocks */
85 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
86 vclk_ecp_cntl &= ~( VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
87 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
89 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
91 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
92 pixclks_cntl &= ~( PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
93 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
94 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
95 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
96 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
97 PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
98 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
100 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
102 /* Force Memory Clocks */
103 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
104 mclk_cntl &= ~( MCLK_CNTL_M6__FORCE_MCLKA |
105 MCLK_CNTL_M6__FORCE_MCLKB |
106 MCLK_CNTL_M6__FORCE_YCLKA |
107 MCLK_CNTL_M6__FORCE_YCLKB );
108 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
111 void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
122 /* Mobility chips only, untested on M9+/M10/11 */
123 if (!rinfo->is_mobility)
125 if (rinfo->family > CHIP_FAMILY_RV250)
129 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
131 clk_pwrmgt_cntl &= ~( CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
132 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
133 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
134 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
136 clk_pwrmgt_cntl = CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
137 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE |
138 (1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
139 (0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
140 (0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
142 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
145 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
146 clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
148 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
150 /* Enable Dyanmic mode for SCLK */
152 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
153 sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
154 sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;
156 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
159 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
160 sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
162 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
165 /* Enable Dynamic mode for PIXCLK & PIX2CLK */
167 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
169 pixclks_cntl|= PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb |
170 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
171 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
172 PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
173 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
174 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
175 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
177 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
180 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
182 vclk_ecp_cntl|= VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
183 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
185 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
188 /* Enable Dynamic mode for MCLK */
190 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
191 mclk_cntl |= MCLK_CNTL_M6__FORCE_MCLKA|
192 MCLK_CNTL_M6__FORCE_MCLKB|
193 MCLK_CNTL_M6__FORCE_YCLKA|
194 MCLK_CNTL_M6__FORCE_YCLKB;
196 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
198 mclk_misc = INPLL(pllMCLK_MISC);
199 mclk_misc |= MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
200 MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
201 MCLK_MISC__MC_MCLK_DYN_ENABLE|
202 MCLK_MISC__IO_MCLK_DYN_ENABLE;
204 OUTPLL(pllMCLK_MISC, mclk_misc);
209 static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
211 OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN);
212 OUTREG( MC_IND_DATA, value);
215 static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
217 OUTREG( MC_IND_INDEX, indx);
218 return INREG( MC_IND_DATA);
221 static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
223 rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
224 rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
225 rinfo->save_regs[2] = INPLL(MCLK_CNTL);
226 rinfo->save_regs[3] = INPLL(SCLK_CNTL);
227 rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
228 rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
229 rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
230 rinfo->save_regs[7] = INPLL(MCLK_MISC);
231 rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
233 rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
234 rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
235 rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
236 rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
237 rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
238 rinfo->save_regs[14] = INREG(BUS_CNTL1);
239 rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
240 rinfo->save_regs[16] = INREG(AGP_CNTL);
241 rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
242 rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
243 rinfo->save_regs[19] = INREG(GPIOPAD_A);
244 rinfo->save_regs[20] = INREG(GPIOPAD_EN);
245 rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
246 rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
247 rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
248 rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
249 rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
250 rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
251 rinfo->save_regs[27] = INREG(GPIO_MONID);
252 rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
254 rinfo->save_regs[29] = INREG(SURFACE_CNTL);
255 rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
256 rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
257 rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
258 rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
261 static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
263 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
265 OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
266 OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
267 OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
268 OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
269 OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
270 OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
271 OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
272 OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
274 OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
275 OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
276 OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
277 OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
278 OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
280 OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
281 OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
282 OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
283 OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
284 OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
285 OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
286 OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
287 OUTREG(AGP_CNTL, rinfo->save_regs[16]);
288 OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
289 OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
291 // wait VBL before that one ?
292 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
294 OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
295 OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
296 OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
297 OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
298 OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
299 OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
300 OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
301 OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
302 OUTREG(GPIO_MONID, rinfo->save_regs[27]);
303 OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
306 static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
308 OUTREG(GPIOPAD_MASK, 0x0001ffff);
309 OUTREG(GPIOPAD_EN, 0x00000400);
310 OUTREG(GPIOPAD_A, 0x00000000);
311 OUTREG(ZV_LCDPAD_MASK, 0x00000000);
312 OUTREG(ZV_LCDPAD_EN, 0x00000000);
313 OUTREG(ZV_LCDPAD_A, 0x00000000);
314 OUTREG(GPIO_VGA_DDC, 0x00030000);
315 OUTREG(GPIO_DVI_DDC, 0x00000000);
316 OUTREG(GPIO_MONID, 0x00030000);
317 OUTREG(GPIO_CRT2_DDC, 0x00000000);
320 static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
322 /* Set v2clk to 65MHz */
323 OUTPLL(pllPIXCLKS_CNTL,
324 INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
326 OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
327 OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
328 OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
330 OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
333 OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
336 OUTPLL(pllPIXCLKS_CNTL,
337 (INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
338 | (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
342 static void radeon_pm_low_current(struct radeonfb_info *rinfo)
346 reg = INREG(BUS_CNTL1);
347 reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
348 reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
349 OUTREG(BUS_CNTL1, reg);
351 reg = INPLL(PLL_PWRMGT_CNTL);
352 reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
353 PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
354 reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
355 reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
356 OUTPLL(PLL_PWRMGT_CNTL, reg);
358 reg = INREG(TV_DAC_CNTL);
359 reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
360 reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
362 (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
363 OUTREG(TV_DAC_CNTL, reg);
365 reg = INREG(TMDS_TRANSMITTER_CNTL);
366 reg &= ~(TMDS_PLL_EN | TMDS_PLLRST);
367 OUTREG(TMDS_TRANSMITTER_CNTL, reg);
369 reg = INREG(DAC_CNTL);
371 OUTREG(DAC_CNTL, reg);
373 reg = INREG(DAC_CNTL2);
375 OUTREG(DAC_CNTL2, reg);
377 reg = INREG(TV_DAC_CNTL);
378 reg &= ~TV_DAC_CNTL_DETECT;
379 OUTREG(TV_DAC_CNTL, reg);
382 static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
385 u32 sclk_cntl, mclk_cntl, sclk_more_cntl;
396 /* Force Core Clocks */
397 sclk_cntl = INPLL( pllSCLK_CNTL_M6);
398 sclk_cntl |= SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
399 SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
400 SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
401 SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
402 SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
403 SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
404 SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
406 SCLK_CNTL_M6__FORCE_DISP2|
407 SCLK_CNTL_M6__FORCE_CP|
408 SCLK_CNTL_M6__FORCE_HDP|
409 SCLK_CNTL_M6__FORCE_DISP1|
410 SCLK_CNTL_M6__FORCE_TOP|
411 SCLK_CNTL_M6__FORCE_E2|
412 SCLK_CNTL_M6__FORCE_SE|
413 SCLK_CNTL_M6__FORCE_IDCT|
414 SCLK_CNTL_M6__FORCE_VIP|
416 SCLK_CNTL_M6__FORCE_RE|
417 SCLK_CNTL_M6__FORCE_PB|
418 SCLK_CNTL_M6__FORCE_TAM|
419 SCLK_CNTL_M6__FORCE_TDM|
420 SCLK_CNTL_M6__FORCE_RB|
421 SCLK_CNTL_M6__FORCE_TV_SCLK|
422 SCLK_CNTL_M6__FORCE_SUBPIC|
423 SCLK_CNTL_M6__FORCE_OV0;
425 OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
427 sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
428 sclk_more_cntl |= SCLK_MORE_CNTL__FORCE_DISPREGS |
429 SCLK_MORE_CNTL__FORCE_MC_GUI |
430 SCLK_MORE_CNTL__FORCE_MC_HOST;
432 OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
435 mclk_cntl = INPLL( pllMCLK_CNTL_M6);
436 mclk_cntl &= ~( MCLK_CNTL_M6__FORCE_MCLKA |
437 MCLK_CNTL_M6__FORCE_MCLKB |
438 MCLK_CNTL_M6__FORCE_YCLKA |
439 MCLK_CNTL_M6__FORCE_YCLKB |
440 MCLK_CNTL_M6__FORCE_MC
442 OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
444 /* Force Display clocks */
445 vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
446 vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
447 vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
448 OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
451 pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
452 pixclks_cntl &= ~( PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
453 PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
454 PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
455 PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
456 PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
457 PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
458 PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
460 OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
464 /* Enable System power management */
465 pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);
467 pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__SPLL_TURNOFF |
468 PLL_PWRMGT_CNTL__MPLL_TURNOFF|
469 PLL_PWRMGT_CNTL__PPLL_TURNOFF|
470 PLL_PWRMGT_CNTL__P2PLL_TURNOFF|
471 PLL_PWRMGT_CNTL__TVPLL_TURNOFF;
473 OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
475 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
477 clk_pwrmgt_cntl &= ~( CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
478 CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
479 CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
480 CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
481 CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
482 CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
483 CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
484 CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
485 CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
486 CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
487 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
488 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
489 CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK
492 clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
494 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
496 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
498 clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;
499 OUTPLL( pllMCLK_MISC, INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND);
501 /* AGP PLL control */
502 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID);
505 (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
506 | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX
507 OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
509 clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
510 clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
511 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
515 (INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))
516 | (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));
519 OUTPLL( pllPLL_PWRMGT_CNTL, INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL);
522 disp_mis_cntl = INREG(DISP_MISC_CNTL);
524 disp_mis_cntl &= ~( DISP_MISC_CNTL__SOFT_RESET_GRPH_PP |
525 DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP |
526 DISP_MISC_CNTL__SOFT_RESET_OV0_PP |
527 DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|
528 DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|
529 DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|
530 DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|
531 DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|
532 DISP_MISC_CNTL__SOFT_RESET_LVDS|
533 DISP_MISC_CNTL__SOFT_RESET_TMDS|
534 DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
535 DISP_MISC_CNTL__SOFT_RESET_TV);
537 OUTREG(DISP_MISC_CNTL, disp_mis_cntl);
539 disp_pwr_man = INREG(DISP_PWR_MAN);
541 disp_pwr_man &= ~( DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN |
542 DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
543 DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|
544 DISP_PWR_MAN__DISP_D3_RST|
545 DISP_PWR_MAN__DISP_D3_REG_RST
548 disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|
549 DISP_PWR_MAN__DISP_D3_SUBPIC_RST|
550 DISP_PWR_MAN__DISP_D3_OV0_RST|
551 DISP_PWR_MAN__DISP_D1D2_GRPH_RST|
552 DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST|
553 DISP_PWR_MAN__DISP_D1D2_OV0_RST|
554 DISP_PWR_MAN__DIG_TMDS_ENABLE_RST|
555 DISP_PWR_MAN__TV_ENABLE_RST|
556 // DISP_PWR_MAN__AUTO_PWRUP_EN|
559 OUTREG(DISP_PWR_MAN, disp_pwr_man);
561 clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
562 pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
563 clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
564 disp_pwr_man = INREG(DISP_PWR_MAN);
568 clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
569 pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
570 clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
571 disp_pwr_man &= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);
574 OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
575 OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
576 OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
577 OUTREG(DISP_PWR_MAN, disp_pwr_man);
579 /* disable display request & disable display */
580 OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
581 OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
587 static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
589 u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
591 mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
592 mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
594 OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
595 OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
597 /* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
598 #ifdef MCLK_YCLK_SYNC_ENABLE
599 mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
600 mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
603 OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
604 OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
609 static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
613 mem_sdram_mode = INREG( MEM_SDRAM_MODE_REG);
615 mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
616 mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
617 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
619 mem_sdram_mode |= MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
620 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
622 mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
623 OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
625 if (delay_required == 1)
626 while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
631 static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
633 #define DLL_RESET_DELAY 5
634 #define DLL_SLEEP_DELAY 1
636 u32 DLL_CKO_Value = INPLL(pllMDLL_CKO) | MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOA_RESET;
637 u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
638 u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
640 /* Setting up the DLL range for write */
641 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
642 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
643 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
645 mdelay( DLL_RESET_DELAY);
650 DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
651 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
652 mdelay( DLL_SLEEP_DELAY);
654 DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
655 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
656 mdelay( DLL_RESET_DELAY);
659 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
660 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
661 mdelay( DLL_SLEEP_DELAY);
663 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
664 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
665 mdelay( DLL_RESET_DELAY);
668 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
669 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
670 mdelay( DLL_SLEEP_DELAY);
672 DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
673 OUTPLL(pllMDLL_RDCKA, DLL_CKA_Value);
674 mdelay( DLL_RESET_DELAY);
680 DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
681 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
682 mdelay( DLL_SLEEP_DELAY);
684 DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
685 OUTPLL(pllMDLL_CKO, DLL_CKO_Value);
686 mdelay( DLL_RESET_DELAY);
689 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
690 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
691 mdelay( DLL_SLEEP_DELAY);
693 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
694 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
695 mdelay( DLL_RESET_DELAY);
698 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
699 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
700 mdelay( DLL_SLEEP_DELAY);
702 DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
703 OUTPLL(pllMDLL_RDCKB, DLL_CKB_Value);
704 mdelay( DLL_RESET_DELAY);
706 #undef DLL_RESET_DELAY
707 #undef DLL_SLEEP_DELAY
710 static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
712 u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
714 crtcGenCntl = INREG( CRTC_GEN_CNTL);
715 crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
717 memRefreshCntl = INREG( MEM_REFRESH_CNTL);
718 crtc_more_cntl = INREG( CRTC_MORE_CNTL);
719 fp_gen_cntl = INREG( FP_GEN_CNTL);
720 fp2_gen_cntl = INREG( FP2_GEN_CNTL);
723 OUTREG( CRTC_MORE_CNTL, 0);
724 OUTREG( FP_GEN_CNTL, 0);
725 OUTREG( FP2_GEN_CNTL, 0);
727 OUTREG( CRTC_GEN_CNTL, (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
728 OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
730 /* Disable refresh */
731 OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
734 OUTREG( MEM_SDRAM_MODE_REG,
735 INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Not Complete
738 radeon_pm_enable_dll(rinfo);
741 radeon_pm_yclk_mclk_sync(rinfo);
743 /* M6, M7 and M9 so far ... */
744 if (rinfo->is_mobility && rinfo->family <= CHIP_FAMILY_RV250) {
745 radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
746 radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
747 radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
748 radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
749 radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
752 OUTREG( MEM_SDRAM_MODE_REG,
753 INREG( MEM_SDRAM_MODE_REG) | MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
755 OUTREG( MEM_REFRESH_CNTL, memRefreshCntl);
757 OUTREG( CRTC_GEN_CNTL, crtcGenCntl);
758 OUTREG( CRTC2_GEN_CNTL, crtcGenCntl2);
759 OUTREG( FP_GEN_CNTL, fp_gen_cntl);
760 OUTREG( FP2_GEN_CNTL, fp2_gen_cntl);
762 OUTREG( CRTC_MORE_CNTL, crtc_more_cntl);
767 static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
774 /* Set the chip into appropriate suspend mode (we use D2,
775 * D3 would require a compete re-initialization of the chip,
776 * including PCI config registers, clocks, AGP conf, ...)
779 printk(KERN_DEBUG "radeonfb: switching to D2 state...\n");
781 /* Disable dynamic power management of clocks for the
782 * duration of the suspend/resume process
784 radeon_pm_disable_dynamic_mode(rinfo);
785 /* Save some registers */
786 radeon_pm_save_regs(rinfo);
788 /* Prepare mobility chips for suspend. Only do that on <= RV250 chips that
791 if (rinfo->is_mobility && rinfo->family <= CHIP_FAMILY_RV250) {
793 radeon_pm_program_v2clk(rinfo);
795 /* Disable IO PADs */
796 radeon_pm_disable_iopad(rinfo);
798 /* Set low current */
799 radeon_pm_low_current(rinfo);
801 /* Prepare chip for power management */
802 radeon_pm_setup_for_suspend(rinfo);
805 OUTPLL( pllMDLL_CKO, INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
808 /* Switch PCI power managment to D2. */
810 pci_read_config_word(
811 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
815 pci_write_config_word(
816 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
817 (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
821 printk(KERN_DEBUG "radeonfb: switching to D0 state...\n");
823 /* Switch back PCI powermanagment to D0 */
825 pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
828 /* Reset the SDRAM controller */
829 radeon_pm_full_reset_sdram(rinfo);
831 /* Restore some registers */
832 radeon_pm_restore_regs(rinfo);
833 radeon_pm_enable_dynamic_mode(rinfo);
837 int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state)
839 struct fb_info *info = pci_get_drvdata(pdev);
840 struct radeonfb_info *rinfo = info->par;
842 /* We don't do anything but D2, for now we return 0, but
843 * we may want to change that. How do we know if the BIOS
844 * can properly take care of D3 ? Also, with swsusp, we
845 * know we'll be rebooted, ...
848 printk(KERN_DEBUG "radeonfb: suspending to state: %d...\n", state);
850 acquire_console_sem();
852 /* Userland should do this but doesn't... bridge gets suspended
853 * too late. Unfortunately, that works only when AGP is built-in,
860 fb_set_suspend(info, 1);
862 if (!radeon_accel_disabled()) {
863 /* Make sure engine is reset */
864 radeon_engine_idle();
865 radeonfb_engine_reset(rinfo);
866 radeon_engine_idle();
869 /* Blank display and LCD */
870 radeonfb_blank(VESA_POWERDOWN, info);
874 rinfo->lock_blank = 1;
876 /* Suspend the chip to D2 state when supported
878 #ifdef CONFIG_RADEON_HAS_D2
879 if (radeon_suspend_to_d2(rinfo, state))
880 radeon_set_suspend(rinfo, 1);
881 #endif /* CONFIG_RADEON_HAS_D2 */
883 release_console_sem();
885 pdev->dev.power_state = state;
890 int radeonfb_pci_resume(struct pci_dev *pdev)
892 struct fb_info *info = pci_get_drvdata(pdev);
893 struct radeonfb_info *rinfo = info->par;
895 if (pdev->dev.power_state == 0)
898 acquire_console_sem();
901 #ifdef CONFIG_RADEON_HAS_D2
902 if (radeon_suspend_to_d2(rinfo, 0))
903 radeon_set_suspend(rinfo, 0);
904 #endif /* CONFIG_RADEON_HAS_D2 */
908 /* Restore display & engine */
909 radeonfb_set_par(info);
910 fb_pan_display(info, &info->var);
911 fb_set_cmap(&info->cmap, 1, info);
914 fb_set_suspend(info, 0);
917 rinfo->lock_blank = 0;
918 radeonfb_blank(0, info);
920 release_console_sem();
922 pdev->dev.power_state = 0;
924 printk(KERN_DEBUG "radeonfb: resumed !\n");
929 #endif /* CONFIG_PM */