Merge branch 'modesetting' into crestline

This commit is contained in:
Keith Packard 2006-12-19 22:01:02 -08:00
commit 07d3f14171
15 changed files with 343 additions and 336 deletions

View File

@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../
ch7xxx_la_LTLIBRARIES = ch7xxx.la
ch7xxx_la_LDFLAGS = -module -avoid-version

View File

@ -25,6 +25,11 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include "xf86.h"
#include "xf86_OSproc.h"
@ -32,6 +37,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
#include "i830_xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "../i2c_vid.h"
#include "ch7xxx.h"
@ -41,151 +49,179 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* driver for the Chrontel 7xxx DVI chip over DVO.
*/
static void ch7xxxSaveRegs(I2CDevPtr d);
static struct ch7xxx_id_struct {
int vid;
char *name;
} ch7xxx_ids[] = {
{ CH7011_VID, "CH7011" },
{ CH7009A_VID, "CH7009A" },
{ CH7009B_VID, "CH7009B" },
};
#define ID_ARRAY_SIZE (sizeof(ch7xxx_ids) / sizeof(ch7xxx_ids[0]))
struct ch7xxx_reg_state {
CARD8 regs[CH7xxx_NUM_REGS];
};
struct ch7xxx_priv {
I2CDevRec d;
struct ch7xxx_reg_state SavedReg;
struct ch7xxx_reg_state ModeReg;
CARD8 save_TCTL, save_TPCP, save_TPD, save_TPVT;
CARD8 save_TLPF, save_TCT, save_PM, save_IDF;
};
static void ch7xxx_save(I2CDevPtr d);
static CARD8 ch7xxxFreqRegs[][7] =
{ { 0, 0x23, 0x08, 0x16, 0x30, 0x60, 0x00 },
{ 0, 0x23, 0x04, 0x26, 0x30, 0x60, 0x00 },
{ 0, 0x2D, 0x07, 0x26, 0x30, 0xE0, 0x00 } };
static Bool ch7xxxReadByte(CH7xxxPtr ch7xxx, int addr, unsigned char *ch)
static char *ch7xxx_get_id(int vid)
{
if (!xf86I2CReadByte(&(ch7xxx->d), addr, ch)) {
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex,
X_ERROR, "Unable to read from %s Slave %d.\n",
ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr);
return FALSE;
int i;
for (i = 0; i < ID_ARRAY_SIZE; i++) {
if (ch7xxx_ids[i].vid == vid)
return ch7xxx_ids[i].name;
}
return TRUE;
}
static Bool ch7xxxWriteByte(CH7xxxPtr ch7xxx, int addr, unsigned char ch)
{
if (!xf86I2CWriteByte(&(ch7xxx->d), addr, ch)) {
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to write to %s Slave %d.\n",
ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
static void *ch7xxxDetect(I2CBusPtr b, I2CSlaveAddr addr)
{
/* this will detect the CH7xxx chip on the specified i2c bus */
CH7xxxPtr ch7xxx;
unsigned char ch;
xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting ch7xxx\n");
ch7xxx = xcalloc(1, sizeof(CH7xxxRec));
if (ch7xxx == NULL)
return NULL;
ch7xxx->d.DevName = "CH7xxx TMDS Controller";
ch7xxx->d.SlaveAddr = addr;
ch7xxx->d.pI2CBus = b;
ch7xxx->d.StartTimeout = b->StartTimeout;
ch7xxx->d.BitTimeout = b->BitTimeout;
ch7xxx->d.AcknTimeout = b->AcknTimeout;
ch7xxx->d.ByteTimeout = b->ByteTimeout;
ch7xxx->d.DriverPrivate.ptr = ch7xxx;
if (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_VID, &ch))
goto out;
ErrorF("VID is %02X", ch);
if (ch!=(CH7xxx_VID & 0xFF)) {
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"ch7xxx not detected got %d: from %s Slave %d.\n",
ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr);
goto out;
}
if (!ch7xxxReadByte(ch7xxx, CH7xxx_REG_DID, &ch))
goto out;
ErrorF("DID is %02X", ch);
if (ch!=(CH7xxx_DID & 0xFF)) {
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"ch7xxx not detected got %d: from %s Slave %d.\n",
ch, ch7xxx->d.pI2CBus->BusName, ch7xxx->d.SlaveAddr);
goto out;
}
if (!xf86I2CDevInit(&(ch7xxx->d))) {
goto out;
}
return ch7xxx;
out:
xfree(ch7xxx);
return NULL;
}
static Bool ch7xxxInit(I2CDevPtr d)
/** Reads an 8 bit register */
static Bool
ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) {
xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex,
X_ERROR, "Unable to read from %s Slave %d.\n",
dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
/* not much to do */
return TRUE;
}
static ModeStatus ch7xxxModeValid(I2CDevPtr d, DisplayModePtr mode)
/** Writes an 8 bit register */
static Bool
ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) {
xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to write to %s Slave %d.\n",
dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
static void *
ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr)
{
/* this will detect the CH7xxx chip on the specified i2c bus */
struct ch7xxx_priv *dev_priv;
CARD8 vendor, device;
unsigned char ch;
char *name;
dev_priv = xcalloc(1, sizeof(struct ch7xxx_priv));
if (dev_priv == NULL)
return NULL;
dev_priv->d.DevName = "CH7xxx TMDS Controller";
dev_priv->d.SlaveAddr = addr;
dev_priv->d.pI2CBus = b;
dev_priv->d.StartTimeout = b->StartTimeout;
dev_priv->d.BitTimeout = b->BitTimeout;
dev_priv->d.AcknTimeout = b->AcknTimeout;
dev_priv->d.ByteTimeout = b->ByteTimeout;
dev_priv->d.DriverPrivate.ptr = dev_priv;
if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor))
goto out;
name = ch7xxx_get_id(vendor);
if (!name) {
xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO,
"ch7xxx not detected; got 0x%02x from %s slave %d.\n",
vendor, dev_priv->d.pI2CBus->BusName,
dev_priv->d.SlaveAddr);
goto out;
}
if (!ch7xxx_read(dev_priv, CH7xxx_REG_DID, &device))
goto out;
if (device != CH7xxx_DID) {
xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO,
"ch7xxx not detected; got 0x%02x from %s slave %d.\n",
device, dev_priv->d.pI2CBus->BusName,
dev_priv->d.SlaveAddr);
goto out;
}
xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO,
"Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
name, vendor, device);
if (!xf86I2CDevInit(&dev_priv->d)) {
goto out;
}
return dev_priv;
out:
xfree(dev_priv);
return NULL;
}
static xf86OutputStatus
ch7xxx_detect(I2CDevPtr d)
{
return XF86OutputStatusUnknown;
}
static ModeStatus
ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode)
{
if (mode->Clock > 165000)
return MODE_CLOCK_HIGH;
return MODE_OK;
}
static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode)
static void
ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
int ret;
unsigned char pm, idf;
unsigned char tpcp, tpd, tpf, cm;
CARD8 *freq_regs;
int i;
struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
CARD8 tvco, tpcp, tpd, tlpf, idf;
ErrorF("Clock is %d\n", mode->Clock);
if (mode->Clock < 75000)
freq_regs = ch7xxxFreqRegs[0];
else if (mode->Clock < 125000)
freq_regs = ch7xxxFreqRegs[1];
else
freq_regs = ch7xxxFreqRegs[2];
for (i = 0x31; i < 0x37; i++) {
ch7xxx->ModeReg.regs[i] = freq_regs[i - 0x31];
ch7xxxWriteByte(ch7xxx, i, ch7xxx->ModeReg.regs[i]);
}
#if 0
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"ch7xxx idf is 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
idf, tpcp, tpd, tpf);
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"ch7xxx pm is %02X\n", pm);
if (mode->Clock < 65000) {
if (mode->Clock <= 65000) {
tvco = 0x23;
tpcp = 0x08;
tpd = 0x16;
tpf = 0x60;
tlpf = 0x60;
} else {
tvco = 0x2d;
tpcp = 0x06;
tpd = 0x26;
tpf = 0xa0;
tlpf = 0xa0;
}
ch7xxx_write(dev_priv, CH7xxx_TCTL, 0x00);
ch7xxx_write(dev_priv, CH7xxx_TVCO, tvco);
ch7xxx_write(dev_priv, CH7xxx_TPCP, tpcp);
ch7xxx_write(dev_priv, CH7xxx_TPD, tpd);
ch7xxx_write(dev_priv, CH7xxx_TPVT, 0x30);
ch7xxx_write(dev_priv, CH7xxx_TLPF, tlpf);
ch7xxx_write(dev_priv, CH7xxx_TCT, 0x00);
ch7xxx_read(dev_priv, CH7xxx_IDF, &idf);
idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
if (mode->Flags & V_PHSYNC)
idf |= CH7xxx_IDF_HSP;
@ -193,87 +229,69 @@ static void ch7xxxMode(I2CDevPtr d, DisplayModePtr mode)
if (mode->Flags & V_PVSYNC)
idf |= CH7xxx_IDF_HSP;
/* setup PM Registers */
pm &= ~CH7xxx_PM_FPD;
pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
/* cm |= 1; */
ch7xxxWriteByte(ch7xxx, CH7xxx_CM, cm);
ch7xxxWriteByte(ch7xxx, CH7xxx_TPCP, tpcp);
ch7xxxWriteByte(ch7xxx, CH7xxx_TPD, tpd);
ch7xxxWriteByte(ch7xxx, CH7xxx_TPF, tpf);
ch7xxxWriteByte(ch7xxx, CH7xxx_TPF, idf);
ch7xxxWriteByte(ch7xxx, CH7xxx_PM, pm);
#endif
ch7xxx_write(dev_priv, CH7xxx_IDF, idf);
}
/* set the CH7xxx power state */
static void ch7xxxPower(I2CDevPtr d, Bool On)
static void
ch7xxx_dpms(I2CDevPtr d, int mode)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
int ret;
unsigned char ch;
struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
ret = ch7xxxReadByte(ch7xxx, CH7xxx_PM, &ch);
if (ret == FALSE)
return;
xf86DrvMsg(ch7xxx->d.pI2CBus->scrnIndex, X_ERROR,
"ch7xxx pm is %02X\n", ch);
#if 0
ret = ch7xxxReadByte(ch7xxx, CH7xxx_REG8, &ch);
if (ret)
return;
if (On)
ch |= CH7xxx_8_PD;
if (mode == DPMSModeOn)
ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
else
ch &= ~CH7xxx_8_PD;
ch7xxxWriteByte(ch7xxx, CH7xxx_REG8, ch);
#endif
ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_FPD);
}
static void ch7xxxPrintRegs(I2CDevPtr d)
static void
ch7xxx_dump_regs(I2CDevPtr d)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
int i;
ch7xxxSaveRegs(d);
for (i = 0; i < CH7xxx_NUM_REGS; i++) {
if (( i % 8 ) == 0 )
ErrorF("\n %02X: ", i);
ErrorF("%02X ", ch7xxx->ModeReg.regs[i]);
ErrorF("%02X ", dev_priv->ModeReg.regs[i]);
}
}
static void ch7xxxSaveRegs(I2CDevPtr d)
static void
ch7xxx_save(I2CDevPtr d)
{
CH7xxxPtr ch7xxx = CH7PTR(d);
int ret;
int i;
struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
for (i = 0; i < CH7xxx_NUM_REGS; i++) {
ret = ch7xxxReadByte(ch7xxx, i, &ch7xxx->SavedReg.regs[i]);
if (ret == FALSE)
break;
}
ch7xxx_read(dev_priv, CH7xxx_TCTL, &dev_priv->save_TCTL);
ch7xxx_read(dev_priv, CH7xxx_TPCP, &dev_priv->save_TPCP);
ch7xxx_read(dev_priv, CH7xxx_TPD, &dev_priv->save_TPD);
ch7xxx_read(dev_priv, CH7xxx_TPVT, &dev_priv->save_TPVT);
ch7xxx_read(dev_priv, CH7xxx_TLPF, &dev_priv->save_TLPF);
ch7xxx_read(dev_priv, CH7xxx_PM, &dev_priv->save_PM);
ch7xxx_read(dev_priv, CH7xxx_IDF, &dev_priv->save_IDF);
}
memcpy(ch7xxx->ModeReg.regs, ch7xxx->SavedReg.regs, CH7xxx_NUM_REGS);
static void
ch7xxx_restore(I2CDevPtr d)
{
struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr;
return;
ch7xxx_write(dev_priv, CH7xxx_TCTL, dev_priv->save_TCTL);
ch7xxx_write(dev_priv, CH7xxx_TPCP, dev_priv->save_TPCP);
ch7xxx_write(dev_priv, CH7xxx_TPD, dev_priv->save_TPD);
ch7xxx_write(dev_priv, CH7xxx_TPVT, dev_priv->save_TPVT);
ch7xxx_write(dev_priv, CH7xxx_TLPF, dev_priv->save_TLPF);
ch7xxx_write(dev_priv, CH7xxx_IDF, dev_priv->save_IDF);
ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM);
}
I830I2CVidOutputRec CH7xxxVidOutput = {
ch7xxxDetect,
ch7xxxInit,
ch7xxxModeValid,
ch7xxxMode,
ch7xxxPower,
ch7xxxPrintRegs,
ch7xxxSaveRegs,
NULL,
.init = ch7xxx_init,
.detect = ch7xxx_detect,
.mode_valid = ch7xxx_mode_valid,
.mode_set = ch7xxx_mode_set,
.dpms = ch7xxx_dpms,
.dump_regs = ch7xxx_dump_regs,
.save = ch7xxx_save,
.restore = ch7xxx_restore,
};

