/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.driver.video.ati.radeon; import org.jnode.driver.video.vgahw.DisplayMode; import org.jnode.util.NumberUtils; /** * @author Ewout Prangsma (epr@users.sourceforge.net) */ final class FpRegs implements RadeonConstants { /* Flat panel regs */ private int fp_crtc_h_total_disp; private int fp_crtc_v_total_disp; private int fp_gen_cntl; private int fp_h_sync_strt_wid; private int fp_horz_stretch; private int fp_v_sync_strt_wid; private int fp_vert_stretch; private int lvds_gen_cntl; private int lvds_pll_cntl; private int tmds_crc; private int tmds_transmitter_cntl; /** * Initialize from a given IO. */ public void saveFromVGA(RadeonVgaIO io) { this.fp_crtc_h_total_disp = io.getReg32(FP_CRTC_H_TOTAL_DISP); this.fp_crtc_v_total_disp = io.getReg32(FP_CRTC_V_TOTAL_DISP); this.fp_h_sync_strt_wid = io.getReg32(FP_H_SYNC_STRT_WID); this.fp_v_sync_strt_wid = io.getReg32(FP_V_SYNC_STRT_WID); this.fp_horz_stretch = io.getReg32(FP_HORZ_STRETCH); this.fp_vert_stretch = io.getReg32(FP_VERT_STRETCH); this.fp_gen_cntl = io.getReg32(FP_GEN_CNTL); this.lvds_gen_cntl = io.getReg32(LVDS_GEN_CNTL); this.lvds_pll_cntl = io.getReg32(LVDS_PLL_CNTL); this.tmds_crc = io.getReg32(TMDS_CRC); this.tmds_transmitter_cntl = io.getReg32(TMDS_TRANSMITTER_CNTL); } /** * Save this state to VGA. */ public final void restoreToVGA(RadeonVgaIO io) { io.setReg32(FP_CRTC_H_TOTAL_DISP, fp_crtc_h_total_disp); io.setReg32(FP_CRTC_V_TOTAL_DISP, fp_crtc_v_total_disp); io.setRegP32(FP_GEN_CNTL, fp_gen_cntl, FP_SEL_CRTC2); io.setReg32(FP_H_SYNC_STRT_WID, fp_h_sync_strt_wid); // io.setReg32(FP_HORZ_STRETCH, fp_horz_stretch); io.setReg32(FP_V_SYNC_STRT_WID, fp_v_sync_strt_wid); // io.setReg32(FP_VERT_STRETCH, fp_vert_stretch); io.setRegP32(LVDS_GEN_CNTL, lvds_gen_cntl, LVDS_ON | LVDS_BLON); // io.setReg32(LVDS_PLL_CNTL, lvds_pll_cntl); io.setReg32(TMDS_CRC, tmds_crc); io.setReg32(TMDS_TRANSMITTER_CNTL, tmds_transmitter_cntl); } /** * Set this state up for a given configuration; * * @param config * @param io */ final void calcForConfiguration(RadeonConfiguration config, PLLInfo pllInfo, RadeonVgaIO io, FBInfo fbinfo, CrtcRegs crtc) { final DisplayMode mode = config.getDisplayMode(); @SuppressWarnings("unused") final int bpp = config.getBitsPerPixel(); final int panel_xres = fbinfo.getPanelXres(); final int panel_yres = fbinfo.getPanelYres(); final int xres = Math.max(mode.getWidth(), panel_xres); final int yres = Math.max(mode.getHeight(), panel_yres); final float hRatio = (float) xres / (float) panel_xres; final float vRatio = (float) yres / (float) panel_yres; if ((hRatio == 1.0f) || true) { fp_horz_stretch &= ~(HORZ_STRETCH_BLEND | HORZ_STRETCH_ENABLE); fp_horz_stretch &= ~(HORZ_AUTO_RATIO | HORZ_PANEL_SIZE); fp_horz_stretch |= ((xres / 8 - 1) << 16); } else { fp_horz_stretch = (((int) ((hRatio * HORZ_STRETCH_RATIO_MAX + 0.5)) & HORZ_STRETCH_RATIO_MASK)) | (fp_horz_stretch & (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH | HORZ_AUTO_RATIO_INC)); fp_horz_stretch |= (HORZ_STRETCH_BLEND | HORZ_STRETCH_ENABLE); fp_horz_stretch &= ~(HORZ_AUTO_RATIO | HORZ_PANEL_SIZE); fp_horz_stretch |= ((panel_xres / 8 - 1) << HORZ_PANEL_SHIFT); } if ((vRatio == 1.0f) || true) { fp_vert_stretch &= ~(VERT_STRETCH_ENABLE | VERT_STRETCH_BLEND); fp_vert_stretch &= ~(VERT_AUTO_RATIO_EN | VERT_PANEL_SIZE); fp_vert_stretch |= ((yres - 1) << 12); } else { fp_vert_stretch = (((((int) (vRatio * VERT_STRETCH_RATIO_MAX + 0.5)) & VERT_STRETCH_RATIO_MASK)) | (fp_vert_stretch & (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED))); fp_vert_stretch |= (VERT_STRETCH_ENABLE | VERT_STRETCH_BLEND); fp_vert_stretch &= ~(VERT_AUTO_RATIO_EN | VERT_PANEL_SIZE); fp_vert_stretch |= ((panel_yres - 1) << VERT_PANEL_SHIFT); } fp_gen_cntl &= ~(FP_SEL_CRTC2 | FP_RMX_HVSYNC_CONTROL_EN | FP_DFP_SYNC_SEL | FP_CRT_SYNC_SEL | /* FP_CRTC_LOCK_8DOT | FP_USE_SHADOW_EN | */ FP_CRTC_USE_SHADOW_VEND | FP_CRT_SYNC_ALT); fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | FP_CRTC_DONT_SHADOW_HEND); if (fbinfo.getPrimaryMonitorType() == MonitorType.LCD) { lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN); } else { /* DFP */ fp_gen_cntl |= (FP_FPON | FP_TMDS_EN); tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | ICHCSEL | TMDS_PLL_EN) & ~(TMDS_PLLRST); } fp_crtc_h_total_disp = crtc.getCrtc_h_total_disp(); fp_crtc_v_total_disp = crtc.getCrtc_v_total_disp(); fp_h_sync_strt_wid = crtc.getCrtc_h_sync_strt_wid(); fp_v_sync_strt_wid = crtc.getCrtc_v_sync_strt_wid(); } @SuppressWarnings("unused") private static final int round_div(int num, int den) { return (num + (den / 2)) / den; } public String toString() { return "fp_crtc_h_total_disp:" + fp_crtc_h_total_disp + ", fp_crtc_v_total_disp:" + fp_crtc_v_total_disp + ", fp_gen_cntl:0x" + NumberUtils.hex(fp_gen_cntl) + ", fp_h_sync_strt_wid:" + fp_h_sync_strt_wid + ", fp_horz_stretch:" + fp_horz_stretch + ", fp_v_sync_strt_wid:" + fp_v_sync_strt_wid + ", fp_vert_stretch:" + fp_vert_stretch + ", lvds_gen_cntl:0x" + NumberUtils.hex(lvds_gen_cntl) + ", lvds_pll_cntl:0x" + NumberUtils.hex(lvds_pll_cntl) + ", tmds_crc:" + tmds_crc + ", tmds_transmitter_cntl:0x" + NumberUtils.hex(tmds_transmitter_cntl); } }