linux/drivers/video/fbdev/aty/radeon_pm.c

// SPDX-License-Identifier: GPL-2.0
/*
 *	drivers/video/aty/radeon_pm.c
 *
 *	Copyright 2003,2004 Ben. Herrenschmidt <[email protected]>
 *	Copyright 2004 Paul Mackerras <[email protected]>
 *
 *	This is the power management code for ATI radeon chipsets. It contains
 *	some dynamic clock PM enable/disable code similar to what X.org does,
 *	some D2-state (APM-style) sleep/wakeup code for use on some PowerMacs,
 *	and the necessary bits to re-initialize from scratch a few chips found
 *	on PowerMacs as well. The later could be extended to more platforms
 *	provided the memory controller configuration code be made more generic,
 *	and you can get the proper mode register commands for your RAMs.
 *	Those things may be found in the BIOS image...
 */

#include "radeonfb.h"

#include <linux/console.h>
#include <linux/agp_backend.h>

#ifdef CONFIG_PPC_PMAC
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#endif

#include "ati_ids.h"

/*
 * Workarounds for bugs in PC laptops:
 * - enable D2 sleep in some IBM Thinkpads
 * - special case for Samsung P35
 *
 * Whitelist by subsystem vendor/device because
 * its the subsystem vendor's fault!
 */

#if defined(CONFIG_PM) && defined(CONFIG_X86)
static void radeon_reinitialize_M10(struct radeonfb_info *rinfo);

struct radeon_device_id {};

#define BUGFIX(model, sv, sd, pm, fn)

static struct radeon_device_id radeon_workaround_list[] =;

static int radeon_apply_workarounds(struct radeonfb_info *rinfo)
{}

#else  /* defined(CONFIG_PM) && defined(CONFIG_X86) */
static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo)
{
        return 0;
}
#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */



static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
{}

static void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
{}

#ifdef CONFIG_PM

static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
{}

static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
{}

static void radeon_pm_save_regs(struct radeonfb_info *rinfo, int saving_for_d3)
{}

static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
{}

static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
{}

static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
{}

static void radeon_pm_low_current(struct radeonfb_info *rinfo)
{}

static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
{}

static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
{}

static void radeon_pm_yclk_mclk_sync_m10(struct radeonfb_info *rinfo)
{}

static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value,
				       u8 delay_required)
{}

static void radeon_pm_m10_program_mode_wait(struct radeonfb_info *rinfo)
{}


static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
{}

static void radeon_pm_enable_dll_m10(struct radeonfb_info *rinfo)
{}


static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
{}

#if defined(CONFIG_X86) || defined(CONFIG_PPC_PMAC)
static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo)
{}

static void radeon_pm_all_ppls_off(struct radeonfb_info *rinfo)
{}

static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo)
{}

static void radeon_pm_m10_disable_spread_spectrum(struct radeonfb_info *rinfo)
{}

static void radeon_pm_m10_enable_lvds_spread_spectrum(struct radeonfb_info *rinfo)
{}

static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
{}

static void radeon_pm_m10_reconfigure_mc(struct radeonfb_info *rinfo)
{}

static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
{}
#endif

#ifdef CONFIG_PPC
#ifdef CONFIG_PPC_PMAC
static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)
{
	OUTREG(MC_CNTL, rinfo->save_regs[46]);
	OUTREG(MC_INIT_GFX_LAT_TIMER, rinfo->save_regs[47]);
	OUTREG(MC_INIT_MISC_LAT_TIMER, rinfo->save_regs[48]);
	OUTREG(MEM_SDRAM_MODE_REG,
	       rinfo->save_regs[35] & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE);
	OUTREG(MC_TIMING_CNTL, rinfo->save_regs[49]);
	OUTREG(MC_READ_CNTL_AB, rinfo->save_regs[50]);
	OUTREG(MEM_REFRESH_CNTL, rinfo->save_regs[42]);
	OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]);
	OUTREG(MC_DEBUG, rinfo->save_regs[53]);
	OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]);

	OUTMC(rinfo, ixMC_IMP_CNTL, rinfo->save_regs[59] /*0x00f460d6*/);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A0, rinfo->save_regs[65] /*0xfecfa666*/);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, rinfo->save_regs[66] /*0x141555ff*/);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B0, rinfo->save_regs[67] /*0xfecfa666*/);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, rinfo->save_regs[68] /*0x141555ff*/);
	OUTMC(rinfo, ixMC_IMP_CNTL_0, rinfo->save_regs[71] /*0x00009249*/);
	OUTREG(MC_IND_INDEX, 0);
	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);

	mdelay(20);
}

