staticvoid gx_save_regs(struct gxfb_par *par)
{ int i;
/* wait for the BLT engine to stop being busy */ do {
i = read_gp(par, GP_BLT_STATUS);
} while (i & (GP_BLT_STATUS_BLT_PENDING | GP_BLT_STATUS_BLT_BUSY));
/* save MSRs */
rdmsrq(MSR_GX_MSR_PADSEL, par->msr.padsel);
rdmsrq(MSR_GLCP_DOTPLL, par->msr.dotpll);
/* wait for the PLL to lock */ for (i = 0; i < 200; i++) {
rdmsrq(MSR_GLCP_DOTPLL, dotpll_lo); if (dotpll_lo & MSR_GLCP_DOTPLL_LOCK) break;
udelay(1);
}
staticvoid gx_restore_gfx_proc(struct gxfb_par *par)
{ int i;
for (i = 0; i < ARRAY_SIZE(par->gp); i++) { switch (i) { case GP_VECTOR_MODE: case GP_BLT_MODE: case GP_BLT_STATUS: case GP_HST_SRC: /* don't restore these registers */ break; default:
write_gp(par, i, par->gp[i]);
}
}
}
staticvoid gx_restore_display_ctlr(struct gxfb_par *par)
{ int i;
for (i = 0; i < ARRAY_SIZE(par->dc); i++) { switch (i) { case DC_UNLOCK: /* unlock the DC; runs first */
write_dc(par, DC_UNLOCK, DC_UNLOCK_UNLOCK); break;
case DC_GENERAL_CFG: /* write without the enables */
write_dc(par, i, par->dc[i] & ~(DC_GENERAL_CFG_VIDE |
DC_GENERAL_CFG_ICNE |
DC_GENERAL_CFG_CURE |
DC_GENERAL_CFG_DFLE)); break;
case DC_DISPLAY_CFG: /* write without the enables */
write_dc(par, i, par->dc[i] & ~(DC_DISPLAY_CFG_VDEN |
DC_DISPLAY_CFG_GDEN |
DC_DISPLAY_CFG_TGEN)); break;
case DC_RSVD_0: case DC_RSVD_1: case DC_RSVD_2: case DC_RSVD_3: case DC_RSVD_4: case DC_LINE_CNT: case DC_PAL_ADDRESS: case DC_PAL_DATA: case DC_DFIFO_DIAG: case DC_CFIFO_DIAG: case DC_RSVD_5: /* don't restore these registers */ break; default:
write_dc(par, i, par->dc[i]);
}
}
/* restore the palette */
write_dc(par, DC_PAL_ADDRESS, 0); for (i = 0; i < ARRAY_SIZE(par->pal); i++)
write_dc(par, DC_PAL_DATA, par->pal[i]);
}
staticvoid gx_restore_video_proc(struct gxfb_par *par)
{ int i;
wrmsrq(MSR_GX_MSR_PADSEL, par->msr.padsel);
for (i = 0; i < ARRAY_SIZE(par->vp); i++) { switch (i) { case VP_VCFG: /* don't enable video yet */
write_vp(par, i, par->vp[i] & ~VP_VCFG_VID_EN); break;
case VP_DCFG: /* don't enable CRT yet */
write_vp(par, i, par->vp[i] &
~(VP_DCFG_DAC_BL_EN | VP_DCFG_VSYNC_EN |
VP_DCFG_HSYNC_EN | VP_DCFG_CRT_EN)); break;
case VP_GAR: case VP_GDR: case VP_RSVD_0: case VP_RSVD_1: case VP_RSVD_2: case VP_RSVD_3: case VP_CRC32: case VP_AWT: case VP_VTM: /* don't restore these registers */ break; default:
write_vp(par, i, par->vp[i]);
}
}
}
staticvoid gx_restore_regs(struct gxfb_par *par)
{ int i;
fp = read_fp(par, FP_PM); if (par->fp[FP_PM] & FP_PM_P) { /* power on the panel if not already power{ed,ing} on */ if (!(fp & (FP_PM_PANEL_ON|FP_PM_PANEL_PWR_UP)))
write_fp(par, FP_PM, par->fp[FP_PM]);
} else { /* power down the panel if not already power{ed,ing} down */ if (!(fp & (FP_PM_PANEL_OFF|FP_PM_PANEL_PWR_DOWN)))
write_fp(par, FP_PM, par->fp[FP_PM]);
}
/* turn everything on */
write_vp(par, VP_VCFG, par->vp[VP_VCFG]);
write_vp(par, VP_DCFG, par->vp[VP_DCFG]);
write_dc(par, DC_DISPLAY_CFG, par->dc[DC_DISPLAY_CFG]); /* do this last; it will enable the FIFO load */
write_dc(par, DC_GENERAL_CFG, par->dc[DC_GENERAL_CFG]);
/* lock the door behind us */
write_dc(par, DC_UNLOCK, DC_UNLOCK_LOCK);
}
int gx_powerdown(struct fb_info *info)
{ struct gxfb_par *par = info->par;
if (par->powered_down) return 0;
gx_save_regs(par);
gx_disable_graphics(par);
par->powered_down = 1; return 0;
}
int gx_powerup(struct fb_info *info)
{ struct gxfb_par *par = info->par;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.