View File

@ -29,7 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CH7xxx_REG_VID 0x4a
#define CH7xxx_REG_DID 0x4b
#define CH7011_VID 0x83
#define CH7011_VID 0x83 /* 7010 as well */
#define CH7009A_VID 0x84
#define CH7009B_VID 0x85
#define CH7301_VID 0x95
@ -39,18 +39,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CH7xxx_NUM_REGS 0x4c
typedef struct _CH7xxxSaveRec {
CARD8 regs[CH7xxx_NUM_REGS];
} CH7xxxSaveRec;
typedef struct {
I2CDevRec d;
CH7xxxSaveRec SavedReg;
CH7xxxSaveRec ModeReg;
} CH7xxxRec, *CH7xxxPtr;
#define CH7PTR(d) ((CH7xxxPtr)(d->DriverPrivate.ptr))
#define CH7xxx_CM 0x1C
#define CH7xxx_CM_XCM (1<<0)
#define CH7xxx_CM_MCP (1<<2)
@ -65,11 +53,12 @@ typedef struct {
#define CH7301_DAC_CNTL 0x21
#define CH7301_HOTPLUG 0x23
#define CH7xxx_TCTL 0x31
#define CH7xxx_TVCO 0x32
#define CH7xxx_TPCP 0x33
#define CH7xxx_TPD 0x34
#define CH7xxx_TPVT 0x35
#define CH7xxx_TPF 0x36
#define CH7301_TCT 0x37
#define CH7xxx_TLPF 0x36
#define CH7xxx_TCT 0x37
#define CH7301_TEST_PATTERN 0x48
#define CH7xxx_PM 0x49

View File

@ -3,14 +3,14 @@
#define I2C_VID_H
typedef struct _I830I2CVidOutputRec {
void *(*Detect)(I2CBusPtr b, I2CSlaveAddr addr);
Bool (*Init)(I2CDevPtr d);
ModeStatus (*ModeValid)(I2CDevPtr d, DisplayModePtr mode);
void (*Mode)(I2CDevPtr d, DisplayModePtr mode);
void (*Power)(I2CDevPtr d, Bool On);
void (*PrintRegs)(I2CDevPtr d);
void (*SaveRegs)(I2CDevPtr d);
void (*RestoreRegs)(I2CDevPtr d);
void *(*init)(I2CBusPtr b, I2CSlaveAddr addr);
xf86OutputStatus (*detect)(I2CDevPtr d);
ModeStatus (*mode_valid)(I2CDevPtr d, DisplayModePtr mode);
void (*mode_set)(I2CDevPtr d, DisplayModePtr mode);
void (*dpms)(I2CDevPtr d, int mode);
void (*dump_regs)(I2CDevPtr d);
void (*save)(I2CDevPtr d);
void (*restore)(I2CDevPtr d);
} I830I2CVidOutputRec, *I830I2CVidOutputPtr;
#endif

View File

@ -962,7 +962,6 @@ void
i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int o, pipe;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
@ -970,54 +969,27 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
for (o = 0; o < xf86_config->num_output; o++)
{
xf86OutputPtr output = xf86_config->output[o];
if (!output->crtc)
if (!output->crtc) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling output %s\n",
output->name);
(*output->funcs->dpms)(output, DPMSModeOff);
}
}
/* Now, any unused plane, pipe, and DPLL (FIXME: except for DVO, i915
* internal TV) should have no outputs trying to pull data out of it, so
* we're ready to turn those off.
*/
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
xf86CrtcPtr crtc = xf86_config->crtc[pipe];
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
int dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
int pipeconf_reg = pipe == 0 ? PIPEACONF : PIPEBCONF;
int dpll_reg = pipe == 0 ? DPLL_A : DPLL_B;
CARD32 dspcntr, pipeconf, dpll;
char *pipe_name = pipe == 0 ? "A" : "B";
if (crtc->enabled)
continue;
dspcntr = INREG(dspcntr_reg);
if (dspcntr & DISPLAY_PLANE_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling plane %s\n",
if (!crtc->enabled) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling CRTC %s\n",
pipe_name);
OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
crtc->funcs->dpms(crtc, DPMSModeOff);
/* Wait for vblank for the disable to take effect */
i830WaitForVblank(pScrn);
memset(&crtc->curMode, 0, sizeof(crtc->curMode));
}
pipeconf = INREG(pipeconf_reg);
if (pipeconf & PIPEACONF_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling pipe %s\n",
pipe_name);
OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
}
dpll = INREG(dpll_reg);
if (dpll & DPLL_VCO_ENABLE) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling DPLL %s\n",
pipe_name);
OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
}
memset(&crtc->curMode, 0, sizeof(crtc->curMode));
}
}
@ -1041,6 +1013,7 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
TRUE);
if (!ok)
goto done;
crtc->desiredMode = *pMode;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Mode bandwidth is %d Mpixel/s\n",

