Ejemplo n.º 1
0
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;
    }
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
static void
atomSetBacklight(struct rhdOutput *Output, int value)
{
    RHDPtr rhdPtr = RHDPTRI(Output);

    RHDFUNC(Output);

    RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlSet, &value);

    atomSetBacklightFromBIOSScratch(Output);
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
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;
    }
}
Ejemplo n.º 7
0
static Bool
RHDAtomOutputAllocFree(struct rhdOutput *Output, enum rhdOutputAllocation Alloc)
{
    struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private;
    struct atomTransmitterConfig *TransmitterConfig = &Private->TransmitterConfig;
    RHDPtr rhdPtr = RHDPTRI(Output);
    char *TransmitterName;

    RHDFUNC(rhdPtr);

    switch (Output->Id) {
	case RHD_OUTPUT_KLDSKP_LVTMA:
	    TransmitterName = "KLDSKP_LVTMA";
	    break;
	case RHD_OUTPUT_UNIPHYA:
	    TransmitterName = "KLDSKP_UNIPHYA";
	    break;
	case RHD_OUTPUT_UNIPHYB:
	    TransmitterName = "KLDSKP_UNIPHYB";
	    break;
	case RHD_OUTPUT_UNIPHYC:
	    TransmitterName = "KLDSKP_UNIPHYC";
	    break;
	case RHD_OUTPUT_UNIPHYD:
	    TransmitterName = "KLDSKP_UNIPHYD";
	    break;
	case RHD_OUTPUT_UNIPHYE:
	    TransmitterName = "KLDSKP_UNIPHYE";
	    break;
	case RHD_OUTPUT_UNIPHYF:
	    TransmitterName = "KLDSKP_UNIPHYF";
	    break;
	default:
	    return TRUE;
    }

    switch (Alloc) {
	case RHD_OUTPUT_ALLOC:
	    /*
	     * LVTMA can only use DIG2. Thus exclude
	     * DIG1 for LVTMA and prefer it for the
	     * UNIPHYs.
	     */
	    if (Private->EncoderId != atomEncoderNone)
		return TRUE;
	    if (Output->Id != RHD_OUTPUT_KLDSKP_LVTMA
		&& !rhdPtr->DigEncoderOutput[0]) {
		rhdPtr->DigEncoderOutput[0] = Output;
		TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG1;
		xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG1 encoder to %s\n",TransmitterName);
		return TRUE;
	    } else if (!rhdPtr->DigEncoderOutput[1]) {
		rhdPtr->DigEncoderOutput[1] = Output;
		TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG2;
		xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG2 encoder to %s\n",TransmitterName);
		return TRUE;
	    } else
		return FALSE;
	case RHD_OUTPUT_FREE:
		TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone;
	    if (rhdPtr->DigEncoderOutput[0] == Output) {
		rhdPtr->DigEncoderOutput[0] = NULL;
		return TRUE;
	    } else if (rhdPtr->DigEncoderOutput[1] == Output) {
		rhdPtr->DigEncoderOutput[1] = NULL;
		return TRUE;
	    } else
		return FALSE;
	    break;
	default:
	    return FALSE;
    }
}
Ejemplo n.º 8
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);
}
Ejemplo n.º 9
0
/*
 * This sets up AtomBIOS based BL control if we need to use a non-standard method to control BL.
 */
int
RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output,
				     Bool (**PropertyFunc)(struct rhdOutput *Output,
							   enum rhdPropertyAction Action,
							   enum rhdOutputProperty Property,
							   union rhdPropertyData *val), void **PrivatePtr)
{
    RHDPtr rhdPtr = RHDPTRI(Output);
    int BlLevel;
    struct rhdAtomOutputPrivate *Private;
    struct atomTransmitterConfig *TransmitterConfig;

    RHDFUNC(Output);

    Private = xnfcalloc(sizeof(struct rhdAtomOutputPrivate), 1);

    switch (Output->Id) {
	case RHD_OUTPUT_KLDSKP_LVTMA:
	case RHD_OUTPUT_UNIPHYE:
	case RHD_OUTPUT_UNIPHYF:
	    /* We set up a those parameters although they may never be needed for BL control */
	    TransmitterConfig = &Private->TransmitterConfig;
	    switch (Output->Id) {
		case RHD_OUTPUT_KLDSKP_LVTMA:
		    Private->TransmitterId = atomTransmitterLVTMA;
		    break;
		case RHD_OUTPUT_UNIPHYE:
		    Private->TransmitterId = atomTransmitterUNIPHY2;
		    TransmitterConfig->Link = atomTransLinkA;
		    break;
		case RHD_OUTPUT_UNIPHYF:
		    Private->TransmitterId = atomTransmitterUNIPHY2;
		    TransmitterConfig->Link = atomTransLinkB;
		    break;
		default:
		    return 0;  /* never get here */
	    }
	    TransmitterConfig = &Private->TransmitterConfig;
	    TransmitterConfig->Mode = atomLVDS;
	    if (rhdPtr->DigEncoderOutput[0] == Output)
		TransmitterConfig->Encoder =  Private->EncoderId = atomEncoderDIG1;
	    else if (rhdPtr->DigEncoderOutput[1] == Output)
		TransmitterConfig->Encoder =  Private->EncoderId = atomEncoderDIG2;
	    else
		TransmitterConfig->Encoder =  Private->EncoderId = atomEncoderNone;
	    LVDSInfoRetrieve(rhdPtr, Private);
	    Private->PixelClock = 0;
	    Private->Hdmi = NULL;
	    break;
	case RHD_OUTPUT_LVTMA:
	    Private->OutputControlId = atomLCDOutput;
	    break;
	default:
	    xfree(Private);
	    return 0;
    }
    *PropertyFunc = atomLVDSPropertyControl;
    *PrivatePtr = Private;
    RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlGet, &BlLevel);

    return BlLevel;
}