예제 #1
0
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);
}
예제 #2
0
static Bool
LVDSInfoRetrieve(RHDPtr rhdPtr, struct rhdAtomOutputPrivate *Private)
{
    AtomBiosArgRec data;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_SEQ_DIG_ONTO_DE, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->PowerDigToDE = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_SEQ_DE_TO_BL, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->PowerDEToBL = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_OFF_DELAY, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->OffDelay = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_DUALLINK, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->DualLink = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_24BIT, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->LVDS24Bit = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_FPDI, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->FPDI = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_TEMPORAL_DITHER, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->TemporalDither = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_SPATIAL_DITHER, &data) != ATOM_SUCCESS)
	return FALSE;
    Private->SpatialDither = data.val;

    if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			ATOM_LVDS_GREYLVL, &data) != ATOM_SUCCESS)
	return FALSE;
    {
	Private->GreyLevel = data.val;
	xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "AtomBIOS returned %i Grey Levels\n",
		   Private->GreyLevel);
    }
    Private->Coherent = FALSE;

    RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlGet, &Private->BlLevel);

    return TRUE;
}
예제 #3
0
static void
rhdPmGetRawState (RHDPtr rhdPtr, struct rhdPowerState *state)
{
    union AtomBiosArg data;

    if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			 ATOM_GET_ENGINE_CLOCK, &data) == ATOM_SUCCESS)
        state->EngineClock = data.clockValue;
    if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			 ATOM_GET_MEMORY_CLOCK, &data) == ATOM_SUCCESS)
        state->MemoryClock = data.clockValue;
    if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			 ATOM_GET_VOLTAGE, &data) == ATOM_SUCCESS)
        state->VDDCVoltage = data.val;
}
예제 #4
0
static Bool
rhdPmSetRawState (RHDPtr rhdPtr, struct rhdPowerState *state)
{
    union AtomBiosArg data;
    Bool ret = TRUE;
    struct rhdPowerState dummy;

    /* TODO: Idle first; find which idles are needed and expose them */
    /* FIXME: Voltage */
    /* FIXME: If Voltage is to be rised, then do that first, then change frequencies.
     *        If Voltage is to be lowered, do it the other way round. */
    if (state->EngineClock && state->EngineClock != rhdPtr->Pm->Current.EngineClock) {
	data.clockValue = state->EngineClock;
	if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			     ATOM_SET_ENGINE_CLOCK, &data) == ATOM_SUCCESS)
	    rhdPtr->Pm->Current.EngineClock = state->EngineClock;
	else
	    ret = FALSE;
    }
#if 0	/* don't do for the moment */
    if (state->MemoryClock && state->MemoryClock != rhdPtr->Pm->Current.MemoryClock) {
	data.clockValue = state->MemoryClock;
	if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			     ATOM_SET_MEMORY_CLOCK, &data) != ATOM_SUCCESS)
	    rhdPtr->Pm->Current.MemoryClock = state->MemoryClock;
	else
	    ret = FALSE;
    }
#endif
#if 0	/* don't do for the moment */
    if (state->VDDCVoltage && state->VDDCVoltage != rhdPtr->Pm->Current.VDDCVoltage) {
	data.val = state->VDDCVoltage;
	if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
			     ATOM_SET_VOLTAGE, &data) != ATOM_SUCCESS)
	    rhdPtr->Pm->Current.VDDCVoltage = state->VDDCVoltage;
	else
	    ret = FALSE;
    }
#endif

    /* AtomBIOS might change values, so that later comparisons would fail, even
     * if re-setting wouldn't change the actual values. So don't save real
     * state in Current, but update only to current values. */
    rhdPmGetRawState (rhdPtr, &dummy);
    return ret;
}
예제 #5
0
static void
rhdAtomOutputRestore(struct rhdOutput *Output)
{
     struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private;
     RHDPtr rhdPtr = RHDPTRI(Output);
     union AtomBiosArg data;

     data.Address = &Private->Save;
     RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_RESTORE_REGISTERS, &data);
     if (Output->Connector && Output->Connector->Type == RHD_CONNECTOR_PANEL)
	 atomSetBacklightFromBIOSScratch(Output);
     RHDHdmiRestore(Private->Hdmi);
}
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
}
예제 #7
0
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;
    }
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;

    LOG("FUNCTION: %s: %s viewport: %dx%d\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->ScalePriv);
    data.Address = &((Crtc->ScalePriv)->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);

    RHDMCTuneAccessForDisplay(rhdPtr, Crtc->Id, Mode,
			ScaledToMode ? ScaledToMode : Mode);
}
예제 #9
0
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;
}
예제 #10
0
static inline void
rhdAtomOutputPower(struct rhdOutput *Output, int Power)
{
    RHDPtr rhdPtr = RHDPTRI(Output);
    struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private;
    struct atomEncoderConfig *EncoderConfig = &Private->EncoderConfig;
    union AtomBiosArg data;
    Bool enableHDMI = FALSE;

    RHDFUNC(Output);

    if(Output->Connector != NULL) {
	enableHDMI = RHDConnectorEnableHDMI(Output->Connector);
	switch(Output->Id) {
	    case RHD_OUTPUT_TMDSA:
	    case RHD_OUTPUT_LVTMA:
		if(enableHDMI && !Private->EncoderConfig.u.lvds2.Hdmi)
		    Private->EncoderConfig.u.lvds2.Hdmi = TRUE;
		else if(!enableHDMI && Private->EncoderConfig.u.lvds2.Hdmi)
		    Private->EncoderConfig.u.lvds2.Hdmi = FALSE;
		break;

	    case RHD_OUTPUT_UNIPHYA:
	    case RHD_OUTPUT_UNIPHYB:
	    case RHD_OUTPUT_KLDSKP_LVTMA:
		if(enableHDMI && Private->TransmitterConfig.Mode == atomDVI) {
		    Private->TransmitterConfig.Mode = atomHDMI;
		    Private->EncoderConfig.u.dig.EncoderMode = atomHDMI;

		} else if(!enableHDMI && Private->TransmitterConfig.Mode == atomHDMI) {
		    Private->TransmitterConfig.Mode = atomDVI;
		    Private->EncoderConfig.u.dig.EncoderMode = atomDVI;
		}
		break;

	    default:
		break;
	}
    }

    data.Address = &Private->Save;
    RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);

    rhdSetEncoderTransmitterConfig(Output, Private->PixelClock);

    switch (Power) {
	case RHD_POWER_ON:
	    RHDDebug(Output->scrnIndex, "RHD_POWER_ON\n");
	    rhdAtomEncoderControl(rhdPtr->atomBIOS,  Private->EncoderId, atomEncoderOn, EncoderConfig);
	    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:
		    if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId,
						      atomTransEnable, &Private->TransmitterConfig)) {
			ERROR_MSG("rhdAtomDigTransmitterControl(atomTransEnable)");
			break;
		    }
		    if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId,
						      atomTransEnableOutput, &Private->TransmitterConfig))
			ERROR_MSG("rhdAtomDigTransmitterControl(atomTransEnableOutput)");
		    break;
		default:
		    if (!rhdAtomOutputControl(rhdPtr->atomBIOS, Private->OutputControlId, atomOutputEnable))
			ERROR_MSG("rhdAtomOutputControl(atomOutputEnable)");
		    break;
	    }
	    RHDHdmiEnable(Private->Hdmi, enableHDMI);
	    break;
	case RHD_POWER_RESET:
	    RHDDebug(Output->scrnIndex, "RHD_POWER_RESET\n");
	    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:
		    if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId,
						      atomTransDisableOutput, &Private->TransmitterConfig))
			ERROR_MSG("rhdAtomDigTransmitterControl(atomTransDisableOutput)");
		    break;
		default:
		    if (!rhdAtomOutputControl(rhdPtr->atomBIOS, Private->OutputControlId, atomOutputDisable))
			ERROR_MSG("rhdAtomOutputControl(atomOutputDisable)");
		    break;
	    }
	    break;
	case RHD_POWER_SHUTDOWN:
	    RHDDebug(Output->scrnIndex, "RHD_POWER_SHUTDOWN\n");
	    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:
		    if (Private->EncoderId == atomEncoderNone)
			break;
		    if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId,
						      atomTransDisableOutput, &Private->TransmitterConfig)) {
			ERROR_MSG("rhdAtomDigTransmitterControl(atomTransDisableOutput)");
			break;
		    }
		    if (!rhdAtomDigTransmitterControl(rhdPtr->atomBIOS, Private->TransmitterId,
						      atomTransDisable, &Private->TransmitterConfig))
			ERROR_MSG("rhdAtomDigTransmitterControl(atomTransDisable)");
		    break;
		default:
		    if (!rhdAtomOutputControl(rhdPtr->atomBIOS, Private->OutputControlId, atomOutputDisable))
			ERROR_MSG("rhdAtomOutputControl(atomOutputDisable)");
		    break;
	    }
	    if (Private->EncoderId != atomEncoderNone)
	    if (!rhdAtomEncoderControl(rhdPtr->atomBIOS, Private->EncoderId, atomEncoderOff, &Private->EncoderConfig))
		ERROR_MSG("rhdAtomEncoderControl(atomEncoderOff)");
	    RHDHdmiEnable(Private->Hdmi, FALSE);
	    break;
    }

    data.Address = NULL;
    RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_SET_REGISTER_LIST_LOCATION, &data);
}