View File

@ -1841,8 +1841,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
#endif
pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
if (pScrn->displayWidth * pI830->cpp > 8192) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support frame buffer stride > 8K > DRI.\n");
if (!IS_I965G(pI830) && pScrn->displayWidth * pI830->cpp > 8192) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Cannot support DRI with frame buffer stride > 8K.\n");
pI830->disableTiling = TRUE;
pI830->directRenderingDisabled = TRUE;
}
@ -3178,6 +3179,8 @@ I830EnterVT(int scrnIndex, int flags)
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
i830DisableUnusedFunctions(pScrn);
for (i = 0; i < xf86_config->num_crtc; i++)
{
xf86CrtcPtr crtc = xf86_config->crtc[i];
@ -3193,8 +3196,6 @@ I830EnterVT(int scrnIndex, int flags)
i830PipeSetBase(crtc, crtc->x, crtc->y);
}
i830DisableUnusedFunctions(pScrn);
i830DumpRegs (pScrn);
i830DescribeOutputConfiguration(pScrn);

View File

@ -62,12 +62,13 @@ i830_dvo_dpms(xf86OutputPtr output, int mode)
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
void * dev_priv = intel_output->i2c_drv->dev_priv;
if (mode == DPMSModeOn) {
OUTREG(DVOC, INREG(DVOC) | DVO_ENABLE);
(*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, TRUE);
(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
} else {
(*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, FALSE);
(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
}
}
@ -78,6 +79,7 @@ i830_dvo_save(xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
void * dev_priv = intel_output->i2c_drv->dev_priv;
/* Each output should probably just save the registers it touches, but for
* now, use more overkill.
@ -86,7 +88,7 @@ i830_dvo_save(xf86OutputPtr output)
pI830->saveDVOB = INREG(DVOB);
pI830->saveDVOC = INREG(DVOC);
(*intel_output->i2c_drv->vid_rec->SaveRegs)(intel_output->i2c_drv->dev_priv);
(*intel_output->i2c_drv->vid_rec->save)(dev_priv);
}
static void
@ -95,28 +97,27 @@ i830_dvo_restore(xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
void * dev_priv = intel_output->i2c_drv->dev_priv;
OUTREG(DVOA, pI830->saveDVOA);
OUTREG(DVOB, pI830->saveDVOB);
OUTREG(DVOC, pI830->saveDVOC);
(*intel_output->i2c_drv->vid_rec->RestoreRegs)(intel_output->i2c_drv->dev_priv);
(*intel_output->i2c_drv->vid_rec->restore)(dev_priv);
}
static int
i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
I830OutputPrivatePtr intel_output = output->driver_private;
void *dev_priv = intel_output->i2c_drv->dev_priv;
if (pMode->Flags & V_DBLSCAN)
return MODE_NO_DBLESCAN;
/* XXX: Validate clock range */
if ((*intel_output->i2c_drv->vid_rec->ModeValid)(intel_output->i2c_drv->dev_priv, pMode))
return MODE_OK;
else
return MODE_BAD;
return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode);
}
static Bool
@ -141,8 +142,8 @@ i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
CARD32 dvo;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
intel_output->i2c_drv->vid_rec->Mode(intel_output->i2c_drv->dev_priv,
mode);
intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv,
mode);
/* Save the data order, since I don't know what it should be set to. */
dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
@ -176,7 +177,10 @@ i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
static xf86OutputStatus
i830_dvo_detect(xf86OutputPtr output)
{
return XF86OutputStatusUnknown;
I830OutputPrivatePtr intel_output = output->driver_private;
void *dev_priv = intel_output->i2c_drv->dev_priv;
return intel_output->i2c_drv->vid_rec->detect(dev_priv);
}
static Bool
@ -198,7 +202,7 @@ I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
if (drv->vid_rec != NULL)
ret_ptr = drv->vid_rec->Detect(pI2CBus, drv->address);
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
drv->dev_priv = ret_ptr;

