Merge branch 'modesetting' into modesetting-rotation

This commit is contained in:
Eric Anholt 2007-01-18 10:20:36 -08:00
commit cc09dc3efe
5 changed files with 177 additions and 18 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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
};

View File

@ -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))

View File

@ -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
*/