summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@freedesktop.org>2008-07-08 16:45:49 +0200
committerEgbert Eich <eich@freedesktop.org>2008-07-08 16:45:49 +0200
commit4f06db8cc99ebe5523d02a922f8b602026b23666 (patch)
tree952546899886a09db587e04724fde15ad619f76c
parentede74365d822ee85343553277fb7239df3901284 (diff)
AtomBIOS: Add missing rhd_atomcrtc.c file.
-rw-r--r--src/rhd_atomcrtc.c426
1 files changed, 426 insertions, 0 deletions
diff --git a/src/rhd_atomcrtc.c b/src/rhd_atomcrtc.c
new file mode 100644
index 0000000..5aeff7f
--- /dev/null
+++ b/src/rhd_atomcrtc.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2007, 2008 Luc Verhaegen <lverhaegen@novell.com>
+ * Copyright 2007, 2008 Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007, 2008 Egbert Eich <eich@novell.com>
+ * Copyright 2007, 2008 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+
+#if HAVE_XF86_ANSIC_H
+# include "xf86_ansic.h"
+#else
+# include <unistd.h>
+#endif
+
+#include "rhd.h"
+#include "rhd_crtc.h"
+#include "rhd_pll.h"
+#include "rhd_lut.h"
+#include "rhd_regs.h"
+#include "rhd_modes.h"
+#ifdef ATOM_BIOS
+# include "rhd_atombios.h"
+
+# define D1_REG_OFFSET 0x0000
+# define D2_REG_OFFSET 0x0800
+
+/*
+ *
+ */
+static void
+rhdAtomCrtcRestore(struct rhdCrtc *Crtc, void *Store)
+{
+ ScrnInfoPtr pScrn = xf86Screens[Crtc->scrnIndex];
+ RHDPtr rhdPtr = RHDPTR(pScrn);
+ union AtomBiosArg data;
+
+ RHDFUNC(rhdPtr);
+
+ data.Address = Store;
+ RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_RESTORE_REGISTERS, &data);
+}
+
+struct rhdAtomScaleStore {
+ void *RegList;
+ CARD32 StoreViewportSize;
+ CARD32 StoreViewportStart;
+};
+
+/*
+ *
+ */
+static void
+rhdAtomScaleSet(struct rhdCrtc *Crtc, enum rhdCrtcScaleType Type,
+ DisplayModePtr Mode, DisplayModePtr ScaledToMode)
+{
+ RHDPtr rhdPtr = RHDPTRI(Crtc);
+ struct rhdScalerOverscan Overscan;
+ struct atomCrtcOverscan AtomOverscan;
+ enum atomCrtc AtomCrtc = RHD_CRTC_1;
+ enum atomScaler Scaler = 0;
+ enum atomScaleMode ScaleMode = 0;
+ union AtomBiosArg data;
+ CARD32 RegOff = 0;
+
+ RHDDebug(Crtc->scrnIndex, "FUNCTION: %s: %s viewport: %ix%i\n", __func__, Crtc->Name,
+ Mode->CrtcHDisplay, Mode->CrtcVDisplay);
+
+ /* D1Mode registers */
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE,
+ Mode->CrtcVDisplay | (Mode->CrtcHDisplay << 16));
+ RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, 0);
+
+ Overscan = rhdCalculateOverscan(Mode, ScaledToMode, Type);
+ Type = Overscan.Type;
+
+ ASSERT(Crtc->ScaleStore);
+ data.Address = &(((struct rhdAtomScaleStore *)Crtc->ScaleStore)->RegList);
+ RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+
+ AtomOverscan.ovscnLeft = Overscan.OverscanLeft;
+ AtomOverscan.ovscnRight = Overscan.OverscanRight;
+ AtomOverscan.ovscnTop = Overscan.OverscanTop;
+ AtomOverscan.ovscnBottom = Overscan.OverscanBottom;
+
+ switch (Crtc->Id) {
+ case RHD_CRTC_1:
+ Scaler = atomScaler1;
+ AtomCrtc = atomCrtc1;
+ break;
+ case RHD_CRTC_2:
+ Scaler = atomScaler2;
+ AtomCrtc = atomCrtc2;
+ break;
+ }
+
+ rhdAtomSetCRTCOverscan(rhdPtr->atomBIOS, AtomCrtc, &AtomOverscan);
+
+ switch (Type) {
+ case RHD_CRTC_SCALE_TYPE_NONE:
+ ScaleMode = atomScaleDisable;
+ break;
+ case RHD_CRTC_SCALE_TYPE_CENTER:
+ ScaleMode = atomScaleCenter;
+ break;
+ case RHD_CRTC_SCALE_TYPE_SCALE:
+ case RHD_CRTC_SCALE_TYPE_SCALE_KEEP_ASPECT_RATIO: /* scaled to fullscreen */
+ ScaleMode = atomScaleExpand;
+ break;
+ }
+ rhdAtomSetScaler(rhdPtr->atomBIOS, Scaler, ScaleMode);
+
+ data.Address = NULL;
+ RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+}
+
+/*
+ *
+ */
+static void
+rhdAtomScaleSave(struct rhdCrtc *Crtc)
+{
+ struct rhdAtomScaleStore* ScaleStore;
+ CARD32 RegOff = 0;
+
+ if (!Crtc->ScaleStore)
+ xfree(Crtc->ScaleStore);
+
+ if(!(ScaleStore = (struct rhdAtomScaleStore*)xnfcalloc(1, sizeof(struct rhdAtomScaleStore))))
+ return;
+ Crtc->ScaleStore = ScaleStore;
+
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ ScaleStore->StoreViewportSize = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_SIZE);
+ ScaleStore->StoreViewportStart = RHDRegRead(Crtc, RegOff + D1MODE_VIEWPORT_START);
+ ScaleStore->RegList = NULL;
+}
+
+/*
+ *
+ */
+static void
+rhdAtomCrtcScaleRestore(struct rhdCrtc *Crtc)
+{
+ struct rhdAtomScaleStore* ScaleStore;
+ CARD32 RegOff = 0;
+
+ rhdAtomCrtcRestore(Crtc, &(((struct rhdAtomScaleStore*)Crtc->ScaleStore)->RegList));
+
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ ScaleStore = (struct rhdAtomScaleStore*)Crtc->ScaleStore;
+ RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_SIZE, ScaleStore->StoreViewportSize);
+ RHDRegWrite(Crtc, RegOff + D1MODE_VIEWPORT_START, ScaleStore->StoreViewportStart);
+
+ xfree(Crtc->ScaleStore);
+ Crtc->ScaleStore = NULL;
+}
+
+/*
+ *
+ */
+struct rhdAtomModeStore {
+ void *RegList;
+ CARD32 StoreModeDataFormat;
+};
+
+static void
+rhdAtomModeSet(struct rhdCrtc *Crtc, DisplayModePtr Mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[Crtc->scrnIndex];
+ RHDPtr rhdPtr = RHDPTR(pScrn);
+ union AtomBiosArg data;
+ CARD32 RegOff = 0;
+
+ RHDFUNC(rhdPtr);
+
+ ASSERT(Crtc->ModeStore);
+ data.Address = &(((struct rhdAtomModeStore *)Crtc->ModeStore)->RegList);
+ RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+
+ if (!rhdAtomSetCRTCTimings(rhdPtr->atomBIOS,
+ Crtc->Id == RHD_CRTC_1 ? atomCrtc1 : atomCrtc2,
+ Mode, pScrn->depth))
+ xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: failed to set mode.\n",__func__);
+
+ /* set interlaced - AtomBIOS never sets the data format - never tested? */
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ if (Mode->Flags & V_INTERLACE)
+ RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x1);
+ else
+ RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, 0x0);
+
+
+ data.Address = NULL;
+ RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+}
+
+/*
+ *
+ */
+static void
+rhdAtomModeSave(struct rhdCrtc *Crtc)
+{
+ struct rhdAtomModeStore* ModeStore;
+ CARD32 RegOff = 0;
+
+ if (Crtc->ModeStore)
+ xfree(Crtc->ModeStore);
+
+ if(!(ModeStore = (struct rhdAtomModeStore*)xnfcalloc(1, sizeof(struct rhdAtomModeStore))))
+ return;
+ Crtc->ModeStore = ModeStore;
+
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ ModeStore->StoreModeDataFormat = RHDRegRead(Crtc, RegOff + D1MODE_DATA_FORMAT);
+}
+
+/*
+ *
+ */
+static void
+rhdAtomCrtcModeRestore(struct rhdCrtc *Crtc)
+{
+ struct rhdAtomModeStore* ModeStore;
+ CARD32 RegOff = 0;
+
+ if (Crtc->Id == RHD_CRTC_1)
+ RegOff = D1_REG_OFFSET;
+ else
+ RegOff = D2_REG_OFFSET;
+
+ ModeStore = (struct rhdAtomModeStore *)Crtc->ModeStore;
+
+ rhdAtomCrtcRestore(Crtc, &ModeStore->RegList);
+
+ RHDRegWrite(Crtc, RegOff + D1MODE_DATA_FORMAT, ModeStore->StoreModeDataFormat);
+
+ xfree(Crtc->ModeStore);
+ Crtc->ModeStore = 0;
+}
+
+/*
+ *
+ */
+static void
+atomCrtcPower(struct rhdCrtc *Crtc, int Power)
+{
+ RHDPtr rhdPtr = RHDPTRI(Crtc);
+ enum atomCrtc AtomCrtc = atomCrtc1;
+ union AtomBiosArg data;
+
+ RHDFUNC(Crtc);
+
+ switch (Crtc->Id) {
+ case RHD_CRTC_1:
+ AtomCrtc = atomCrtc1;
+ break;
+ case RHD_CRTC_2:
+ AtomCrtc = atomCrtc2;
+ break;
+ }
+ data.Address = &(((struct rhdAtomModeStore *)Crtc->ModeStore)->RegList);
+ RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+
+ /*
+ * We call rhdAtomEnableCrtcMemReq blindly as this table seemed to have existed in all
+ * versions of AtomBIOS on the hardware we support
+ */
+ switch (Power) {
+ case RHD_POWER_ON:
+ rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
+ rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcEnable);
+ break;
+ case RHD_POWER_RESET:
+ case RHD_POWER_SHUTDOWN:
+ default:
+ rhdAtomEnableCrtc(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
+ rhdAtomEnableCrtcMemReq(rhdPtr->atomBIOS, AtomCrtc, atomCrtcDisable);
+ break;
+ }
+ data.Address = NULL;
+ RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+}
+
+/*
+ *
+ */
+static void
+atomCrtcBlank(struct rhdCrtc *Crtc, Bool Blank)
+{
+ RHDPtr rhdPtr = RHDPTRI(Crtc);
+ enum atomCrtc AtomCrtc = atomCrtc1;
+ struct atomCrtcBlank Config;
+ union AtomBiosArg data;
+
+ RHDFUNC(Crtc);
+
+ switch (Crtc->Id) {
+ case RHD_CRTC_1:
+ AtomCrtc = atomCrtc1;
+ break;
+ case RHD_CRTC_2:
+ AtomCrtc = atomCrtc2;
+ break;
+ }
+ if (Blank)
+ Config.Action = atomBlankOn;
+ else
+ Config.Action = atomBlankOff;
+
+ Config.r = Config.g = Config.b = 0;
+
+ data.Address = &(((struct rhdAtomModeStore *)Crtc->ModeStore)->RegList);
+ RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+
+ rhdAtomBlankCRTC(rhdPtr->atomBIOS, AtomCrtc , &Config);
+
+ data.Address = NULL;
+ RHDAtomBiosFunc(Crtc->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
+}
+
+/*
+ *
+ */
+void
+RHDAtomCrtcsInit(RHDPtr rhdPtr)
+{
+ struct rhdCrtc *Crtc;
+ int i;
+
+ RHDFUNC(rhdPtr);
+
+ if (rhdPtr->Crtc[0] == NULL || rhdPtr->Crtc[1] == NULL) {
+ xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: CRTCs not initialized\n",__func__);
+ return;
+ }
+
+ for (i = 0; i < 2; i++) {
+
+ Crtc = rhdPtr->Crtc[i];
+
+ if (i == 0) {
+ Crtc->Name = "ATOM CRTC 1";
+ Crtc->Id = RHD_CRTC_1;
+ } else {
+ Crtc->Name = "ATOM CRTC 2";
+ Crtc->Id = RHD_CRTC_2;
+ }
+
+ /* We don't have to deal with FMT as this is handled in the SelectCrtcSource table */
+ Crtc->FMTStore = NULL;
+ Crtc->FMTModeSet = NULL;
+ Crtc->FMTSave = NULL;
+ Crtc->FMTRestore = NULL;
+
+ /* EnableGraphSurfaces is only a BIOS internal table. So use the hardcoded path.
+ Crtc->FBValid = atomFBValid;
+ Crtc->FBSet = atomFBSet;
+ Crtc->FBSave = atomSave;
+ Crtc->FBRestore = atomRestore;
+ */
+
+ /* There is no separate function to set up the LUT thru AtomBIOS */
+
+ /* Crtc->ScaleValid: From rhd_crtc.c */
+ Crtc->ScaleSet = rhdAtomScaleSet;
+ Crtc->ScaleSave = rhdAtomScaleSave;
+ Crtc->ScaleRestore = rhdAtomCrtcScaleRestore;
+
+ /* No such AtomBIOS table */
+ /* Crtc->FrameSet = atomViewPortStart; */
+
+ /* Crtc->ModeValid: From rhd_crtc.c */
+ Crtc->ModeSet = rhdAtomModeSet;
+ Crtc->ModeSave = rhdAtomModeSave;
+ Crtc->ModeRestore = rhdAtomCrtcModeRestore;
+
+ Crtc->Power = atomCrtcPower;
+ Crtc->Blank = atomCrtcBlank;
+ }
+}
+
+#endif /* ATOM_BIOS */