static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo)
{
	u32 tmp, i;

	/* Restore a bunch of registers first */
	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
	OUTREG(OV0_BASE_ADDR, rinfo->save_regs[80]);
	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
	OUTREG(MPP_TB_CONFIG, rinfo->save_regs[37]);
	OUTREG(FCP_CNTL, rinfo->save_regs[38]);
	OUTREG(RBBM_CNTL, rinfo->save_regs[39]);

	OUTREG(DAC_CNTL, rinfo->save_regs[40]);
	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | DAC2_EXPAND_MODE);

	/* Reset the PAD CTLR */
	radeon_pm_reset_pad_ctlr_strength(rinfo);

	/* Some PLLs are Read & written identically in the trace here...
	 * I suppose it's actually to switch them all off & reset,
	 * let's assume off is what we want. I'm just doing that for all major PLLs now.
	 */
	radeon_pm_all_ppls_off(rinfo);

	/* Clear tiling, reset swappers */
	INREG(SURFACE_CNTL);
	OUTREG(SURFACE_CNTL, 0);

	/* Some black magic with TV_DAC_CNTL, we should restore those from backups
	 * rather than hard coding...
	 */
	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_BGADJ_MASK;
	tmp |= 6 << TV_DAC_CNTL_BGADJ__SHIFT;
	OUTREG(TV_DAC_CNTL, tmp);

	tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK;
	tmp |= 6 << TV_DAC_CNTL_DACADJ__SHIFT;
	OUTREG(TV_DAC_CNTL, tmp);

	OUTPLL(pllAGP_PLL_CNTL, rinfo->save_regs[78]);

	OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]);
	OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]);
	OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]);

	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
	OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]); /* MacOS sets that to 0 !!! */
	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);

	tmp  = rinfo->save_regs[1]
		& ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK |
		    CLK_PWRMGT_CNTL__MC_BUSY);
	OUTPLL(pllCLK_PWRMGT_CNTL, tmp);

	OUTREG(FW_CNTL, rinfo->save_regs[57]);

	/* Disable SDRAM refresh */
	OUTREG(MEM_REFRESH_CNTL, INREG(MEM_REFRESH_CNTL)
	       | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);

	/* Restore XTALIN routing (CLK_PIN_CNTL) */
       	OUTPLL(pllCLK_PIN_CNTL, rinfo->save_regs[4]);

	/* Force MCLK to be PCI sourced and forced ON */
	tmp = rinfo->save_regs[2] & 0xff000000;
	tmp |=	MCLK_CNTL__FORCE_MCLKA |
		MCLK_CNTL__FORCE_MCLKB |
		MCLK_CNTL__FORCE_YCLKA |
		MCLK_CNTL__FORCE_YCLKB |
		MCLK_CNTL__FORCE_MC    |
		MCLK_CNTL__FORCE_AIC;
	OUTPLL(pllMCLK_CNTL, tmp);

	/* Force SCLK to be PCI sourced with a bunch forced */
	tmp =	0 |
		SCLK_CNTL__FORCE_DISP2|
		SCLK_CNTL__FORCE_CP|
		SCLK_CNTL__FORCE_HDP|
		SCLK_CNTL__FORCE_DISP1|
		SCLK_CNTL__FORCE_TOP|
		SCLK_CNTL__FORCE_E2|
		SCLK_CNTL__FORCE_SE|
		SCLK_CNTL__FORCE_IDCT|
		SCLK_CNTL__FORCE_VIP|
		SCLK_CNTL__FORCE_RE|
		SCLK_CNTL__FORCE_PB|
		SCLK_CNTL__FORCE_TAM|
		SCLK_CNTL__FORCE_TDM|
		SCLK_CNTL__FORCE_RB;
	OUTPLL(pllSCLK_CNTL, tmp);

	/* Clear VCLK_ECP_CNTL & PIXCLKS_CNTL  */
	OUTPLL(pllVCLK_ECP_CNTL, 0);
	OUTPLL(pllPIXCLKS_CNTL, 0);

	/* Setup MCLK_MISC, non dynamic mode */
	OUTPLL(pllMCLK_MISC,
	       MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT |
	       MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT);

	mdelay(5);

	/* Set back the default clock dividers */
	OUTPLL(pllM_SPLL_REF_FB_DIV, rinfo->save_regs[77]);
	OUTPLL(pllMPLL_AUX_CNTL, rinfo->save_regs[75]);
	OUTPLL(pllSPLL_AUX_CNTL, rinfo->save_regs[76]);

	/* PPLL and P2PLL default values & off */
	OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3);
	OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3);

	/* S and M PLLs are reset & off, configure them */
	OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03);
	OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03);

	/* Default values for MDLL ... fixme */
	OUTPLL(pllMDLL_CKO, 0x9c009c);
	OUTPLL(pllMDLL_RDCKA, 0x08830883);
	OUTPLL(pllMDLL_RDCKB, 0x08830883);
	mdelay(5);

	/* Restore PLL_PWRMGT_CNTL */ // XXXX
	tmp = rinfo->save_regs[0];
	tmp &= ~PLL_PWRMGT_CNTL_SU_SCLK_USE_BCLK;
	tmp |= PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
	OUTPLL(PLL_PWRMGT_CNTL,  tmp);

	/* Clear HTOTAL_CNTL & HTOTAL2_CNTL */
	OUTPLL(pllHTOTAL_CNTL, 0);
	OUTPLL(pllHTOTAL2_CNTL, 0);

	/* All outputs off */
	OUTREG(CRTC_GEN_CNTL, 0x04000000);
	OUTREG(CRTC2_GEN_CNTL, 0x04000000);
	OUTREG(FP_GEN_CNTL, 0x00004008);
	OUTREG(FP2_GEN_CNTL, 0x00000008);
	OUTREG(LVDS_GEN_CNTL, 0x08000008);

	/* Restore Memory Controller configuration */
	radeon_pm_m9p_reconfigure_mc(rinfo);

	/* Now we actually start MCLK and SCLK */
	radeon_pm_start_mclk_sclk(rinfo);

	/* Full reset sdrams, this also re-inits the MDLL */
	radeon_pm_full_reset_sdram(rinfo);

	/* Fill palettes */
	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x20);
	for (i=0; i<256; i++)
		OUTREG(PALETTE_30_DATA, 0x15555555);
	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~20);
	udelay(20);
	for (i=0; i<256; i++)
		OUTREG(PALETTE_30_DATA, 0x15555555);

	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) & ~0x20);
	mdelay(3);

	/* Restore TV stuff, make sure TV DAC is down */
	OUTREG(TV_MASTER_CNTL, rinfo->save_regs[88]);
	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13] | 0x07000000);

	/* Restore GPIOS. MacOS does some magic here with one of the GPIO bits,
	 * possibly related to the weird PLL related workarounds and to the
	 * fact that CLK_PIN_CNTL is tweaked in ways I don't fully understand,
	 * but we keep things the simple way here
	 */
	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);

	/* Now do things with SCLK_MORE_CNTL. Force bits are already set, copy
	 * high bits from backup
	 */
	tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff;
	tmp |= rinfo->save_regs[34] & 0xffff0000;
	tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS;
	OUTPLL(pllSCLK_MORE_CNTL, tmp);

	tmp = INPLL(pllSCLK_MORE_CNTL) & 0x0000ffff;
	tmp |= rinfo->save_regs[34] & 0xffff0000;
	tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS;
	OUTPLL(pllSCLK_MORE_CNTL, tmp);

	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] &
	       ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN));
	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_BLON);
	OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000);
	mdelay(20);

	/* write some stuff to the framebuffer... */
	for (i = 0; i < 0x8000; ++i)
		writeb(0, rinfo->fb_base + i);

	OUTREG(0x2ec, 0x6332a020);
	OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44] /*0x3f */);
	OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45] /*0x000081bb */);
	tmp = INPLL(pllSSPLL_CNTL);
	tmp &= ~2;
	OUTPLL(pllSSPLL_CNTL, tmp);
	mdelay(6);
	tmp &= ~1;
	OUTPLL(pllSSPLL_CNTL, tmp);
	mdelay(5);
	tmp |= 3;
	OUTPLL(pllSSPLL_CNTL, tmp);
	mdelay(5);

	OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90] & ~3);/*0x0020300c*/
	OUTREG(0x2ec, 0x6332a3f0);
	mdelay(17);

	OUTPLL(pllPPLL_REF_DIV, rinfo->pll.ref_div);
	OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);

	mdelay(40);
	OUTREG(LVDS_GEN_CNTL, INREG(LVDS_GEN_CNTL) | LVDS_DIGON | LVDS_ON);
	mdelay(40);

	/* Restore a few more things */
	OUTREG(GRPH_BUFFER_CNTL, rinfo->save_regs[94]);
	OUTREG(GRPH2_BUFFER_CNTL, rinfo->save_regs[95]);

	/* Restore PPLL, spread spectrum & LVDS */
	radeon_pm_m10_disable_spread_spectrum(rinfo);
	radeon_pm_restore_pixel_pll(rinfo);
	radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
}
#endif