View File

@ -272,31 +272,21 @@ i830I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
CARD32 val, tristate = 0;
CARD32 val;
val = INREG(b->DriverPrivate.uval);
/* If we've released either of the lines from holding low, tristate them
* so that we can successfully read. Some hardware fails to read low
* values driven by slaves when our master is not tri-stated, while other
* chips succeed.
/*
* to read valid data, we must have written a 1 to
* the associated bit. Writing a 1 is done by
* tri-stating the bus in PutBits, so we needn't make
* sure that is true here
*/
if ((val & GPIO_DATA_DIR_OUT) && (val & GPIO_DATA_VAL_OUT))
tristate |= GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
if ((val & GPIO_CLOCK_DIR_OUT) && (val & GPIO_CLOCK_VAL_OUT))
tristate |= GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
if (tristate) {
OUTREG(b->DriverPrivate.uval, tristate);
val = INREG(b->DriverPrivate.uval);
}
*data = (val & GPIO_DATA_VAL_IN) != 0;
*clock = (val & GPIO_CLOCK_VAL_IN) != 0;
#if I2C_DEBUG
ErrorF("Getting I2C: %c %c\n",
ErrorF("Getting %s: %c %c\n", b->BusName,
*clock ? '^' : 'v',
*data ? '^' : 'v');
#endif
@ -306,6 +296,7 @@ static void
i830I2CPutBits(I2CBusPtr b, int clock, int data)
{
CARD32 reserved = 0;
CARD32 data_bits, clock_bits;
#if I2C_DEBUG
int cur_clock, cur_data;
@ -318,11 +309,11 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data)
i830I2CGetBits(b, &cur_clock, &cur_data);
if (first) {
ErrorF("I2C Debug: C D C D\n");
ErrorF("%s Debug: C D C D\n", b->BusName);
first = FALSE;
}
ErrorF("Setting I2C 0x%08x to: %c %c\n",
ErrorF("Setting %s 0x%08x to: %c %c\n", b->BusName,
(int)b->DriverPrivate.uval,
clock ? '^' : 'v',
data ? '^' : 'v');
@ -334,17 +325,19 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data)
(GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE);
}
OUTREG(b->DriverPrivate.uval,
reserved |
(data ? GPIO_DATA_VAL_OUT : 0) |
(clock ? GPIO_CLOCK_VAL_OUT : 0) |
GPIO_CLOCK_DIR_OUT |
GPIO_DATA_DIR_OUT |
GPIO_CLOCK_DIR_MASK |
GPIO_CLOCK_VAL_MASK |
GPIO_DATA_DIR_MASK |
GPIO_DATA_VAL_MASK);
/* data or clock == 1 means to tristate the bus. otherwise, drive it low */
if (data)
data_bits = GPIO_DATA_DIR_IN|GPIO_DATA_DIR_MASK;
else
data_bits = GPIO_DATA_DIR_OUT|GPIO_DATA_DIR_MASK|GPIO_DATA_VAL_MASK;
if (clock)
clock_bits = GPIO_CLOCK_DIR_IN|GPIO_CLOCK_DIR_MASK;
else
clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK;
OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits);
}
#endif
/* the i830 has a number of I2C Buses */

