void RHDLUTsInit(RHDPtr rhdPtr) { struct rhdLUT *LUT; RHDFUNC(rhdPtr); LUT = xnfcalloc(sizeof(struct rhdLUT), 1); LUT->scrnIndex = rhdPtr->scrnIndex; LUT->Name = "LUT A"; LUT->Id = RHD_LUT_A; LUT->Save = LUTxSave; LUT->Restore = LUTxRestore; LUT->Set = LUTxSet; rhdPtr->LUT[0] = LUT; LUT = xnfcalloc(sizeof(struct rhdLUT), 1); LUT->scrnIndex = rhdPtr->scrnIndex; LUT->Name = "LUT B"; LUT->Id = RHD_LUT_B; LUT->Save = LUTxSave; LUT->Restore = LUTxRestore; LUT->Set = LUTxSet; rhdPtr->LUT[1] = LUT; }
static void LUTxSave(struct rhdLUT *LUT) { CARD16 RegOff; int i; RHDFUNC(LUT); if (LUT->Id == RHD_LUT_A) RegOff = RHD_REGOFFSET_LUTA; else RegOff = RHD_REGOFFSET_LUTB; LUT->StoreControl = RHDRegRead(LUT, RegOff + DC_LUTA_CONTROL); LUT->StoreBlackBlue = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_BLUE); LUT->StoreBlackGreen = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_GREEN); LUT->StoreBlackRed = RHDRegRead(LUT, RegOff + DC_LUTA_BLACK_OFFSET_RED); LUT->StoreWhiteBlue = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_BLUE); LUT->StoreWhiteGreen = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_GREEN); LUT->StoreWhiteRed = RHDRegRead(LUT, RegOff + DC_LUTA_WHITE_OFFSET_RED); RHDRegWrite(LUT, DC_LUT_RW_MODE, 0); /* Table */ if (LUT->Id == RHD_LUT_A) RHDRegWrite(LUT, DC_LUT_READ_PIPE_SELECT, 0); else RHDRegWrite(LUT, DC_LUT_READ_PIPE_SELECT, 1); RHDRegWrite(LUT, DC_LUT_RW_INDEX, 0); for (i = 0; i < 0x300; i++) LUT->StoreEntry[i] = RHDRegRead(LUT, DC_LUT_SEQ_COLOR); LUT->Stored = TRUE; }
void RHDVGARestore(RHDPtr rhdPtr) { struct rhdVGA *VGA = rhdPtr->VGA; RHDFUNC(rhdPtr); if (!VGA) return; /* We don't need to warn , this is intended use */ if (!VGA->Stored) { xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: trying to restore uninitialized values.\n", __func__); return; } if (VGA->FB) memcpy(((CARD8 *) rhdPtr->FbBase) + VGA->FBOffset, VGA->FB, VGA->FBSize); RHDRegWrite(rhdPtr, VGA_RENDER_CONTROL, VGA->Render_Control); RHDRegWrite(rhdPtr, VGA_MODE_CONTROL, VGA->Mode_Control); RHDRegWrite(rhdPtr, VGA_HDP_CONTROL, VGA->HDP_Control); RHDRegWrite(rhdPtr, D1VGA_CONTROL, VGA->D1_Control); RHDRegWrite(rhdPtr, D2VGA_CONTROL, VGA->D2_Control); RHD_UNSETDEBUGFLAG(rhdPtr, VGA_SETUP); }
static ModeStatus rhdAtomOutputModeValid(struct rhdOutput *Output, DisplayModePtr Mode) { RHDFUNC(Output); if (Mode->Flags & V_INTERLACE) return MODE_NO_INTERLACE; if (Mode->Clock < 25000) return MODE_CLOCK_LOW; if (Output->Connector->Type == RHD_CONNECTOR_DVI_SINGLE #if 0 || Output->Connector->Type == RHD_CONNECTOR_DP_DUAL || Output->Connector->Type == RHD_CONNECTOR_HDMI_B #endif ) { if (Mode->Clock > 165000) return MODE_CLOCK_HIGH; } else if (Output->Connector->Type == RHD_CONNECTOR_DVI) { if (Mode->Clock > 330000) /* could go higher still */ return MODE_CLOCK_HIGH; } return MODE_OK; }
static void atomSetBacklightFromBIOSScratch(struct rhdOutput *Output) { RHDPtr rhdPtr = RHDPTRI(Output); struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; RHDFUNC(Output); switch (Output->Id) { case RHD_OUTPUT_KLDSKP_LVTMA: case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYD: case RHD_OUTPUT_UNIPHYE: case RHD_OUTPUT_UNIPHYF: rhdSetEncoderTransmitterConfig(Output, Private->PixelClock); if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId, atomTransLcdBlBrightness, &Private->TransmitterConfig)) ERROR_MSG("rhdAtomDigTransmitterControl(atomTransEnable)"); break; default: if (!rhdAtomOutputControl(rhdPtr->atomBIOS, Private->OutputControlId, atomOutputLcdBrightnessControl)) ERROR_MSG("rhdAtomOutputControl(atomOutputLcdBrightnessControl)"); break; } }
void RHDLUTsDestroy(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); xfree(rhdPtr->LUT[0]); xfree(rhdPtr->LUT[1]); xfree(rhdPtr->LUTStore); }
static inline void rhdAtomOutputSet(struct rhdOutput *Output, DisplayModePtr Mode) { RHDPtr rhdPtr = RHDPTRI(Output); struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; struct atomEncoderConfig *EncoderConfig = &Private->EncoderConfig; struct atomCrtcSourceConfig CrtcSourceConfig; union AtomBiosArg data; RHDFUNC(Output); Private->Mode = Mode; data.Address = &Private->Save; RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data); Private->PixelClock = Mode->SynthClock; rhdSetEncoderTransmitterConfig(Output, Private->PixelClock); switch ( Private->CrtcSourceVersion.cref){ case 1: CrtcSourceConfig.u.Device = Output->OutputDriverPrivate->Device; break; case 2: CrtcSourceConfig.u.crtc2.Encoder = Private->EncoderId; CrtcSourceConfig.u.crtc2.Mode = EncoderConfig->u.dig.EncoderMode; break; default: xf86DrvMsg(Output->scrnIndex, X_ERROR, "Unknown version of SelectCrtcSource code table: %i\n",Private->CrtcSourceVersion.cref); return; } switch (Output->Id) { case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYD: case RHD_OUTPUT_UNIPHYE: case RHD_OUTPUT_UNIPHYF: #if 1 rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId, atomTransInit, &Private->TransmitterConfig); #endif case RHD_OUTPUT_KLDSKP_LVTMA: rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId, atomTransSetup, &Private->TransmitterConfig); break; default: break; } rhdAtomSelectCrtcSource(rhdPtr->atomBIOS, Output->Crtc->Id ? atomCrtc2 : atomCrtc1, &CrtcSourceConfig); data.Address = NULL; RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data); RHDHdmiSetMode(Private->Hdmi, Mode); }
void RHDVGADisable(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); _RHDRegMask(rhdPtr, VGA_RENDER_CONTROL, 0, 0x00030000); _RHDRegMask(rhdPtr, VGA_MODE_CONTROL, 0, 0x00000030); _RHDRegMask(rhdPtr, VGA_HDP_CONTROL, 0x00010010, 0x00010010); RHDRegMask(rhdPtr, D1VGA_CONTROL, 0, D1VGA_MODE_ENABLE); RHDRegMask(rhdPtr, D2VGA_CONTROL, 0, D2VGA_MODE_ENABLE); }
static void atomSetBacklight(struct rhdOutput *Output, int value) { RHDPtr rhdPtr = RHDPTRI(Output); RHDFUNC(Output); RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlSet, &value); atomSetBacklightFromBIOSScratch(Output); }
void RHDOutputsRestore(RHDPtr rhdPtr) { struct rhdOutput *Output = rhdPtr->Outputs; RHDFUNC(rhdPtr); while (Output) { if (Output->Restore) Output->Restore(Output); Output = Output->Next; } }
static void rhdAtomOutputDestroy(struct rhdOutput *Output) { struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; RHDFUNC(Output); if (Private->Save) xfree(Private->Save); RHDHdmiDestroy(Private->Hdmi); if (Private) xfree(Private); Output->Private = NULL; xfree(Output->Name); }
static void rhdAtomCrtcRestore(struct rhdCrtc *Crtc, void *Store) { #ifdef SaveRestore 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); #endif }
void RHDVGADestroy(RHDPtr rhdPtr) { struct rhdVGA *VGA = rhdPtr->VGA; RHDFUNC(rhdPtr); if (!VGA) return; /* We don't need to warn , this is intended use */ if (VGA->FB) xfree(VGA->FB); xfree(VGA); }
static void rhdAtomScaleSave(struct rhdCrtc *Crtc) { struct rhdCrtcScalePrivate* ScalePriv; CARD32 RegOff = 0; RHDFUNC(Crtc); if (!Crtc->ScalePriv) { ScalePriv = IONew(struct rhdCrtcScalePrivate, 1); if(!ScalePriv) return; else bzero(ScalePriv, sizeof(struct rhdCrtcScalePrivate)); Crtc->ScalePriv = ScalePriv; } else
void RHDOutputsPower(RHDPtr rhdPtr, int Power) { struct rhdOutput *Output = rhdPtr->Outputs; RHDFUNC(rhdPtr); while (Output) { if (Output->Active && Output->Power) Output->Power(Output, Power); Output = Output->Next; } }
void RHDOutputsMode(RHDPtr rhdPtr, struct rhdCrtc *Crtc, DisplayModePtr Mode) { struct rhdOutput *Output = rhdPtr->Outputs; RHDFUNC(rhdPtr); while (Output) { if (Output->Active && Output->Mode && (Output->Crtc == Crtc)) Output->Mode(Output, Mode); Output = Output->Next; } }
void RHDOutputsShutdownInactive(RHDPtr rhdPtr) { struct rhdOutput *Output = rhdPtr->Outputs; RHDFUNC(rhdPtr); while (Output) { if (!Output->Active && Output->Power) { xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "Shutting down %s\n", Output->Name); Output->Power(Output, RHD_POWER_SHUTDOWN); } Output = Output->Next; } }
void RHDOutputAdd(RHDPtr rhdPtr, struct rhdOutput *New) { struct rhdOutput *Last = rhdPtr->Outputs; RHDFUNC(rhdPtr); if (!New) return; if (Last) { while (Last->Next) Last = Last->Next; Last->Next = New; } else rhdPtr->Outputs = New; }
void RHDVGASave(RHDPtr rhdPtr) { struct rhdVGA *VGA = rhdPtr->VGA; RHDFUNC(rhdPtr); if (!VGA) return; /* We don't need to warn , this is intended use */ VGA->Render_Control = RHDRegRead(rhdPtr, VGA_RENDER_CONTROL); VGA->Mode_Control = RHDRegRead(rhdPtr, VGA_MODE_CONTROL); VGA->HDP_Control = RHDRegRead(rhdPtr, VGA_HDP_CONTROL); VGA->D1_Control = RHDRegRead(rhdPtr, D1VGA_CONTROL); VGA->D2_Control = RHDRegRead(rhdPtr, D2VGA_CONTROL); rhdVGASaveFB(rhdPtr); VGA->Stored = TRUE; }
static Bool atomLVDSPropertyControl(struct rhdOutput *Output, enum rhdPropertyAction Action, enum rhdOutputProperty Property, union rhdPropertyData *val) { struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; RHDFUNC(Output); switch (Action) { case rhdPropertyCheck: if (Private->BlLevel < 0) return FALSE; switch (Property) { case RHD_OUTPUT_BACKLIGHT: return TRUE; default: return FALSE; } case rhdPropertyGet: if (Private->BlLevel < 0) return FALSE; switch (Property) { case RHD_OUTPUT_BACKLIGHT: val->integer = Private->BlLevel; return TRUE; default: return FALSE; } break; case rhdPropertySet: if (Private->BlLevel < 0) return FALSE; switch (Property) { case RHD_OUTPUT_BACKLIGHT: atomSetBacklight(Output, val->integer); return TRUE; default: return FALSE; } break; } return TRUE; }
void RHDPmInit(RHDPtr rhdPtr) { struct rhdPm *Pm = IONew(struct rhdPm, 1); if (!Pm) return; bzero(Pm, sizeof(struct rhdPm)); union AtomBiosArg data; RHDFUNC(rhdPtr); rhdPtr->Pm = Pm; Pm->scrnIndex = rhdPtr->scrnIndex; Pm->SelectState = rhdPmSelectState; Pm->DefineState = rhdPmDefineState; if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_GET_CHIP_LIMITS, &data) != ATOM_SUCCESS) { /* Not getting the information is fatal */ IODelete(Pm, struct rhdPm, 1); rhdPtr->Pm = NULL; return; }
void RHDVGAInit(RHDPtr rhdPtr) { struct rhdVGA *VGA; RHDFUNC(rhdPtr); /* Check whether one of our VGA bits is set */ if (!(_RHDRegRead(rhdPtr, VGA_RENDER_CONTROL) & 0x00030000) && (_RHDRegRead(rhdPtr, VGA_HDP_CONTROL) & 0x00000010) && !(_RHDRegRead(rhdPtr, D1VGA_CONTROL) & 0x00000001) && !(_RHDRegRead(rhdPtr, D2VGA_CONTROL) & 0x00000001)) return; xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "Detected VGA mode.\n"); VGA = xnfcalloc(sizeof(struct rhdVGA), 1); VGA->Stored = FALSE; rhdPtr->VGA = VGA; }
/* * This is (usually) ok, as VGASave is called after the memory has been mapped, * but before the MC is set up. So the use of RHDMCGetFBLocation is correct in * rhdVGAFBOffsetGet. */ static void rhdVGASaveFB(RHDPtr rhdPtr) { struct rhdVGA *VGA = rhdPtr->VGA; ASSERT(rhdPtr->FbBase); RHDFUNC(rhdPtr); VGA->FBOffset = rhdVGAFBOffsetGet(rhdPtr); if (VGA->FBOffset == 0xFFFFFFFF) { xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "%s: Unable to access the VGA " "framebuffer (0x%08X)\n", __func__, (unsigned int) RHDRegRead(rhdPtr, VGA_MEMORY_BASE_ADDRESS)); if (VGA->FB) xfree(VGA->FB); VGA->FB = NULL; VGA->FBSize = 0; return; } VGA->FBSize = 256 * 1024; RHDDebug(rhdPtr->scrnIndex, "%s: VGA FB Offset 0x%08X [0x%08X]\n", __func__, VGA->FBOffset, VGA->FBSize); if (!VGA->FB) VGA->FB = xcalloc(VGA->FBSize, 1); if (VGA->FB) memcpy(VGA->FB, ((CARD8 *) rhdPtr->FbBase) + VGA->FBOffset, VGA->FBSize); else { xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "%s: Failed to allocate" " space for storing the VGA framebuffer.\n", __func__); VGA->FBOffset = 0xFFFFFFFF; VGA->FBSize = 0; } }
static void LUTxRestore(struct rhdLUT *LUT) { CARD16 RegOff; int i; RHDFUNC(LUT); if (!LUT->Stored) { xf86DrvMsg(LUT->scrnIndex, X_ERROR, "%s: %s: nothing stored!\n", __func__, LUT->Name); return; } if (LUT->Id == RHD_LUT_A) RegOff = RHD_REGOFFSET_LUTA; else RegOff = RHD_REGOFFSET_LUTB; RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_BLUE, LUT->StoreBlackBlue); RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_GREEN, LUT->StoreBlackGreen); RHDRegWrite(LUT, RegOff + DC_LUTA_BLACK_OFFSET_RED, LUT->StoreBlackRed); RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_BLUE, LUT->StoreWhiteBlue); RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_GREEN, LUT->StoreWhiteGreen); RHDRegWrite(LUT, RegOff + DC_LUTA_WHITE_OFFSET_RED, LUT->StoreWhiteRed); if (LUT->Id == RHD_LUT_A) RHDRegWrite(LUT, DC_LUT_RW_SELECT, 0); else RHDRegWrite(LUT, DC_LUT_RW_SELECT, 1); RHDRegWrite(LUT, DC_LUT_RW_MODE, 0); /* Table */ RHDRegWrite(LUT, DC_LUT_WRITE_EN_MASK, 0x0000003F); RHDRegWrite(LUT, DC_LUT_RW_INDEX, 0); for (i = 0; i < 0x300; i++) RHDRegWrite(LUT, DC_LUT_SEQ_COLOR, LUT->StoreEntry[i]); RHDRegWrite(LUT, RegOff + DC_LUTA_CONTROL, LUT->StoreControl); }
void RHDOutputsDestroy(RHDPtr rhdPtr) { struct rhdOutput *Output = rhdPtr->Outputs, *Next; RHDFUNC(rhdPtr); while (Output) { Next = Output->Next; xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "Destroying %s\n", Output->Name); if (Output->Destroy) Output->Destroy(Output); if (Output->OutputDriverPrivate) xfree(Output->OutputDriverPrivate); xfree(Output); Output = Next; } }
void RHDLUTsSave(RHDPtr rhdPtr) { struct rhdLUTStore *Store = rhdPtr->LUTStore; RHDFUNC(rhdPtr); if (!Store) { Store = xnfcalloc(sizeof(struct rhdLUTStore), 1); rhdPtr->LUTStore = Store; } Store->Select = _RHDRegRead(rhdPtr, DC_LUT_RW_SELECT); Store->Mode = _RHDRegRead(rhdPtr, DC_LUT_RW_MODE); Store->Index = _RHDRegRead(rhdPtr, DC_LUT_RW_INDEX); Store->Color = _RHDRegRead(rhdPtr, DC_LUT_30_COLOR); Store->ReadPipe = _RHDRegRead(rhdPtr, DC_LUT_READ_PIPE_SELECT); Store->WriteMask = _RHDRegRead(rhdPtr, DC_LUT_WRITE_EN_MASK); rhdPtr->LUT[0]->Save(rhdPtr->LUT[0]); rhdPtr->LUT[1]->Save(rhdPtr->LUT[1]); }
void RHDLUTsRestore(RHDPtr rhdPtr) { struct rhdLUTStore *Store = rhdPtr->LUTStore; RHDFUNC(rhdPtr); rhdPtr->LUT[0]->Restore(rhdPtr->LUT[0]); rhdPtr->LUT[1]->Restore(rhdPtr->LUT[1]); if (!Store) { xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: nothing stored!\n", __func__); return; } _RHDRegWrite(rhdPtr, DC_LUT_RW_SELECT, Store->Select); _RHDRegWrite(rhdPtr, DC_LUT_RW_MODE, Store->Mode); _RHDRegWrite(rhdPtr, DC_LUT_RW_INDEX, Store->Index); _RHDRegWrite(rhdPtr, DC_LUT_30_COLOR, Store->Color); _RHDRegWrite(rhdPtr, DC_LUT_READ_PIPE_SELECT, Store->ReadPipe); _RHDRegWrite(rhdPtr, DC_LUT_WRITE_EN_MASK, Store->WriteMask); }
static Bool atomTMDSPropertyControl(struct rhdOutput *Output, enum rhdPropertyAction Action, enum rhdOutputProperty Property, union rhdPropertyData *val) { struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; RHDFUNC(Output); switch (Action) { case rhdPropertyCheck: switch (Property) { case RHD_OUTPUT_COHERENT: return TRUE; default: return FALSE; } case rhdPropertyGet: switch (Property) { case RHD_OUTPUT_COHERENT: val->Bool = Private->Coherent; return TRUE; default: return FALSE; } break; case rhdPropertySet: switch (Property) { case RHD_OUTPUT_COHERENT: Private->Coherent = val->Bool; Output->Mode(Output, Private->Mode); Output->Power(Output, RHD_POWER_ON); break; default: return FALSE; } break; } return TRUE; }
static inline void rhdSetEncoderTransmitterConfig(struct rhdOutput *Output, int PixelClock) { RHDPtr rhdPtr = RHDPTRI(Output); struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private; struct atomEncoderConfig *EncoderConfig = &Private->EncoderConfig; struct atomTransmitterConfig *TransmitterConfig = &Private->TransmitterConfig; RHDFUNC(Output); EncoderConfig->PixelClock = TransmitterConfig->PixelClock = PixelClock; switch (Output->Id) { case RHD_OUTPUT_NONE: break; case RHD_OUTPUT_DVO: EncoderConfig->u.dvo.DvoDeviceType = Output->OutputDriverPrivate->Device; switch (EncoderConfig->u.dvo.DvoDeviceType) { case atomCRT1: case atomCRT2: EncoderConfig->u.dvo.digital = FALSE; break; case atomTV1: case atomTV2: case atomCV: EncoderConfig->u.dvo.digital = FALSE; EncoderConfig->u.dvo.u.TVMode = rhdPtr->tvMode; break; case atomLCD1: case atomDFP1: case atomDFP2: case atomLCD2: case atomDFP3: case atomDFP4: case atomDFP5: EncoderConfig->u.dvo.digital = TRUE; /* @@@ no digital attributes, yet */ break; case atomNone: break; } break; case RHD_OUTPUT_DACA: case RHD_OUTPUT_DACB: switch (Output->SensedType) { case RHD_SENSED_VGA: EncoderConfig->u.dac.DacStandard = atomDAC_VGA; break; case RHD_SENSED_TV_COMPONENT: EncoderConfig->u.dac.DacStandard = atomDAC_CV; break; case RHD_SENSED_TV_SVIDEO: case RHD_SENSED_TV_COMPOSITE: switch (rhdPtr->tvMode) { case RHD_TV_NTSC: case RHD_TV_NTSCJ: EncoderConfig->u.dac.DacStandard = atomDAC_NTSC; /* NTSC */ break; case RHD_TV_PAL: case RHD_TV_PALN: case RHD_TV_PALCN: case RHD_TV_PAL60: default: EncoderConfig->u.dac.DacStandard = atomDAC_PAL; /* PAL */ break; } break; case RHD_SENSED_NONE: EncoderConfig->u.dac.DacStandard = atomDAC_VGA; break; default: xf86DrvMsg(Output->scrnIndex, X_ERROR, "Sensed incompatible output for DAC\n"); EncoderConfig->u.dac.DacStandard = atomDAC_VGA; break; } break; case RHD_OUTPUT_TMDSA: case RHD_OUTPUT_LVTMA: if (Output->Connector && PixelClock > 0) { if (Output->Connector->Type == RHD_CONNECTOR_DVI #if 0 || Output->Connector->Type == RHD_CONNECTOR_HDMI_B #endif ) Private->RunDualLink = (PixelClock > 165000) ? TRUE : FALSE; else Private->RunDualLink = FALSE; } else /* only get here for power down: thus power down both channels to be save */ Private->RunDualLink = TRUE; switch (Private->EncoderVersion.cref) { case 1: if (Private->RunDualLink) EncoderConfig->u.lvds.LinkCnt = atomDualLink; else EncoderConfig->u.lvds.LinkCnt = atomSingleLink; break; case 2: case 3: if (Private->RunDualLink) EncoderConfig->u.lvds2.LinkCnt = atomDualLink; else EncoderConfig->u.lvds2.LinkCnt = atomSingleLink; if (Private->Coherent) EncoderConfig->u.lvds2.Coherent = TRUE; else EncoderConfig->u.lvds2.Coherent = FALSE; break; } break; case RHD_OUTPUT_KLDSKP_LVTMA: case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYD: case RHD_OUTPUT_UNIPHYE: case RHD_OUTPUT_UNIPHYF: if (Output->Connector && PixelClock > 0) { if (Output->Connector->Type == RHD_CONNECTOR_DVI #if 0 || Output->Connector->Type == RHD_CONNECTOR_DP_DUAL || Output->Connector->Type == RHD_CONNECTOR_HDMI_B #endif ) Private->RunDualLink = (PixelClock > 165000) ? TRUE : FALSE; else Private->RunDualLink = FALSE; } else /* only get here for power down: thus power down both channels to be save */ Private->RunDualLink = TRUE; if (Private->RunDualLink) { TransmitterConfig->LinkCnt = EncoderConfig->u.dig.LinkCnt = atomDualLink; if (TransmitterConfig->Link == atomTransLinkA) TransmitterConfig->Link = atomTransLinkAB; else if (TransmitterConfig->Link == atomTransLinkB) TransmitterConfig->Link = atomTransLinkBA; } else { TransmitterConfig->LinkCnt = EncoderConfig->u.dig.LinkCnt = atomSingleLink; if (TransmitterConfig->Link == atomTransLinkAB) TransmitterConfig->Link = atomTransLinkA; else if (TransmitterConfig->Link == atomTransLinkBA) TransmitterConfig->Link = atomTransLinkB; } TransmitterConfig->Coherent = Private->Coherent; break; } }
struct rhdOutput * RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, rhdOutputType OutputType) { struct rhdOutput *Output; struct rhdAtomOutputPrivate *Private; struct atomEncoderConfig *EncoderConfig; struct atomTransmitterConfig *TransmitterConfig; char *OutputName = NULL; RHDFUNC(rhdPtr); switch (OutputType) { case RHD_OUTPUT_NONE: return NULL; case RHD_OUTPUT_DACA: OutputName = "DACA"; break; case RHD_OUTPUT_DACB: OutputName = "DACB"; break; case RHD_OUTPUT_TMDSA: OutputName = "TMDSA"; break; case RHD_OUTPUT_LVTMA: OutputName = "LVTMA"; break; case RHD_OUTPUT_DVO: OutputName = "DVO"; break; case RHD_OUTPUT_KLDSKP_LVTMA: OutputName = "KldskpLvtma"; break; case RHD_OUTPUT_UNIPHYA: OutputName = "UniphyA"; break; case RHD_OUTPUT_UNIPHYB: OutputName = "UniphyB"; break; case RHD_OUTPUT_UNIPHYC: OutputName = "UniphyC"; break; case RHD_OUTPUT_UNIPHYD: OutputName = "UniphyD"; break; case RHD_OUTPUT_UNIPHYE: OutputName = "UniphyE"; break; case RHD_OUTPUT_UNIPHYF: OutputName = "UniphyF"; break; } Output = xnfcalloc(sizeof(struct rhdOutput), 1); Output->scrnIndex = rhdPtr->scrnIndex; Output->Name = RhdAppendString(NULL, "AtomOutput"); Output->Name = RhdAppendString(Output->Name, OutputName); Output->Id = OutputType; Output->Sense = NULL; Private = xnfcalloc(sizeof(struct rhdAtomOutputPrivate), 1); Output->Private = Private; Output->OutputDriverPrivate = NULL; EncoderConfig = &Private->EncoderConfig; Private->PixelClock = 0; switch (OutputType) { case RHD_OUTPUT_NONE: xfree(Output); xfree(Private); return NULL; case RHD_OUTPUT_DACA: Output->Sense = RHDBIOSScratchDACSense; Private->EncoderId = atomEncoderDACA; Private->OutputControlId = atomDAC1Output; Private->Hdmi = NULL; break; case RHD_OUTPUT_DACB: Output->Sense = RHDBIOSScratchDACSense; Private->EncoderId = atomEncoderDACB; Private->OutputControlId = atomDAC2Output; Private->Hdmi = NULL; break; case RHD_OUTPUT_TMDSA: case RHD_OUTPUT_LVTMA: if (OutputType == RHD_OUTPUT_LVTMA) { if (ConnectorType == RHD_CONNECTOR_PANEL) { Private->OutputControlId = atomLCDOutput; LVDSInfoRetrieve(rhdPtr, Private); Private->RunDualLink = Private->DualLink; Private->EncoderId = atomEncoderLVDS; } else { TMDSInfoRetrieve(rhdPtr, Private); Private->OutputControlId = atomLVTMAOutput; Private->EncoderId = atomEncoderTMDS2; } } else { TMDSInfoRetrieve(rhdPtr, Private); Private->OutputControlId = atomTMDSAOutput; Private->EncoderId = atomEncoderTMDS1; } if (OutputType == RHD_CONNECTOR_DVI) Private->DualLink = TRUE; else Private->DualLink = FALSE; if (ConnectorType != RHD_CONNECTOR_PANEL) Private->Hdmi = RHDHdmiInit(rhdPtr, Output); else Private->Hdmi = NULL; Private->EncoderVersion = rhdAtomEncoderControlVersion(rhdPtr->atomBIOS, Private->EncoderId); switch (Private->EncoderVersion.cref) { case 1: EncoderConfig->u.lvds.Is24bit = Private->LVDS24Bit; break; case 2: case 3: EncoderConfig->u.lvds2.Is24bit = Private->LVDS24Bit; EncoderConfig->u.lvds2.SpatialDither = Private->SpatialDither; EncoderConfig->u.lvds2.LinkB = 0; /* @@@ */ EncoderConfig->u.lvds2.Hdmi = FALSE; #if 0 if (ConnectorType == RHD_CONNECTOR_HDMI_B || ConnectorType == RHD_CONNECTOR_HDMI_A) EncoderConfig->u.lvds2.hdmi = TRUE; #endif switch (Private->GreyLevel) { case 2: EncoderConfig->u.lvds2.TemporalGrey = atomTemporalDither2; break; case 4: EncoderConfig->u.lvds2.TemporalGrey = atomTemporalDither4; break; case 0: default: EncoderConfig->u.lvds2.TemporalGrey = atomTemporalDither0; } if (Private->SpatialDither) EncoderConfig->u.lvds2.SpatialDither = TRUE; else EncoderConfig->u.lvds2.SpatialDither = FALSE; EncoderConfig->u.lvds2.Coherent = Private->Coherent; break; } break; case RHD_OUTPUT_DVO: Private->EncoderId = atomEncoderDVO; Private->EncoderVersion = rhdAtomEncoderControlVersion(rhdPtr->atomBIOS, Private->EncoderId); switch (Private->EncoderVersion.cref) { case 1: case 2: /* Output->OutputDriverPrivate->Device not set yet. */ break; case 3: /* @@@ still to be handled */ xfree(Output); xfree(Private); return NULL; } { struct atomCodeTableVersion version = rhdAtomOutputControlVersion(rhdPtr->atomBIOS, atomDVOOutput); switch (version.cref) { case 1: case 2: Private->OutputControlId = atomDVOOutput; break; case 3: #if 0 Private->TransmitterId = atomTransmitterDVO; /* @@@ check how to handle this one */ break; #else xfree(Output); xfree(Private); return NULL; #endif } } break; case RHD_OUTPUT_KLDSKP_LVTMA: Private->EncoderVersion = rhdAtomEncoderControlVersion(rhdPtr->atomBIOS, Private->EncoderId); Output->AllocFree = RHDAtomOutputAllocFree; EncoderConfig->u.dig.Link = atomTransLinkA; EncoderConfig->u.dig.Transmitter = Private->TransmitterId = atomTransmitterLVTMA; TransmitterConfig = &Private->TransmitterConfig; TransmitterConfig->Link = atomTransLinkA; TransmitterConfig->Encoder = Private->TransmitterId; if (ConnectorType == RHD_CONNECTOR_PANEL) { TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomLVDS; LVDSInfoRetrieve(rhdPtr, Private); Private->Hdmi = NULL; } else { TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDVI; TMDSInfoRetrieve(rhdPtr, Private); Private->Coherent = FALSE; Private->Hdmi = RHDHdmiInit(rhdPtr, Output); } break; case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYD: case RHD_OUTPUT_UNIPHYE: case RHD_OUTPUT_UNIPHYF: Output->AllocFree = RHDAtomOutputAllocFree; if (RHDIsIGP(rhdPtr->ChipSet)) EncoderConfig->u.dig.Transmitter = Private->TransmitterId = atomTransmitterPCIEPHY; else { switch (OutputType) { case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: EncoderConfig->u.dig.Transmitter = Private->TransmitterId = atomTransmitterUNIPHY; break; case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYD: EncoderConfig->u.dig.Transmitter = Private->TransmitterId = atomTransmitterUNIPHY1; break; case RHD_OUTPUT_UNIPHYE: case RHD_OUTPUT_UNIPHYF: EncoderConfig->u.dig.Transmitter = Private->TransmitterId = atomTransmitterUNIPHY2; break; default: xfree(Private); xfree(Output); return NULL; } } TransmitterConfig = &Private->TransmitterConfig; TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone; switch (OutputType) { case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYC: case RHD_OUTPUT_UNIPHYE: TransmitterConfig->Link = EncoderConfig->u.dig.Link = atomTransLinkA; break; case RHD_OUTPUT_UNIPHYB: case RHD_OUTPUT_UNIPHYD: case RHD_OUTPUT_UNIPHYF: TransmitterConfig->Link = EncoderConfig->u.dig.Link = atomTransLinkB; break; default: xfree(Private); xfree(Output); return NULL; } if (RHDIsIGP(rhdPtr->ChipSet)) { AtomBiosArgRec data; data.val = 1; if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS, ATOM_GET_PCIE_LANES, &data) == ATOM_SUCCESS) TransmitterConfig->Lanes = data.pcieLanes.Chassis; /* only do 'chassis' for now */ else { xfree(Private); xfree(Output); return NULL; } } if (ConnectorType == RHD_CONNECTOR_PANEL) LVDSInfoRetrieve(rhdPtr, Private); else TMDSInfoRetrieve(rhdPtr, Private); switch (ConnectorType) { case RHD_CONNECTOR_DVI: case RHD_CONNECTOR_DVI_SINGLE: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDVI; Private->Hdmi = RHDHdmiInit(rhdPtr, Output); break; case RHD_CONNECTOR_PANEL: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomLVDS; break; #if 0 case RHD_CONNECTOR_DP: case RHD_CONNECTOR_DP_DUAL: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDP; break; case RHD_CONNECTOR_HDMI_A: case RHD_CONNECTOR_HDMI_B: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomHDMI; break; #endif default: xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: Unknown connector type\n",__func__); xfree(Output); xfree(Private); return NULL; } break; default: xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "Unknown output type\n"); xfree(Output); xfree(Private); return NULL; } if (ConnectorType == RHD_CONNECTOR_PANEL) { Output->Property = atomLVDSPropertyControl; LVDSInfoRetrieve(rhdPtr, Private); } else { Output->Property = atomTMDSPropertyControl; TMDSInfoRetrieve(rhdPtr, Private); } Output->Mode = rhdAtomOutputSet; Output->Power = rhdAtomOutputPower; Output->Save = rhdAtomOutputSave; Output->Restore = rhdAtomOutputRestore; Output->ModeValid = rhdAtomOutputModeValid; Output->Destroy = rhdAtomOutputDestroy; Private->CrtcSourceVersion = rhdAtomSelectCrtcSourceVersion(rhdPtr->atomBIOS); return Output; }