#if 0 /* Not ready yet */
static void radeon_reinitialize_QW(struct radeonfb_info *rinfo)
{
	int i;
	u32 tmp, tmp2;
	u32 cko, cka, ckb;
	u32 cgc, cec, c2gc;

	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
	OUTREG(BUS_CNTL, rinfo->save_regs[36]);
	OUTREG(RBBM_CNTL, rinfo->save_regs[39]);

	INREG(PAD_CTLR_STRENGTH);
	OUTREG(PAD_CTLR_STRENGTH, INREG(PAD_CTLR_STRENGTH) & ~0x10000);
	for (i = 0; i < 65; ++i) {
		mdelay(1);
		INREG(PAD_CTLR_STRENGTH);
	}

	OUTREG(DISP_TEST_DEBUG_CNTL, INREG(DISP_TEST_DEBUG_CNTL) | 0x10000000);
	OUTREG(OV0_FLAG_CNTRL, INREG(OV0_FLAG_CNTRL) | 0x100);
	OUTREG(CRTC_GEN_CNTL, INREG(CRTC_GEN_CNTL));
	OUTREG(DAC_CNTL, 0xff00410a);
	OUTREG(CRTC2_GEN_CNTL, INREG(CRTC2_GEN_CNTL));
	OUTREG(DAC_CNTL2, INREG(DAC_CNTL2) | 0x4000);

	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
	OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]);
	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);

	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A0, 0xf7bb4433);
	OUTREG(MC_IND_INDEX, 0);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B0, 0xf7bb4433);
	OUTREG(MC_IND_INDEX, 0);

	OUTREG(CRTC_MORE_CNTL, INREG(CRTC_MORE_CNTL));

	tmp = INPLL(pllVCLK_ECP_CNTL);
	OUTPLL(pllVCLK_ECP_CNTL, tmp);
	tmp = INPLL(pllPIXCLKS_CNTL);
	OUTPLL(pllPIXCLKS_CNTL, tmp);

	OUTPLL(MCLK_CNTL, 0xaa3f0000);
	OUTPLL(SCLK_CNTL, 0xffff0000);
	OUTPLL(pllMPLL_AUX_CNTL, 6);
	OUTPLL(pllSPLL_AUX_CNTL, 1);
	OUTPLL(MDLL_CKO, 0x9f009f);
	OUTPLL(MDLL_RDCKA, 0x830083);
	OUTPLL(pllMDLL_RDCKB, 0x830083);
	OUTPLL(PPLL_CNTL, 0xa433);
	OUTPLL(P2PLL_CNTL, 0xa433);
	OUTPLL(MPLL_CNTL, 0x0400a403);
	OUTPLL(SPLL_CNTL, 0x0400a433);

	tmp = INPLL(M_SPLL_REF_FB_DIV);
	OUTPLL(M_SPLL_REF_FB_DIV, tmp);
	tmp = INPLL(M_SPLL_REF_FB_DIV);
	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0xc);
	INPLL(M_SPLL_REF_FB_DIV);

	tmp = INPLL(MPLL_CNTL);
	OUTREG8(CLOCK_CNTL_INDEX, MPLL_CNTL + PLL_WR_EN);
	radeon_pll_errata_after_index(rinfo);
	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
	radeon_pll_errata_after_data(rinfo);

	tmp = INPLL(M_SPLL_REF_FB_DIV);
	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x5900);

	tmp = INPLL(MPLL_CNTL);
	OUTPLL(MPLL_CNTL, tmp & ~0x2);
	mdelay(1);
	tmp = INPLL(MPLL_CNTL);
	OUTPLL(MPLL_CNTL, tmp & ~0x1);
	mdelay(10);

	OUTPLL(MCLK_CNTL, 0xaa3f1212);
	mdelay(1);

	INPLL(M_SPLL_REF_FB_DIV);
	INPLL(MCLK_CNTL);
	INPLL(M_SPLL_REF_FB_DIV);

	tmp = INPLL(SPLL_CNTL);
	OUTREG8(CLOCK_CNTL_INDEX, SPLL_CNTL + PLL_WR_EN);
	radeon_pll_errata_after_index(rinfo);
	OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
	radeon_pll_errata_after_data(rinfo);

	tmp = INPLL(M_SPLL_REF_FB_DIV);
	OUTPLL(M_SPLL_REF_FB_DIV, tmp | 0x780000);

	tmp = INPLL(SPLL_CNTL);
	OUTPLL(SPLL_CNTL, tmp & ~0x1);
	mdelay(1);
	tmp = INPLL(SPLL_CNTL);
	OUTPLL(SPLL_CNTL, tmp & ~0x2);
	mdelay(10);

	tmp = INPLL(SCLK_CNTL);
	OUTPLL(SCLK_CNTL, tmp | 2);
	mdelay(1);

	cko = INPLL(pllMDLL_CKO);
	cka = INPLL(pllMDLL_RDCKA);
	ckb = INPLL(pllMDLL_RDCKB);

	cko &= ~(MDLL_CKO__MCKOA_SLEEP | MDLL_CKO__MCKOB_SLEEP);
	OUTPLL(pllMDLL_CKO, cko);
	mdelay(1);
	cko &= ~(MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
	OUTPLL(pllMDLL_CKO, cko);
	mdelay(5);

	cka &= ~(MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP);
	OUTPLL(pllMDLL_RDCKA, cka);
	mdelay(1);
	cka &= ~(MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET);
	OUTPLL(pllMDLL_RDCKA, cka);
	mdelay(5);

	ckb &= ~(MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP);
	OUTPLL(pllMDLL_RDCKB, ckb);
	mdelay(1);
	ckb &= ~(MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET);
	OUTPLL(pllMDLL_RDCKB, ckb);
	mdelay(5);

	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, 0x151550ff);
	OUTREG(MC_IND_INDEX, 0);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, 0x151550ff);
	OUTREG(MC_IND_INDEX, 0);
	mdelay(1);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_A1, 0x141550ff);
	OUTREG(MC_IND_INDEX, 0);
	OUTMC(rinfo, ixMC_CHP_IO_CNTL_B1, 0x141550ff);
	OUTREG(MC_IND_INDEX, 0);
	mdelay(1);

	OUTPLL(pllHTOTAL_CNTL, 0);
	OUTPLL(pllHTOTAL2_CNTL, 0);

	OUTREG(MEM_CNTL, 0x29002901);
	OUTREG(MEM_SDRAM_MODE_REG, 0x45320032);	/* XXX use save_regs[35]? */
	OUTREG(EXT_MEM_CNTL, 0x1a394333);
	OUTREG(MEM_IO_CNTL_A1, 0x0aac0aac);
	OUTREG(MEM_INIT_LATENCY_TIMER, 0x34444444);
	OUTREG(MEM_REFRESH_CNTL, 0x1f1f7218);	/* XXX or save_regs[42]? */
	OUTREG(MC_DEBUG, 0);
	OUTREG(MEM_IO_OE_CNTL, 0x04300430);

	OUTMC(rinfo, ixMC_IMP_CNTL, 0x00f460d6);
	OUTREG(MC_IND_INDEX, 0);
	OUTMC(rinfo, ixMC_IMP_CNTL_0, 0x00009249);
	OUTREG(MC_IND_INDEX, 0);

	OUTREG(CNFG_MEMSIZE, rinfo->video_ram);

	radeon_pm_full_reset_sdram(rinfo);

	INREG(FP_GEN_CNTL);
	OUTREG(TMDS_CNTL, 0x01000000);	/* XXX ? */
	tmp = INREG(FP_GEN_CNTL);
	tmp |= FP_CRTC_DONT_SHADOW_HEND | FP_CRTC_DONT_SHADOW_VPAR | 0x200;
	OUTREG(FP_GEN_CNTL, tmp);

	tmp = INREG(DISP_OUTPUT_CNTL);
	tmp &= ~0x400;
	OUTREG(DISP_OUTPUT_CNTL, tmp);

	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);

	tmp = INPLL(MCLK_MISC);
	tmp |= MCLK_MISC__MC_MCLK_DYN_ENABLE | MCLK_MISC__IO_MCLK_DYN_ENABLE;
	OUTPLL(MCLK_MISC, tmp);

	tmp = INPLL(SCLK_CNTL);
	OUTPLL(SCLK_CNTL, tmp);

	OUTREG(CRTC_MORE_CNTL, 0);
	OUTREG8(CRTC_GEN_CNTL+1, 6);
	OUTREG8(CRTC_GEN_CNTL+3, 1);
	OUTREG(CRTC_PITCH, 32);

	tmp = INPLL(VCLK_ECP_CNTL);
	OUTPLL(VCLK_ECP_CNTL, tmp);

	tmp = INPLL(PPLL_CNTL);
	OUTPLL(PPLL_CNTL, tmp);

	/* palette stuff and BIOS_1_SCRATCH... */

	tmp = INREG(FP_GEN_CNTL);
	tmp2 = INREG(TMDS_TRANSMITTER_CNTL);
	tmp |= 2;
	OUTREG(FP_GEN_CNTL, tmp);
	mdelay(5);
	OUTREG(FP_GEN_CNTL, tmp);
	mdelay(5);
	OUTREG(TMDS_TRANSMITTER_CNTL, tmp2);
	OUTREG(CRTC_MORE_CNTL, 0);
	mdelay(20);

	tmp = INREG(CRTC_MORE_CNTL);
	OUTREG(CRTC_MORE_CNTL, tmp);

	cgc = INREG(CRTC_GEN_CNTL);
	cec = INREG(CRTC_EXT_CNTL);
	c2gc = INREG(CRTC2_GEN_CNTL);

	OUTREG(CRTC_H_SYNC_STRT_WID, 0x008e0580);
	OUTREG(CRTC_H_TOTAL_DISP, 0x009f00d2);
	OUTREG8(CLOCK_CNTL_INDEX, HTOTAL_CNTL + PLL_WR_EN);
	radeon_pll_errata_after_index(rinfo);
	OUTREG8(CLOCK_CNTL_DATA, 0);
	radeon_pll_errata_after_data(rinfo);
	OUTREG(CRTC_V_SYNC_STRT_WID, 0x00830403);
	OUTREG(CRTC_V_TOTAL_DISP, 0x03ff0429);
	OUTREG(FP_CRTC_H_TOTAL_DISP, 0x009f0033);
	OUTREG(FP_H_SYNC_STRT_WID, 0x008e0080);
	OUTREG(CRT_CRTC_H_SYNC_STRT_WID, 0x008e0080);
	OUTREG(FP_CRTC_V_TOTAL_DISP, 0x03ff002a);
	OUTREG(FP_V_SYNC_STRT_WID, 0x00830004);
	OUTREG(CRT_CRTC_V_SYNC_STRT_WID, 0x00830004);
	OUTREG(FP_HORZ_VERT_ACTIVE, 0x009f03ff);
	OUTREG(FP_HORZ_STRETCH, 0);
	OUTREG(FP_VERT_STRETCH, 0);
	OUTREG(OVR_CLR, 0);
	OUTREG(OVR_WID_LEFT_RIGHT, 0);
	OUTREG(OVR_WID_TOP_BOTTOM, 0);

	tmp = INPLL(PPLL_REF_DIV);
	tmp = (tmp & ~PPLL_REF_DIV_MASK) | rinfo->pll.ref_div;
	OUTPLL(PPLL_REF_DIV, tmp);
	INPLL(PPLL_REF_DIV);

	OUTREG8(CLOCK_CNTL_INDEX, PPLL_CNTL + PLL_WR_EN);
	radeon_pll_errata_after_index(rinfo);
	OUTREG8(CLOCK_CNTL_DATA + 1, 0xbc);
	radeon_pll_errata_after_data(rinfo);

	tmp = INREG(CLOCK_CNTL_INDEX);
	radeon_pll_errata_after_index(rinfo);
	OUTREG(CLOCK_CNTL_INDEX, tmp & 0xff);
	radeon_pll_errata_after_index(rinfo);
	radeon_pll_errata_after_data(rinfo);

	OUTPLL(PPLL_DIV_0, 0x48090);

	tmp = INPLL(PPLL_CNTL);
	OUTPLL(PPLL_CNTL, tmp & ~0x2);
	mdelay(1);
	tmp = INPLL(PPLL_CNTL);
	OUTPLL(PPLL_CNTL, tmp & ~0x1);
	mdelay(10);

	tmp = INPLL(VCLK_ECP_CNTL);
	OUTPLL(VCLK_ECP_CNTL, tmp | 3);
	mdelay(1);

	tmp = INPLL(VCLK_ECP_CNTL);
	OUTPLL(VCLK_ECP_CNTL, tmp);

	c2gc |= CRTC2_DISP_REQ_EN_B;
	OUTREG(CRTC2_GEN_CNTL, c2gc);
	cgc |= CRTC_EN;
	OUTREG(CRTC_GEN_CNTL, cgc);
	OUTREG(CRTC_EXT_CNTL, cec);
	OUTREG(CRTC_PITCH, 0xa0);
	OUTREG(CRTC_OFFSET, 0);
	OUTREG(CRTC_OFFSET_CNTL, 0);

	OUTREG(GRPH_BUFFER_CNTL, 0x20117c7c);
	OUTREG(GRPH2_BUFFER_CNTL, 0x00205c5c);

	tmp2 = INREG(FP_GEN_CNTL);
	tmp = INREG(TMDS_TRANSMITTER_CNTL);
	OUTREG(0x2a8, 0x0000061b);
	tmp |= TMDS_PLL_EN;
	OUTREG(TMDS_TRANSMITTER_CNTL, tmp);
	mdelay(1);
	tmp &= ~TMDS_PLLRST;
	OUTREG(TMDS_TRANSMITTER_CNTL, tmp);
	tmp2 &= ~2;
	tmp2 |= FP_TMDS_EN;
	OUTREG(FP_GEN_CNTL, tmp2);
	mdelay(5);
	tmp2 |= FP_FPON;
	OUTREG(FP_GEN_CNTL, tmp2);

	OUTREG(CUR_HORZ_VERT_OFF, CUR_LOCK | 1);
	cgc = INREG(CRTC_GEN_CNTL);
	OUTREG(CUR_HORZ_VERT_POSN, 0xbfff0fff);
	cgc |= 0x10000;
	OUTREG(CUR_OFFSET, 0);
}
#endif /* 0 */

#endif /* CONFIG_PPC */

static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t state)
{}

static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
{}

static int radeonfb_pci_suspend_late(struct device *dev, pm_message_t mesg)
{}

static int radeonfb_pci_suspend(struct device *dev)
{}

static int radeonfb_pci_hibernate(struct device *dev)
{}

static int radeonfb_pci_freeze(struct device *dev)
{}

static int radeon_check_power_loss(struct radeonfb_info *rinfo)
{}

static int radeonfb_pci_resume(struct device *dev)
{}

const struct dev_pm_ops radeonfb_pci_pm_ops =;

#ifdef CONFIG_PPC__disabled
static void radeonfb_early_resume(void *data)
{
        struct radeonfb_info *rinfo = data;

	rinfo->no_schedule = 1;
	pci_restore_state(rinfo->pdev);
	radeonfb_pci_resume(rinfo->pdev);
	rinfo->no_schedule = 0;
}
#endif /* CONFIG_PPC */

#endif /* CONFIG_PM */

void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)
{}

void radeonfb_pm_exit(struct radeonfb_info *rinfo)
{}