View File

@ -835,9 +835,10 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
int c;
int width, height;
int mmWidth, mmHeight;
/*
* Compute width of screen
* Compute size of screen
*/
width = 0; height = 0;
for (c = 0; c < config->num_crtc; c++)
@ -854,14 +855,19 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
if (width && height)
{
int mmWidth, mmHeight;
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
if (width != pScreen->width)
mmWidth = mmWidth * width / pScreen->width;
if (height != pScreen->height)
mmHeight = mmHeight * height / pScreen->height;
/*
* Compute physical size of screen
*/
if (monitorResolution)
{
mmWidth = width * 25.4 / monitorResolution;
mmHeight = height * 25.4 / monitorResolution;
}
else
{
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);

View File

@ -777,7 +777,7 @@ i830_tv_init(ScrnInfoPtr pScrn)
return;
}
dev_priv = (struct i830_tv_priv *) (intel_output + 1);
intel_output->type = I830_OUTPUT_SDVO;
intel_output->type = I830_OUTPUT_TVOUT;
intel_output->dev_priv = dev_priv;
dev_priv->type = TV_TYPE_UNKNOWN;

View File

@ -555,16 +555,20 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
for (mode = pScrn->modes; mode; mode = mode->next)
if (xf86ModesEqual (mode, &crtc->desiredMode))
break;
/* For some reason, pScrn->modes is circular, unlike the other mode lists.
* How great is that?
*/
for (last = pScrn->modes; last && last->next; last = last->next);
last->next = pScrn->modes;
pScrn->modes->prev = last;
if (mode)
while (pScrn->modes != mode)
pScrn->modes = pScrn->modes->next;
if (pScrn->modes != NULL) {
/* For some reason, pScrn->modes is circular, unlike the other mode
* lists. How great is that?
*/
for (last = pScrn->modes; last && last->next; last = last->next)
;
last->next = pScrn->modes;
pScrn->modes->prev = last;
if (mode) {
while (pScrn->modes != mode)
pScrn->modes = pScrn->modes->next;
}
}
pScrn->currentMode = pScrn->modes;
}

