+static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo)
+{
+ u32 tmp, tmp2;
+ int i,j;
+
+ /* Reset the PAD_CTLR_STRENGTH & wait for it to be stable */
+ INREG(PAD_CTLR_STRENGTH);
+ OUTREG(PAD_CTLR_STRENGTH, INREG(PAD_CTLR_STRENGTH) & ~PAD_MANUAL_OVERRIDE);
+ tmp = INREG(PAD_CTLR_STRENGTH);
+ for (i = j = 0; i < 65; ++i) {
+ mdelay(1);
+ tmp2 = INREG(PAD_CTLR_STRENGTH);
+ if (tmp != tmp2) {
+ tmp = tmp2;
+ i = 0;
+ j++;
+ if (j > 10) {
+ printk(KERN_WARNING "radeon: PAD_CTLR_STRENGTH doesn't "
+ "stabilize !\n");
+ break;
+ }
+ }
+ }
+}
+
+static void radeon_pm_all_ppls_off(struct radeonfb_info *rinfo)
+{
+ u32 tmp;
+
+ tmp = INPLL(pllPPLL_CNTL);
+ OUTPLL(pllPPLL_CNTL, tmp | 0x3);
+ tmp = INPLL(pllP2PLL_CNTL);
+ OUTPLL(pllP2PLL_CNTL, tmp | 0x3);
+ tmp = INPLL(pllSPLL_CNTL);
+ OUTPLL(pllSPLL_CNTL, tmp | 0x3);
+ tmp = INPLL(pllMPLL_CNTL);
+ OUTPLL(pllMPLL_CNTL, tmp | 0x3);
+}
+
+static void radeon_pm_start_mclk_sclk(struct radeonfb_info *rinfo)
+{
+ u32 tmp;
+
+ /* Switch SPLL to PCI source */
+ tmp = INPLL(pllSCLK_CNTL);
+ OUTPLL(pllSCLK_CNTL, tmp & ~SCLK_CNTL__SCLK_SRC_SEL_MASK);
+
+ /* Reconfigure SPLL charge pump, VCO gain, duty cycle */
+ tmp = INPLL(pllSPLL_CNTL);
+ OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
+ OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+ radeon_pll_errata_after_data(rinfo);
+
+ /* Set SPLL feedback divider */
+ tmp = INPLL(pllM_SPLL_REF_FB_DIV);
+ tmp = (tmp & 0xff00fffful) | (rinfo->save_regs[77] & 0x00ff0000ul);
+ OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);
+
+ /* Power up SPLL */
+ tmp = INPLL(pllSPLL_CNTL);
+ OUTPLL(pllSPLL_CNTL, tmp & ~1);
+ (void)INPLL(pllSPLL_CNTL);
+
+ mdelay(10);
+
+ /* Release SPLL reset */
+ tmp = INPLL(pllSPLL_CNTL);
+ OUTPLL(pllSPLL_CNTL, tmp & ~0x2);
+ (void)INPLL(pllSPLL_CNTL);
+
+ mdelay(10);
+
+ /* Select SCLK source */
+ tmp = INPLL(pllSCLK_CNTL);
+ tmp &= ~SCLK_CNTL__SCLK_SRC_SEL_MASK;
+ tmp |= rinfo->save_regs[3] & SCLK_CNTL__SCLK_SRC_SEL_MASK;
+ OUTPLL(pllSCLK_CNTL, tmp);
+ (void)INPLL(pllSCLK_CNTL);
+
+ mdelay(10);
+
+ /* Reconfigure MPLL charge pump, VCO gain, duty cycle */
+ tmp = INPLL(pllMPLL_CNTL);
+ OUTREG8(CLOCK_CNTL_INDEX, pllMPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
+ OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+ radeon_pll_errata_after_data(rinfo);
+
+ /* Set MPLL feedback divider */
+ tmp = INPLL(pllM_SPLL_REF_FB_DIV);
+ tmp = (tmp & 0xffff00fful) | (rinfo->save_regs[77] & 0x0000ff00ul);
+
+ OUTPLL(pllM_SPLL_REF_FB_DIV, tmp);
+ /* Power up MPLL */
+ tmp = INPLL(pllMPLL_CNTL);
+ OUTPLL(pllMPLL_CNTL, tmp & ~0x2);
+ (void)INPLL(pllMPLL_CNTL);
+
+ mdelay(10);
+
+ /* Un-reset MPLL */
+ tmp = INPLL(pllMPLL_CNTL);
+ OUTPLL(pllMPLL_CNTL, tmp & ~0x1);
+ (void)INPLL(pllMPLL_CNTL);
+
+ mdelay(10);
+
+ /* Select source for MCLK */
+ tmp = INPLL(pllMCLK_CNTL);
+ tmp |= rinfo->save_regs[2] & 0xffff;
+ OUTPLL(pllMCLK_CNTL, tmp);
+ (void)INPLL(pllMCLK_CNTL);
+
+ mdelay(10);
+}
+
+static void radeon_pm_m10_disable_spread_spectrum(struct radeonfb_info *rinfo)
+{
+ u32 r2ec;
+
+ /* GACK ! I though we didn't have a DDA on Radeon's anymore
+ * here we rewrite with the same value, ... I suppose we clear
+ * some bits that are already clear ? Or maybe this 0x2ec
+ * register is something new ?
+ */
+ mdelay(20);
+ r2ec = INREG(VGA_DDA_ON_OFF);
+ OUTREG(VGA_DDA_ON_OFF, r2ec);
+ mdelay(1);
+
+ /* Spread spectrum PLLL off */
+ OUTPLL(pllSSPLL_CNTL, 0xbf03);
+
+ /* Spread spectrum disabled */
+ OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90] & ~3);
+
+ /* The trace shows read & rewrite of LVDS_PLL_CNTL here with same
+ * value, not sure what for...
+ */
+
+ r2ec |= 0x3f0;
+ OUTREG(VGA_DDA_ON_OFF, r2ec);
+ mdelay(1);
+}
+
+static void radeon_pm_m10_enable_lvds_spread_spectrum(struct radeonfb_info *rinfo)
+{
+ u32 r2ec, tmp;
+
+ /* GACK (bis) ! I though we didn't have a DDA on Radeon's anymore
+ * here we rewrite with the same value, ... I suppose we clear/set
+ * some bits that are already clear/set ?
+ */
+ r2ec = INREG(VGA_DDA_ON_OFF);
+ OUTREG(VGA_DDA_ON_OFF, r2ec);
+ mdelay(1);
+
+ /* Enable spread spectrum */
+ OUTPLL(pllSSPLL_CNTL, rinfo->save_regs[43] | 3);
+ mdelay(3);
+
+ OUTPLL(pllSSPLL_REF_DIV, rinfo->save_regs[44]);
+ OUTPLL(pllSSPLL_DIV_0, rinfo->save_regs[45]);
+ tmp = INPLL(pllSSPLL_CNTL);
+ OUTPLL(pllSSPLL_CNTL, tmp & ~0x2);
+ mdelay(6);
+ tmp = INPLL(pllSSPLL_CNTL);
+ OUTPLL(pllSSPLL_CNTL, tmp & ~0x1);
+ mdelay(5);
+
+ OUTPLL(pllSS_INT_CNTL, rinfo->save_regs[90]);
+
+ r2ec |= 8;
+ OUTREG(VGA_DDA_ON_OFF, r2ec);
+ mdelay(20);
+
+ /* Enable LVDS interface */
+ tmp = INREG(LVDS_GEN_CNTL);
+ OUTREG(LVDS_GEN_CNTL, tmp | LVDS_EN);
+
+ /* Enable LVDS_PLL */
+ tmp = INREG(LVDS_PLL_CNTL);
+ tmp &= ~0x30000;
+ tmp |= 0x10000;
+ OUTREG(LVDS_PLL_CNTL, tmp);
+
+ OUTPLL(pllSCLK_MORE_CNTL, rinfo->save_regs[34]);
+ OUTPLL(pllSS_TST_CNTL, rinfo->save_regs[91]);
+
+ /* The trace reads that one here, waiting for something to settle down ? */
+ INREG(RBBM_STATUS);
+
+ /* Ugh ? SS_TST_DEC is supposed to be a read register in the
+ * R300 register spec at least...
+ */
+ tmp = INPLL(pllSS_TST_CNTL);
+ tmp |= 0x00400000;
+ OUTPLL(pllSS_TST_CNTL, tmp);
+}
+
+static void radeon_pm_restore_pixel_pll(struct radeonfb_info *rinfo)
+{
+ u32 tmp;
+
+ OUTREG8(CLOCK_CNTL_INDEX, pllHTOTAL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
+ OUTREG8(CLOCK_CNTL_DATA, 0);
+ radeon_pll_errata_after_data(rinfo);
+
+ tmp = INPLL(pllVCLK_ECP_CNTL);
+ OUTPLL(pllVCLK_ECP_CNTL, tmp | 0x80);
+ mdelay(5);
+
+ tmp = INPLL(pllPPLL_REF_DIV);
+ tmp = (tmp & ~PPLL_REF_DIV_MASK) | rinfo->pll.ref_div;
+ OUTPLL(pllPPLL_REF_DIV, tmp);
+ INPLL(pllPPLL_REF_DIV);
+
+ /* Reconfigure SPLL charge pump, VCO gain, duty cycle,
+ * probably useless since we already did it ...
+ */
+ tmp = INPLL(pllPPLL_CNTL);
+ OUTREG8(CLOCK_CNTL_INDEX, pllSPLL_CNTL + PLL_WR_EN);
+ radeon_pll_errata_after_index(rinfo);
+ OUTREG8(CLOCK_CNTL_DATA + 1, (tmp >> 8) & 0xff);
+ radeon_pll_errata_after_data(rinfo);
+
+ /* Restore our "reference" PPLL divider set by firmware
+ * according to proper spread spectrum calculations
+ */
+ OUTPLL(pllPPLL_DIV_0, rinfo->save_regs[92]);
+
+ tmp = INPLL(pllPPLL_CNTL);
+ OUTPLL(pllPPLL_CNTL, tmp & ~0x2);
+ mdelay(5);
+
+ tmp = INPLL(pllPPLL_CNTL);
+ OUTPLL(pllPPLL_CNTL, tmp & ~0x1);
+ mdelay(5);
+
+ tmp = INPLL(pllVCLK_ECP_CNTL);
+ OUTPLL(pllVCLK_ECP_CNTL, tmp | 3);
+ mdelay(5);
+
+ tmp = INPLL(pllVCLK_ECP_CNTL);
+ OUTPLL(pllVCLK_ECP_CNTL, tmp | 3);
+ mdelay(5);
+
+ /* Switch pixel clock to firmware default div 0 */
+ OUTREG8(CLOCK_CNTL_INDEX+1, 0);
+ radeon_pll_errata_after_index(rinfo);
+ radeon_pll_errata_after_data(rinfo);
+}
+
+static void radeon_pm_m10_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(MEM_REFRESH_CNTL, rinfo->save_regs[42]);
+ OUTREG(MC_READ_CNTL_AB, rinfo->save_regs[50]);
+ OUTREG(MC_CHIP_IO_OE_CNTL_AB, rinfo->save_regs[52]);
+ OUTREG(MC_IOPAD_CNTL, rinfo->save_regs[51]);
+ OUTREG(MC_DEBUG, rinfo->save_regs[53]);
+
+ OUTMC(rinfo, ixR300_MC_MC_INIT_WR_LAT_TIMER, rinfo->save_regs[58]);
+ OUTMC(rinfo, ixR300_MC_IMP_CNTL, rinfo->save_regs[59]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C0, rinfo->save_regs[60]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_C1, rinfo->save_regs[61]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D0, rinfo->save_regs[62]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_D1, rinfo->save_regs[63]);
+ OUTMC(rinfo, ixR300_MC_BIST_CNTL_3, rinfo->save_regs[64]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A0, rinfo->save_regs[65]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_A1, rinfo->save_regs[66]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B0, rinfo->save_regs[67]);
+ OUTMC(rinfo, ixR300_MC_CHP_IO_CNTL_B1, rinfo->save_regs[68]);
+ OUTMC(rinfo, ixR300_MC_DEBUG_CNTL, rinfo->save_regs[69]);
+ OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);
+ OUTMC(rinfo, ixR300_MC_IMP_CNTL_0, rinfo->save_regs[71]);
+ OUTMC(rinfo, ixR300_MC_ELPIDA_CNTL, rinfo->save_regs[72]);
+ OUTMC(rinfo, ixR300_MC_READ_CNTL_CD, rinfo->save_regs[96]);
+ OUTREG(MC_IND_INDEX, 0);
+}
+
+static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)
+{
+ u32 tmp, i;
+
+ /* Restore a bunch of registers first */
+ 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(CONFIG_MEMSIZE, rinfo->video_ram);
+ 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_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8);
+ OUTREG(DAC_MACRO_CNTL, (INREG(DAC_MACRO_CNTL) & ~0x6) | 8);
+
+ /* Hrm... */
+ 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 |= 8 << TV_DAC_CNTL_BGADJ__SHIFT;
+ OUTREG(TV_DAC_CNTL, tmp);
+
+ tmp = INREG(TV_DAC_CNTL) & ~TV_DAC_CNTL_DACADJ_MASK;
+ tmp |= 7 << TV_DAC_CNTL_DACADJ__SHIFT;
+ OUTREG(TV_DAC_CNTL, tmp);
+
+ /* More registers restored */
+ OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+ OUTREG(HOST_PATH_CNTL, rinfo->save_regs[41]);
+ OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+
+ /* Hrmmm ... What is that ? */
+ tmp = rinfo->save_regs[1]
+ & ~(CLK_PWRMGT_CNTL__ACTIVE_HILO_LAT_MASK |
+ CLK_PWRMGT_CNTL__MC_BUSY);
+ OUTPLL(pllCLK_PWRMGT_CNTL, tmp);
+
+ OUTREG(PAD_CTLR_MISC, rinfo->save_regs[56]);
+ OUTREG(FW_CNTL, rinfo->save_regs[57]);
+ OUTREG(HDP_DEBUG, rinfo->save_regs[96]);
+ OUTREG(PAMAC0_DLY_CNTL, rinfo->save_regs[54]);
+ OUTREG(PAMAC1_DLY_CNTL, rinfo->save_regs[55]);
+ OUTREG(PAMAC2_DLY_CNTL, rinfo->save_regs[79]);
+
+ /* Restore Memory Controller configuration */
+ radeon_pm_m10_reconfigure_mc(rinfo);
+
+ /* Make sure CRTC's dont touch memory */
+ OUTREG(CRTC_GEN_CNTL, INREG(CRTC_GEN_CNTL)
+ | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
+ OUTREG(CRTC2_GEN_CNTL, INREG(CRTC2_GEN_CNTL)
+ | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
+ mdelay(30);
+
+ /* 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]);
+
+ /* Switch MCLK, YCLK and SCLK PLLs to PCI source & force them 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;
+ OUTPLL(pllMCLK_CNTL, tmp);
+
+ /* Force all clocks on in SCLK */
+ tmp = INPLL(pllSCLK_CNTL);
+ tmp |= 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_PB|
+ SCLK_CNTL__FORCE_TAM|
+ SCLK_CNTL__FORCE_TDM|
+ SCLK_CNTL__FORCE_RB|
+ SCLK_CNTL__FORCE_TV_SCLK|
+ SCLK_CNTL__FORCE_SUBPIC|
+ SCLK_CNTL__FORCE_OV0;
+ tmp |= SCLK_CNTL__CP_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__HDP_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__TV_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__E2_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__SE_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__IDCT_MAX_DYN_STOP_LAT|
+ SCLK_CNTL__VIP_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__RE_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__PB_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__TAM_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__TDM_MAX_DYN_STOP_LAT |
+ SCLK_CNTL__RB_MAX_DYN_STOP_LAT;
+ OUTPLL(pllSCLK_CNTL, tmp);
+
+ OUTPLL(pllVCLK_ECP_CNTL, 0);
+ OUTPLL(pllPIXCLKS_CNTL, 0);
+ OUTPLL(pllMCLK_MISC,
+ MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT |
+ MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT);
+
+ mdelay(5);
+
+ /* Restore the M_SPLL_REF_FB_DIV, MPLL_AUX_CNTL and SPLL_AUX_CNTL values */
+ 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]);
+
+ /* Now restore the major PLLs settings, keeping them off & reset though */
+ OUTPLL(pllPPLL_CNTL, rinfo->save_regs[93] | 0x3);
+ OUTPLL(pllP2PLL_CNTL, rinfo->save_regs[8] | 0x3);
+ OUTPLL(pllMPLL_CNTL, rinfo->save_regs[73] | 0x03);
+ OUTPLL(pllSPLL_CNTL, rinfo->save_regs[74] | 0x03);
+
+ /* Restore MC DLL state and switch it off/reset too */
+ OUTMC(rinfo, ixR300_MC_DLL_CNTL, rinfo->save_regs[70]);
+
+ /* Switch MDLL off & reset */
+ OUTPLL(pllMDLL_RDCKA, rinfo->save_regs[98] | 0xff);
+ mdelay(5);
+
+ /* Setup some black magic bits in PLL_PWRMGT_CNTL. Hrm... we saved
+ * 0xa1100007... and MacOS writes 0xa1000007 ..
+ */
+ OUTPLL(pllPLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+
+ /* Restore more stuffs */
+ OUTPLL(pllHTOTAL_CNTL, 0);
+ OUTPLL(pllHTOTAL2_CNTL, 0);
+
+ /* More PLL initial configuration */
+ tmp = INPLL(pllSCLK_CNTL2); /* What for ? */
+ OUTPLL(pllSCLK_CNTL2, tmp);
+
+ tmp = INPLL(pllSCLK_MORE_CNTL);
+ tmp |= SCLK_MORE_CNTL__FORCE_DISPREGS | /* a guess */
+ SCLK_MORE_CNTL__FORCE_MC_GUI |
+ SCLK_MORE_CNTL__FORCE_MC_HOST;
+ OUTPLL(pllSCLK_MORE_CNTL, tmp);
+
+ /* 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 TMDS */
+ OUTREG(FP_GEN_CNTL, rinfo->save_regs[82]);
+ OUTREG(FP2_GEN_CNTL, rinfo->save_regs[83]);
+
+ /* Set LVDS registers but keep interface & pll down */
+ OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11] &
+ ~(LVDS_EN | LVDS_ON | LVDS_DIGON | LVDS_BLON | LVDS_BL_MOD_EN));
+ OUTREG(LVDS_PLL_CNTL, (rinfo->save_regs[12] & ~0xf0000) | 0x20000);
+
+ OUTREG(DISP_OUTPUT_CNTL, rinfo->save_regs[86]);
+
+ /* Restore GPIOPAD state */
+ OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+ OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+ OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+
+ /* write some stuff to the framebuffer... */
+ for (i = 0; i < 0x8000; ++i)
+ writeb(0, rinfo->fb_base + i);
+
+ 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]);
+
+ /* Take care of spread spectrum & PPLLs now */
+ radeon_pm_m10_disable_spread_spectrum(rinfo);
+ radeon_pm_restore_pixel_pll(rinfo);
+
+ /* GRRRR... I can't figure out the proper LVDS power sequence, and the
+ * code I have for blank/unblank doesn't quite work on some laptop models
+ * it seems ... Hrm. What I have here works most of the time ...
+ */
+ radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);
+}
+
+#ifdef CONFIG_PPC_OF
+
+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(CONFIG_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);
+}
+
+#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(CONFIG_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_OF */
+