diff --git a/src/rhd_lvtma.c b/src/rhd_lvtma.c index 93960d4..102fc6f 100644 --- a/src/rhd_lvtma.c +++ b/src/rhd_lvtma.c @@ -91,6 +91,8 @@ LVTMARegisterShift(int ChipSet, CARD16 R500, CARD16 R600) LVTMAREGSHIFT(LVTMA_R500_TRANSMITTER_CONTROL, LVTMA_R600_TRANSMITTER_CONTROL) #define LVTMA_REG_TEST_OUTPUT \ LVTMAREGSHIFT(LVTMA_R500_REG_TEST_OUTPUT, LVTMA_R600_REG_TEST_OUTPUT) +#define LVTMA_BL_MOD_CNTL \ + LVTMAREGSHIFT(LVTMA_R500_BL_MOD_CNTL, LVTMA_R600_BL_MOD_CNTL) /* * @@ -400,6 +402,54 @@ LVDSSave(struct rhdOutput *Output) Private->Stored = TRUE; } +static int +LVDSBacklight(struct rhdOutput *Output) +{ + RHDPtr rhdPtr = RHDPTRI(Output); + CARD32 tmp; + Bool Blon, BlonOvrd, BlonPol, BlModEn; + int BlModLevel, BlModRes = 0; + + tmp = (RHDRegRead(Output, LVTMA_PWRSEQ_STATE) >> 3) & 0x01; + xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "%s: PWRSEQ BLON State: %s\n", + __func__, tmp ? "on" : "off"); + tmp = RHDRegRead(rhdPtr, LVTMA_PWRSEQ_CNTL); + Blon = (tmp >> 24) & 0x1; + BlonOvrd = (tmp >> 25) & 0x1; + BlonPol = (tmp >> 26) & 0x1; + + xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "%s: BLON: %s BLON_OVRD: %s BLON_POL: %s\n", + __func__, Blon ? "on" : "off", + BlonOvrd ? "enabled" : "disabled", + BlonPol ? "invert" : "non-invert"); + + tmp = RHDRegRead(rhdPtr, LVTMA_BL_MOD_CNTL); + BlModEn = tmp & 0x1; + BlModLevel = (tmp >> 8) & 0xFF; + if (rhdPtr->ChipSet >= RHD_RS600) + BlModRes = (tmp >> 16) & 0xFF; + + xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "%s: BL_MOD: %s BL_MOD_LEVEL: %d BL_MOD_RES: %d\n", + __func__, BlModEn ? "enable" : "disable", + BlModLevel, BlModRes); + + return BlModLevel; +} + +static void +LVDSSetBacklight(struct rhdOutput *Output, int level) +{ + RHDPtr rhdPtr = RHDPTRI(Output); + + xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "%s: trying to set BL_MOD_LEVEL to: %d\n", __func__, level); + RHDRegMask(rhdPtr, LVTMA_BL_MOD_CNTL, level << 8, 0xFF00); + + /* + * Poor man's debug + */ + LVDSBacklight(Output); +} + /* * This needs to reset things like the temporal dithering and the TX appropriately. * Currently it's a dumb register dump. @@ -432,6 +482,11 @@ LVDSRestore(struct rhdOutput *Output) RHDRegWrite(Output, LVTMA_TRANSMITTER_ENABLE, Private->StoreTxEnable); RHDRegWrite(Output, LVTMA_MACRO_CONTROL, Private->StoreMacroControl); RHDRegWrite(Output, LVTMA_TRANSMITTER_CONTROL, Private->StoreTXControl); + + /* + * Poor man's debug + */ + LVDSBacklight(Output); } /* @@ -469,6 +524,14 @@ LVDSInfoRetrieve(RHDPtr rhdPtr) Private->LVDS24Bit = RHDRegRead(rhdPtr, LVTMA_LVDS_DATA_CNTL) & 0x00000001; Private->FPDI = RHDRegRead(rhdPtr, LVTMA_LVDS_DATA_CNTL) & 0x00000010; + { + struct rhdOutput *ro = rhdPtr->Outputs; + while(ro && ro->Id != RHD_OUTPUT_LVTMA) + ro = ro->Next; + if (ro) + LVDSBacklight(ro); + } + tmp = RHDRegRead(rhdPtr, LVTMA_BIT_DEPTH_CONTROL); Private->TemporalDither = ((tmp & (1 << 16)) != 0); Private->SpatialDither = ((tmp & (1 << 8)) != 0); @@ -930,6 +993,8 @@ RHDLVTMAInit(RHDPtr rhdPtr, CARD8 Type) Output->Power = LVDSPower; Output->Save = LVDSSave; Output->Restore = LVDSRestore; + Output->Backlight = LVDSBacklight; + Output->SetBacklight = LVDSSetBacklight; Output->Private = LVDSInfoRetrieve(rhdPtr); } else { diff --git a/src/rhd_output.h b/src/rhd_output.h index f94168a..d147e06 100644 --- a/src/rhd_output.h +++ b/src/rhd_output.h @@ -80,6 +80,8 @@ struct rhdOutput { void (*Save) (struct rhdOutput *Output); void (*Restore) (struct rhdOutput *Output); void (*Destroy) (struct rhdOutput *Output); + int (*Backlight) (struct rhdOutput *Output); + void (*SetBacklight) (struct rhdOutput *Output, int level); /* Output Private data */ void *Private; diff --git a/src/rhd_randr.c b/src/rhd_randr.c index 2c80aa2..af79387 100644 --- a/src/rhd_randr.c +++ b/src/rhd_randr.c @@ -101,9 +101,10 @@ typedef struct _rhdRandrOutput { #define ATOM_CONNECTOR_NUMBER "RANDR_CONNECTOR_NUMBER" #define ATOM_OUTPUT_NUMBER "RANDR_OUTPUT_NUMBER" #define ATOM_PANNING_AREA "RANDR_PANNING_AREA" +#define ATOM_BACKLIGHT "BACKLIGHT" static Atom atomSignalFormat, atomConnectorType, atomConnectorNumber, - atomOutputNumber, atomPanningArea; + atomOutputNumber, atomPanningArea, atomBacklight; /* Get RandR property values */ @@ -414,7 +415,9 @@ static Bool rhdRRCrtcModeFixupDUMMY(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ return TRUE; } +{ + return TRUE; +} #if 0 /* Needed if we want to support rotation w/o own hardware support */ void * @@ -455,6 +458,8 @@ rhdRROutputCreateResources(xf86OutputPtr out) struct rhdOutput *o; const char *val; CARD32 num; + int err; + INT32 range[2]; RHDFUNC(rhdPtr); @@ -479,6 +484,33 @@ rhdRROutputCreateResources(xf86OutputPtr out) FALSE, FALSE, TRUE, 0, NULL); RRConfigureOutputProperty(out->randr_output, atomPanningArea, FALSE, FALSE, FALSE, 0, NULL); + + if (rout->Output->Id == RHD_OUTPUT_LVTMA && + rout->Connector->Type == RHD_CONNECTOR_PANEL) { + atomBacklight = MakeAtom(ATOM_BACKLIGHT, + sizeof(ATOM_BACKLIGHT)-1, TRUE); + + range[0] = 0; + range[1] = 255; + err = RRConfigureOutputProperty(out->randr_output, atomBacklight, + FALSE, TRUE, FALSE, 2, range); + if (err != 0) + xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error: %d\n", err); + else { + int data = rout->Output->Backlight ? + rout->Output->Backlight(rout->Output) : 255; + + err = RRChangeOutputProperty(out->randr_output, atomBacklight, + XA_INTEGER, 32, PropModeReplace, + 1, &data, FALSE, FALSE); + if (err != 0) + xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, + "In %s RRChangeOutputProperty error: %d\n", + __func__, err); + } + } + val = rhdGetSignalFormat(rout); RRChangeOutputProperty(out->randr_output, atomSignalFormat, XA_STRING, 8, PropModeReplace, @@ -946,12 +978,53 @@ rhdRROutputSetProperty(xf86OutputPtr out, Atom property, default: return FALSE; } + } else if (property == atomBacklight) { + if (value->type != XA_INTEGER || value->format != 32) { + xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: wrong value\n", __func__); + return FALSE; + } + if (rout->Output->SetBacklight) { + rout->Output->SetBacklight(rout->Output, *(int*)(value->data)); + } + return TRUE; } return FALSE; /* Others are not mutable */ } +#ifdef RANDR_13_INTERFACE +static Bool +rhdRROutputGetProperty(xf86OutputPtr out, Atom property) +{ + RHDPtr rhdPtr = RHDPTR(out->scrn); + rhdRandrOutputPtr rout = (rhdRandrOutputPtr) out->driver_private; + int data = 255, err; + + xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "In %s\n", __func__); + + if (property == atomBacklight) { + if (rout->Output->Backlight == NULL) + return FALSE; + + data = rout->Output->Backlight(rout->Output); + + err = RRChangeOutputProperty(out->randr_output, atomBacklight, + XA_INTEGER, 32, PropModeReplace, + 1, &data, FALSE, FALSE); + + if (err != 0) { + xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "In %s RRChangeOutputProperty error: %d\n", __func__, err); + return FALSE; + } + + return TRUE; + } + + return FALSE; +} +#endif + /* * Xorg Interface */ @@ -981,6 +1054,9 @@ static const xf86OutputFuncsRec rhdRROutputFuncs = { rhdRROutputPrepare, rhdRROutputCommit, rhdRROutputModeSet, rhdRROutputDetect, rhdRROutputGetModes, rhdRROutputSetProperty, /* Only(!) RANDR_12_INTERFACE */ +#ifdef RANDR_13_INTERFACE + rhdRROutputGetProperty, /* get_property */ +#endif NULL /* Destroy */ }; diff --git a/src/rhd_regs.h b/src/rhd_regs.h index efb53b4..83b3bea 100644 --- a/src/rhd_regs.h +++ b/src/rhd_regs.h @@ -293,6 +293,7 @@ enum { LVTMA_R500_PWRSEQ_DELAY2 = 0x7AEC, LVTMA_R500_PWRSEQ_CNTL = 0x7AF0, LVTMA_R500_PWRSEQ_STATE = 0x7AF4, + LVTMA_R500_BL_MOD_CNTL = 0x7AF8, LVTMA_R500_LVDS_DATA_CNTL = 0x7AFC, LVTMA_R500_MODE = 0x7B00, LVTMA_R500_TRANSMITTER_ENABLE = 0x7B04, @@ -308,6 +309,7 @@ enum { LVTMA_R600_PWRSEQ_DELAY2 = 0x7AF0, LVTMA_R600_PWRSEQ_CNTL = 0x7AF4, LVTMA_R600_PWRSEQ_STATE = 0x7AF8, + LVTMA_R600_BL_MOD_CNTL = 0x7AFC, LVTMA_R600_LVDS_DATA_CNTL = 0x7B00, LVTMA_R600_MODE = 0x7B04, LVTMA_R600_TRANSMITTER_ENABLE = 0x7B08,