View File

@ -142,7 +142,9 @@ static CARD32 I915GetBlendCntl(int op, PicturePtr pMask, CARD32 dst_format)
* the source blend factor is 0, and the source blend value is the mask
* channels multiplied by the source picture's alpha.
*/
if (pMask && pMask->componentAlpha && I915BlendOp[op].src_alpha) {
if (pMask && pMask->componentAlpha && PICT_FORMAT_RGB(pMask->format) &&
I915BlendOp[op].src_alpha)
{
if (dblend == BLENDFACT_SRC_ALPHA) {
dblend = BLENDFACT_SRC_COLR;
} else if (dblend == BLENDFACT_INV_SRC_ALPHA) {
@ -228,7 +230,9 @@ I915EXACheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
/* Check for unsupported compositing operations. */
if (op >= sizeof(I915BlendOp) / sizeof(I915BlendOp[0]))
I830FALLBACK("Unsupported Composite op 0x%x\n", op);
if (pMaskPicture != NULL && pMaskPicture->componentAlpha) {
if (pMaskPicture != NULL && pMaskPicture->componentAlpha &&
PICT_FORMAT_RGB(pMaskPicture->format))
{
/* Check if it's component alpha that relies on a source alpha and on
* the source value. We can only get one of those into the single
* source value that we get to blend with.
@ -463,7 +467,7 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
if (PICT_FORMAT_A(pMaskPicture->format) == 0)
i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
/* If component alpha is set in the mask and the blend operation
/* If component alpha is active in the mask and the blend operation
* uses the source alpha, then we know we don't need the source
* value (otherwise we would have hit a fallback earlier), so we
* provide the source alpha (src.A * mask.X) as output color.
@ -472,7 +476,9 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
* is unused.. Otherwise, we provide the non-CA source value
* (src.X * mask.A).
*/
if (pMaskPicture->componentAlpha) {
if (pMaskPicture->componentAlpha &&
PICT_FORMAT_RGB(pMaskPicture->format))
{
if (I915BlendOp[op].src_alpha) {
i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W),
i915_fs_operand_reg(FS_R1));

View File

@ -60,7 +60,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
DrawablePtr pDraw)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 format, ms3, s2;
CARD32 format, ms3, s2, s5;
BoxPtr pbox;
int nbox, dxo, dyo;
Bool planar;
@ -103,7 +103,7 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
/* draw rect -- just clipping */
OUT_RING(_3DSTATE_DRAW_RECT_CMD);
OUT_RING(0x00000000); /* flags */
OUT_RING(DRAW_DITHER_OFS_X(pDraw->x & 3)| DRAW_DITHER_OFS_Y(pDraw->y & 3)); /* flags */
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING((pScrn->virtualX - 1) |
(pScrn->virtualY - 1) << 16); /* ymax, xmax */
@ -131,7 +131,10 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
OUT_RING(s2);
OUT_RING((1 << S4_POINT_WIDTH_SHIFT) | S4_LINE_WIDTH_ONE |
S4_CULLMODE_NONE | S4_VFMT_XY);
OUT_RING(0x00000000); /* S5 - enable bits */
s5 = 0x0;
if (pI830->cpp == 2)
s5 |= S5_COLOR_DITHER_ENABLE;
OUT_RING(s5); /* S5 - enable bits */
OUT_RING((2 << S6_DEPTH_TEST_FUNC_SHIFT) |
(2 << S6_CBUF_SRC_BLEND_FACT_SHIFT) |
(1 << S6_CBUF_DST_BLEND_FACT_SHIFT) | S6_COLOR_WRITE_ENABLE |

View File

@ -3,7 +3,7 @@
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@ -I$(srcdir)/../
sil164_la_LTLIBRARIES = sil164.la
sil164_la_LDFLAGS = -module -avoid-version

View File

@ -26,22 +26,25 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
#include "i830_xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "../i2c_vid.h"
#include "sil164.h"
#include "sil164_reg.h"
static void
sil164PrintRegs(I2CDevPtr d);
static void
sil164Power(I2CDevPtr d, Bool On);
static Bool
sil164ReadByte(SIL164Ptr sil, int addr, CARD8 *ch)
{
@ -68,7 +71,7 @@ sil164WriteByte(SIL164Ptr sil, int addr, CARD8 ch)
/* Silicon Image 164 driver for chip on i2c bus */
static void *
sil164Detect(I2CBusPtr b, I2CSlaveAddr addr)
sil164_init(I2CBusPtr b, I2CSlaveAddr addr)
{
/* this will detect the SIL164 chip on the specified i2c bus */
SIL164Ptr sil;
@ -120,26 +123,33 @@ out:
return NULL;
}
static Bool
sil164Init(I2CDevPtr d)
static xf86OutputStatus
sil164_detect(I2CDevPtr d)
{
/* not much to do */
return TRUE;
SIL164Ptr sil = SILPTR(d);
CARD8 reg9;
sil164ReadByte(sil, SIL164_REG9, &reg9);
if (reg9 & SIL164_9_HTPLG)
return XF86OutputStatusConnected;
else
return XF86OutputStatusDisconnected;
}
static ModeStatus
sil164ModeValid(I2CDevPtr d, DisplayModePtr mode)
sil164_mode_valid(I2CDevPtr d, DisplayModePtr mode)
{
return MODE_OK;
}
static void
sil164Mode(I2CDevPtr d, DisplayModePtr mode)
sil164_mode_set(I2CDevPtr d, DisplayModePtr mode)
{
sil164Power(d, TRUE);
sil164PrintRegs(d);
/* As long as the basics are set up, since we don't have clock dependencies
* in the mode setup, we can just leave the registers alone and everything
* will work fine.
*/
/* recommended programming sequence from doc */
/*sil164WriteByte(sil, 0x08, 0x30);
sil164WriteByte(sil, 0x09, 0x00);
@ -152,7 +162,7 @@ sil164Mode(I2CDevPtr d, DisplayModePtr mode)
/* set the SIL164 power state */
static void
sil164Power(I2CDevPtr d, Bool On)
sil164_dpms(I2CDevPtr d, int mode)
{
SIL164Ptr sil = SILPTR(d);
int ret;
@ -162,7 +172,7 @@ sil164Power(I2CDevPtr d, Bool On)
if (ret == FALSE)
return;
if (On)
if (mode == DPMSModeOn)
ch |= SIL164_8_PD;
else
ch &= ~SIL164_8_PD;
@ -173,7 +183,7 @@ sil164Power(I2CDevPtr d, Bool On)
}
static void
sil164PrintRegs(I2CDevPtr d)
sil164_dump_regs(I2CDevPtr d)
{
SIL164Ptr sil = SILPTR(d);
CARD8 val;
@ -193,7 +203,7 @@ sil164PrintRegs(I2CDevPtr d)
}
static void
sil164SaveRegs(I2CDevPtr d)
sil164_save(I2CDevPtr d)
{
SIL164Ptr sil = SILPTR(d);
@ -210,7 +220,7 @@ sil164SaveRegs(I2CDevPtr d)
}
static void
sil164RestoreRegs(I2CDevPtr d)
sil164_restore(I2CDevPtr d)
{
SIL164Ptr sil = SILPTR(d);
@ -224,12 +234,12 @@ sil164RestoreRegs(I2CDevPtr d)
I830I2CVidOutputRec SIL164VidOutput = {
sil164Detect,
sil164Init,
sil164ModeValid,
sil164Mode,
sil164Power,
sil164PrintRegs,
sil164SaveRegs,
sil164RestoreRegs,
.init = sil164_init,
.detect = sil164_detect,
.mode_valid = sil164_mode_valid,
.mode_set = sil164_mode_set,
.dpms = sil164_dpms,
.dump_regs = sil164_dump_regs,
.save = sil164_save,
.restore = sil164_restore,
};