Merge branch 'modesetting' into modesetting-rotation
This commit is contained in:
commit
cc09dc3efe
|
|
@ -937,8 +937,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define BLC_PWM_CTL 0x61254
|
||||
#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
|
||||
/**
|
||||
* This is the most significant 15 bits of the number of backlight cycles in a
|
||||
* complete cycle of the modulated backlight control.
|
||||
*
|
||||
* The actual value is this field multiplied by two.
|
||||
*/
|
||||
#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
|
||||
#define BLM_LEGACY_MODE (1 << 16)
|
||||
/**
|
||||
* This is the number of cycles out of the backlight modulation cycle for which
|
||||
* the backlight is on.
|
||||
*
|
||||
* This field must be no greater than the number of cycles in the complete
|
||||
* backlight modulation cycle.
|
||||
*/
|
||||
#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
|
||||
#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ typedef enum {
|
|||
DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
|
||||
/* First detailed mode is bogus, prefer largest mode at 60hz */
|
||||
DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
|
||||
/* 135MHz clock is too high, drop a bit */
|
||||
DDC_QUIRK_135_CLOCK_TOO_HIGH = 1 << 2
|
||||
} ddc_quirk_t;
|
||||
|
||||
static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
|
||||
|
|
@ -78,6 +80,16 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
|
||||
{
|
||||
/* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
|
||||
if (memcmp (DDC->vendor.name, "EPI", 4) == 0 &&
|
||||
DDC->vendor.prod_id == 59264)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
|
||||
ddc_quirk_t quirk;
|
||||
|
|
@ -93,6 +105,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
|
|||
quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60,
|
||||
"Detailed timing is not preferred, use largest mode at 60Hz"
|
||||
},
|
||||
{
|
||||
quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
|
||||
"Recommended 135MHz pixel clock is too high"
|
||||
},
|
||||
{
|
||||
NULL, DDC_QUIRK_NONE,
|
||||
"No known quirks"
|
||||
|
|
@ -197,7 +213,11 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
|
|||
if (preferred)
|
||||
Mode->type |= M_T_PREFERRED;
|
||||
|
||||
Mode->Clock = timing->clock / 1000.0;
|
||||
if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) &&
|
||||
timing->clock == 135000000 )
|
||||
Mode->Clock = 108880;
|
||||
else
|
||||
Mode->Clock = timing->clock / 1000.0;
|
||||
|
||||
Mode->HDisplay = timing->h_active;
|
||||
Mode->HSyncStart = timing->h_active + timing->h_sync_off;
|
||||
|
|
|
|||
124
src/i830_lvds.c
124
src/i830_lvds.c
|
|
@ -32,6 +32,34 @@
|
|||
#include "xf86.h"
|
||||
#include "i830.h"
|
||||
#include "i830_bios.h"
|
||||
#include "X11/Xatom.h"
|
||||
|
||||
/**
|
||||
* Sets the backlight level.
|
||||
*
|
||||
* \param level backlight level, from 0 to i830_lvds_get_max_backlight().
|
||||
*/
|
||||
static void
|
||||
i830_lvds_set_backlight(ScrnInfoPtr pScrn, int level)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 blc_pwm_ctl;
|
||||
|
||||
blc_pwm_ctl = INREG(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum level of the backlight duty cycle field.
|
||||
*/
|
||||
static CARD32
|
||||
i830_lvds_get_max_backlight(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
return ((INREG(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
|
||||
BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the power state for the panel.
|
||||
|
|
@ -41,25 +69,16 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
|
|||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 pp_status;
|
||||
CARD32 blc_pwm_ctl;
|
||||
int backlight_duty_cycle;
|
||||
|
||||
blc_pwm_ctl = INREG (BLC_PWM_CTL);
|
||||
backlight_duty_cycle = blc_pwm_ctl & BACKLIGHT_DUTY_CYCLE_MASK;
|
||||
if (backlight_duty_cycle)
|
||||
pI830->backlight_duty_cycle = backlight_duty_cycle;
|
||||
|
||||
if (on) {
|
||||
OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON);
|
||||
do {
|
||||
pp_status = INREG(PP_STATUS);
|
||||
} while ((pp_status & PP_ON) == 0);
|
||||
OUTREG(BLC_PWM_CTL,
|
||||
(blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK) |
|
||||
pI830->backlight_duty_cycle);
|
||||
|
||||
i830_lvds_set_backlight(pScrn, pI830->backlight_duty_cycle);
|
||||
} else {
|
||||
OUTREG(BLC_PWM_CTL,
|
||||
(blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK));
|
||||
i830_lvds_set_backlight(pScrn, 0);
|
||||
|
||||
OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON);
|
||||
do {
|
||||
|
|
@ -99,11 +118,8 @@ i830_lvds_save (xf86OutputPtr output)
|
|||
/*
|
||||
* If the light is off at server startup, just make it full brightness
|
||||
*/
|
||||
if (pI830->backlight_duty_cycle == 0) {
|
||||
pI830->backlight_duty_cycle =
|
||||
(pI830->saveBLC_PWM_CTL & BACKLIGHT_MODULATION_FREQ_MASK) >>
|
||||
BACKLIGHT_MODULATION_FREQ_SHIFT;
|
||||
}
|
||||
if (pI830->backlight_duty_cycle == 0)
|
||||
pI830->backlight_duty_cycle = i830_lvds_get_max_backlight(pScrn);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -294,7 +310,80 @@ i830_lvds_destroy (xf86OutputPtr output)
|
|||
xfree (intel_output);
|
||||
}
|
||||
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
#define BACKLIGHT_NAME "BACKLIGHT"
|
||||
static Atom backlight_atom;
|
||||
#endif /* RANDR_12_INTERFACE */
|
||||
|
||||
static void
|
||||
i830_lvds_create_resources(xf86OutputPtr output)
|
||||
{
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
INT32 range[2];
|
||||
int data, err;
|
||||
|
||||
/* Set up the backlight property, which takes effect immediately
|
||||
* and accepts values only within the range.
|
||||
*
|
||||
* XXX: Currently, RandR doesn't verify that properties set are
|
||||
* within the range.
|
||||
*/
|
||||
backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1,
|
||||
TRUE);
|
||||
|
||||
range[0] = 0;
|
||||
range[1] = i830_lvds_get_max_backlight(pScrn);
|
||||
err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
|
||||
FALSE, TRUE, FALSE, 2, range);
|
||||
if (err != 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"RRConfigureOutputProperty error, %d\n", err);
|
||||
}
|
||||
/* Set the current value of the backlight property */
|
||||
data = pI830->backlight_duty_cycle;
|
||||
err = RRChangeOutputProperty(output->randr_output, backlight_atom,
|
||||
XA_INTEGER, 32, PropModeReplace, 4, &data,
|
||||
FALSE);
|
||||
if (err != 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"RRChangeOutputProperty error, %d\n", err);
|
||||
}
|
||||
|
||||
#endif /* RANDR_12_INTERFACE */
|
||||
}
|
||||
|
||||
static Bool
|
||||
i830_lvds_set_property(xf86OutputPtr output, Atom property,
|
||||
RRPropertyValuePtr value)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (property == backlight_atom) {
|
||||
INT32 val;
|
||||
|
||||
if (value->type != XA_INTEGER || value->format != 32 ||
|
||||
value->size != 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
val = *(INT32 *)value->data;
|
||||
if (val < 0 || val > i830_lvds_get_max_backlight(pScrn))
|
||||
return FALSE;
|
||||
|
||||
i830_lvds_set_backlight(pScrn, val);
|
||||
pI830->backlight_duty_cycle = val;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const xf86OutputFuncsRec i830_lvds_output_funcs = {
|
||||
.create_resources = i830_lvds_create_resources,
|
||||
.dpms = i830_lvds_dpms,
|
||||
.save = i830_lvds_save,
|
||||
.restore = i830_lvds_restore,
|
||||
|
|
@ -303,6 +392,7 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = {
|
|||
.mode_set = i830_lvds_mode_set,
|
||||
.detect = i830_lvds_detect,
|
||||
.get_modes = i830_lvds_get_modes,
|
||||
.set_property = i830_lvds_set_property,
|
||||
.destroy = i830_lvds_destroy
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -680,6 +680,23 @@ xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12OutputSetProperty (ScreenPtr pScreen,
|
||||
RROutputPtr randr_output,
|
||||
Atom property,
|
||||
RRPropertyValuePtr value)
|
||||
{
|
||||
xf86OutputPtr output = randr_output->devPrivate;
|
||||
|
||||
/* If we don't have any property handler, then we don't care what the
|
||||
* user is setting properties to.
|
||||
*/
|
||||
if (output->funcs->set_property == NULL)
|
||||
return TRUE;
|
||||
|
||||
return output->funcs->set_property(output, property, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a list of xf86 modes and a RandR Output object, construct
|
||||
* RandR modes and assign them to the output
|
||||
|
|
@ -871,6 +888,9 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
|
|||
strlen (output->name),
|
||||
output);
|
||||
RROutputAttachScreen (output->randr_output, pScreen);
|
||||
|
||||
if (output->funcs->create_resources != NULL)
|
||||
output->funcs->create_resources(output);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -907,6 +927,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
|
|||
rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
|
||||
rp->rrCrtcSet = xf86RandR12CrtcSet;
|
||||
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
||||
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
|
||||
rp->rrSetConfig = NULL;
|
||||
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
||||
if (!xf86RandR12CreateObjects12 (pScreen))
|
||||
|
|
|
|||
|
|
@ -200,6 +200,13 @@ struct _xf86Crtc {
|
|||
};
|
||||
|
||||
typedef struct _xf86OutputFuncs {
|
||||
/**
|
||||
* Called to allow the output a chance to create properties after the
|
||||
* RandR objects have been created.
|
||||
*/
|
||||
void
|
||||
(*create_resources)(xf86OutputPtr output);
|
||||
|
||||
/**
|
||||
* Turns the output on/off, or sets intermediate power levels if available.
|
||||
*
|
||||
|
|
@ -275,6 +282,14 @@ typedef struct _xf86OutputFuncs {
|
|||
DisplayModePtr
|
||||
(*get_modes)(xf86OutputPtr output);
|
||||
|
||||
/**
|
||||
* Callback when an output's property has changed.
|
||||
*/
|
||||
Bool
|
||||
(*set_property)(xf86OutputPtr output,
|
||||
Atom property,
|
||||
RRPropertyValuePtr value);
|
||||
|
||||
/**
|
||||
* Clean up driver-specific bits of the output
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue