xf86-video-intel: Branch 'modesetting-rotation' - 6 commits - src/i810_reg.h src/i830_edid_modes.c src/i830_lvds.c src/i830_randr.c src/i830_xf86Crtc.c src/i830_xf86Crtc.h src/i830_xf86Rotate.c
Eric Anholt
anholt at kemper.freedesktop.org
Thu Jan 18 21:37:49 EET 2007
src/i810_reg.h | 13 +++++
src/i830_edid_modes.c | 22 ++++++++
src/i830_lvds.c | 124 +++++++++++++++++++++++++++++++++++++++++++-------
src/i830_randr.c | 21 ++++++++
src/i830_xf86Crtc.c | 30 ++++++++----
src/i830_xf86Crtc.h | 15 ++++++
src/i830_xf86Rotate.c | 55 ++++++++++++++--------
7 files changed, 235 insertions(+), 45 deletions(-)
New commits:
diff-tree d2ae2e2ccc3a8e7dc84745c235836cba150754d8 (from 92b0f3d2013c32d94fe57fe674da1b195288f347)
Author: Eric Anholt <eric at anholt.net>
Date: Thu Jan 18 11:37:14 2007 -0800
Update CRTC values first so they can be used by the driver in mode setting.
With this, the screen now gets rotated, though there are major issues.
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index a926e9f..c879d99 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -154,6 +154,9 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, Displ
Bool ret = FALSE;
Bool didLock = FALSE;
DisplayModePtr adjusted_mode;
+ DisplayModeRec saved_mode;
+ int saved_x, saved_y;
+ Rotation saved_rotation;
adjusted_mode = xf86DuplicateMode(mode);
@@ -167,6 +170,18 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, Displ
didLock = crtc->funcs->lock (crtc);
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+ /* Update crtc values up front so the driver can rely on them for mode
+ * setting.
+ */
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+
/* XXX short-circuit changes to base location only */
/* Pass our mode to the outputs and the CRTC to give them a chance to
@@ -180,18 +195,15 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, Displ
continue;
if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
- ret = FALSE;
goto done;
}
}
if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
- ret = FALSE;
goto done;
}
if (!xf86CrtcRotate (crtc, mode, rotation)) {
- ret = FALSE;
goto done;
}
@@ -228,14 +240,16 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, Displ
output->funcs->dpms(output, DPMSModeOn);
}
- crtc->mode = *mode;
- crtc->x = x;
- crtc->y = y;
- crtc->rotation = rotation;
-
/* XXX free adjustedmode */
ret = TRUE;
done:
+ if (!ret) {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ crtc->mode = saved_mode;
+ }
+
if (didLock)
crtc->funcs->unlock (crtc);
diff-tree 92b0f3d2013c32d94fe57fe674da1b195288f347 (from 14d265a02312e9cda7a21614d77525c7140c0ca8)
Author: Eric Anholt <eric at anholt.net>
Date: Thu Jan 18 11:23:22 2007 -0800
Disable the clipping for now, since it won't work.
diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
index 39733fd..670ad7a 100644
--- a/src/i830_xf86Rotate.c
+++ b/src/i830_xf86Rotate.c
@@ -127,7 +127,13 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
ErrorF("couldn't create src pict\n");
return;
}
- SetPictureClipRegion (src, 0, 0, region);
+ /* Unfortunately, we don't do clipping on transformed source pictures.
+ * So we can't use this. Instead, we'll just repaint the whole screen
+ * for now, and do transform of the source region into a dest region
+ * later.
+ */
+ /* SetPictureClipRegion (src, 0, 0, region); */
+
memset (&transform, '\0', sizeof (transform));
transform.matrix[2][2] = IntToxFixed(1);
transform.matrix[0][2] = IntToxFixed(crtc->x);
diff-tree 14d265a02312e9cda7a21614d77525c7140c0ca8 (from cc09dc3efe7279bf67512babb0f6cdaeba654772)
Author: Eric Anholt <eric at anholt.net>
Date: Thu Jan 18 11:21:58 2007 -0800
Store fixed values, not integers, in the transformation matrix.
Also, add a bit more error checking.
diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
index 14c0c5d..39733fd 100644
--- a/src/i830_xf86Rotate.c
+++ b/src/i830_xf86Rotate.c
@@ -112,8 +112,10 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
NULL,
serverClient,
&error);
- if (!src)
+ if (!src) {
+ ErrorF("couldn't create src pict\n");
return;
+ }
dst = CreatePicture (None,
&dst_pixmap->drawable,
format,
@@ -121,38 +123,41 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
NULL,
serverClient,
&error);
- if (!dst)
+ if (!dst) {
+ ErrorF("couldn't create src pict\n");
return;
+ }
SetPictureClipRegion (src, 0, 0, region);
memset (&transform, '\0', sizeof (transform));
- transform.matrix[2][2] = 1;
- transform.matrix[0][2] = crtc->x;
- transform.matrix[1][2] = crtc->y;
+ transform.matrix[2][2] = IntToxFixed(1);
+ transform.matrix[0][2] = IntToxFixed(crtc->x);
+ transform.matrix[1][2] = IntToxFixed(crtc->y);
switch (crtc->rotation & 0xf) {
case RR_Rotate_0:
- transform.matrix[0][0] = 1;
- transform.matrix[1][1] = 1;
+ transform.matrix[0][0] = IntToxFixed(1);
+ transform.matrix[1][1] = IntToxFixed(1);
break;
case RR_Rotate_90:
/* XXX probably wrong */
- transform.matrix[0][1] = 1;
- transform.matrix[1][0] = -1;
- transform.matrix[1][2] += crtc->mode.HDisplay;
+ transform.matrix[0][1] = IntToxFixed(1);
+ transform.matrix[1][0] = IntToxFixed(-1);
+ transform.matrix[1][2] += IntToxFixed(crtc->mode.HDisplay);
break;
case RR_Rotate_180:
/* XXX probably wrong */
- transform.matrix[0][0] = -1;
- transform.matrix[1][1] = -1;
- transform.matrix[0][2] += crtc->mode.HDisplay;
- transform.matrix[1][2] += crtc->mode.VDisplay;
+ transform.matrix[0][0] = IntToxFixed(-1);
+ transform.matrix[1][1] = IntToxFixed(-1);
+ transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
+ transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
break;
case RR_Rotate_270:
/* XXX probably wrong */
- transform.matrix[0][1] = -1;
- transform.matrix[1][0] = 1;
- transform.matrix[0][2] += crtc->mode.VDisplay;
+ transform.matrix[0][1] = IntToxFixed(-1);
+ transform.matrix[1][0] = IntToxFixed(1);
+ transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
break;
}
+
/* handle reflection */
if (crtc->rotation & RR_Reflect_X)
{
@@ -162,7 +167,13 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crt
{
/* XXX figure this out too */
}
- SetPictureTransform (src, &transform);
+
+ error = SetPictureTransform (src, &transform);
+ if (error) {
+ ErrorF("Couldn't set transform\n");
+ return;
+ }
+
CompositePicture (PictOpSrc,
src, NULL, dst,
0, 0, 0, 0, 0, 0,
diff-tree cc09dc3efe7279bf67512babb0f6cdaeba654772 (from parents)
Merge: 53e765d1cf5016961c25a798a27f0fe09bd1f237 3094100cdd04560af1b098bbe8024ae5270a10f4
Author: Eric Anholt <eric at anholt.net>
Date: Thu Jan 18 10:20:36 2007 -0800
Merge branch 'modesetting' into modesetting-rotation
diff-tree 3094100cdd04560af1b098bbe8024ae5270a10f4 (from 66c6427cc83e5e381932b0c10743cba4cb9ac883)
Author: Gary Wong <gtw at gnu.org>
Date: Tue Jan 16 13:25:24 2007 -0800
Bug #9550: Add a quirk for too-high clock from EDID on the EN-7100e.
diff --git a/src/i830_edid_modes.c b/src/i830_edid_modes.c
index 249f87a..1bab4cd 100644
--- a/src/i830_edid_modes.c
+++ b/src/i830_edid_modes.c
@@ -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 s
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,
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;
diff-tree 66c6427cc83e5e381932b0c10743cba4cb9ac883 (from 45696aa29124e2852f94880642e70bb2e0cee827)
Author: Eric Anholt <eric at anholt.net>
Date: Tue Jan 16 12:54:29 2007 -0800
Add a settable backlight property for LVDS.
This extends the output funcs to have a callback for when it's time to
configure properties, and another for when the server has changed a property
whose value isn't pending a mode set. (Pending properties are to be picked up
by the driver at mode_set time).
diff --git a/src/i810_reg.h b/src/i810_reg.h
index c2eb854..33b059d 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -937,8 +937,21 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#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)
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 18ac76b..223c6ab 100644
--- a/src/i830_lvds.c
+++ b/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,
{
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_lvd
.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
};
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 18f84c4..6388849 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -672,6 +672,23 @@ xf86RandR12CrtcSetGamma (ScreenPtr pS
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
@@ -861,6 +878,9 @@ xf86RandR12CreateObjects12 (ScreenPtr pS
strlen (output->name),
output);
RROutputAttachScreen (output->randr_output, pScreen);
+
+ if (output->funcs->create_resources != NULL)
+ output->funcs->create_resources(output);
}
return TRUE;
}
@@ -897,6 +917,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))
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
index 8fea162..b5f2fc2 100644
--- a/src/i830_xf86Crtc.h
+++ b/src/i830_xf86Crtc.h
@@ -171,6 +171,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.
*
* Unsupported intermediate modes drop to the lower power setting. If the
@@ -246,6 +253,14 @@ typedef struct _xf86OutputFuncs {
(*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
*/
void
More information about the xorg-commit
mailing list