diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/ch7xxx/Makefile.am | 16 | ||||
-rw-r--r-- | src/ch7xxx/ch7xxx.c | 272 | ||||
-rw-r--r-- | src/ch7xxx/ch7xxx.h | 33 | ||||
-rw-r--r-- | src/ch7xxx/ch7xxx_module.c | 36 | ||||
-rw-r--r-- | src/ch7xxx/ch7xxx_reg.h | 91 | ||||
-rw-r--r-- | src/i2c_vid.h | 16 | ||||
-rw-r--r-- | src/i810_reg.h | 26 | ||||
-rw-r--r-- | src/i830.h | 9 | ||||
-rw-r--r-- | src/i830_display.c | 43 | ||||
-rw-r--r-- | src/i830_driver.c | 36 | ||||
-rw-r--r-- | src/i830_dvo.c | 84 | ||||
-rw-r--r-- | src/sil164/Makefile.am | 16 | ||||
-rw-r--r-- | src/sil164/sil164.c | 192 | ||||
-rw-r--r-- | src/sil164/sil164.h | 33 | ||||
-rw-r--r-- | src/sil164/sil164_module.c | 36 | ||||
-rw-r--r-- | src/sil164/sil164_reg.h | 75 |
18 files changed, 995 insertions, 24 deletions
diff --git a/configure.ac b/configure.ac index deb99c21..5c9291bf 100644 --- a/configure.ac +++ b/configure.ac @@ -125,5 +125,7 @@ AC_OUTPUT([ src/Makefile src/xvmc/Makefile src/bios_reader/Makefile + src/ch7xxx/Makefile + src/sil164/Makefile man/Makefile ]) diff --git a/src/Makefile.am b/src/Makefile.am index f8aaad1d..50d0ad1a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -SUBDIRS = xvmc bios_reader +SUBDIRS = xvmc bios_reader ch7xxx sil164 # this is obnoxious: # -module lets us name the module exactly how we want # -avoid-version prevents gratuitous .0.0.0 version numbers on the end @@ -54,6 +54,7 @@ i810_drv_la_SOURCES = \ i830_display.c \ i830_display.h \ i830_driver.c \ + i830_dvo.c \ i830.h \ i830_gtf.c \ i830_i2c.c \ diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am new file mode 100644 index 00000000..645ac692 --- /dev/null +++ b/src/ch7xxx/Makefile.am @@ -0,0 +1,16 @@ +# this is obnoxious: +# -module lets us name the module exactly how we want +# -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@ + +ch7xxx_la_LTLIBRARIES = ch7xxx.la +ch7xxx_la_LDFLAGS = -module -avoid-version +ch7xxx_ladir = @moduledir@/drivers + +ch7xxx_la_SOURCES = \ + ch7xxx.c \ + ch7xxx_module.c \ + ch7xxx.h \ + ch7xxx_reg.h diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c new file mode 100644 index 00000000..77c49b53 --- /dev/null +++ b/src/ch7xxx/ch7xxx.c @@ -0,0 +1,272 @@ +/************************************************************************** + +Copyright © 2006 Dave Airlie + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "miscstruct.h" +#include "xf86i2c.h" + +#include <string.h> + +#include "../i2c_vid.h" +#include "ch7xxx.h" +#include "ch7xxx_reg.h" + +static void ch7xxxSaveRegs(void *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) +{ + 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; + } + 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; +} + +/* Ch7xxxicon Image 164 driver for chip on i2c bus */ +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) +{ + CH7xxxPtr ch7xxx = CH7PTR(d); + + /* not much to do */ + return TRUE; +} + +static ModeStatus ch7xxxModeValid(I2CDevPtr d, DisplayModePtr mode) +{ + CH7xxxPtr ch7xxx = CH7PTR(d); + + return MODE_OK; +} + +static void ch7xxxMode(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; + 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) { + tpcp = 0x08; + tpd = 0x16; + tpf = 0x60; + } else { + tpcp = 0x06; + tpd = 0x26; + tpf = 0xa0; + } + + idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP); + if (mode->Flags & V_PHSYNC) + idf |= CH7xxx_IDF_HSP; + + 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 + /* don't do much */ + return; +} + +/* set the CH7xxx power state */ +static void ch7xxxPower(I2CDevPtr d, Bool On) +{ + CH7xxxPtr ch7xxx = CH7PTR(d); + int ret; + unsigned char ch; + + + 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; + else + ch &= ~CH7xxx_8_PD; + + ch7xxxWriteByte(ch7xxx, CH7xxx_REG8, ch); +#endif + return; +} + +static void ch7xxxPrintRegs(I2CDevPtr d) +{ + CH7xxxPtr ch7xxx = CH7PTR(d); + 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]); + + } +} + +static void ch7xxxSaveRegs(void *d) +{ + CH7xxxPtr ch7xxx = CH7PTR(((I2CDevPtr)d)); + int ret; + int i; + + for (i = 0; i < CH7xxx_NUM_REGS; i++) { + ret = ch7xxxReadByte(ch7xxx, i, &ch7xxx->SavedReg.regs[i]); + if (ret == FALSE) + break; + } + + memcpy(ch7xxx->ModeReg.regs, ch7xxx->SavedReg.regs, CH7xxx_NUM_REGS); + + return; +} + +I830I2CVidOutputRec CH7xxxVidOutput = { + ch7xxxDetect, + ch7xxxInit, + ch7xxxModeValid, + ch7xxxMode, + ch7xxxPower, + ch7xxxPrintRegs, + ch7xxxSaveRegs, + NULL, +}; diff --git a/src/ch7xxx/ch7xxx.h b/src/ch7xxx/ch7xxx.h new file mode 100644 index 00000000..5ae0ab8c --- /dev/null +++ b/src/ch7xxx/ch7xxx.h @@ -0,0 +1,33 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef CH7xxx_H +#define CH7xxx_H + +#define CH7xxx_ADDR_1 0x76 + +#define CH7xxx_SYMBOL_LIST "CH7xxxVidOutput" + +#endif diff --git a/src/ch7xxx/ch7xxx_module.c b/src/ch7xxx/ch7xxx_module.c new file mode 100644 index 00000000..19dc6cd1 --- /dev/null +++ b/src/ch7xxx/ch7xxx_module.c @@ -0,0 +1,36 @@ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" + +static MODULESETUPPROTO(ch7xxxSetup); + +static XF86ModuleVersionInfo ch7xxxVersRec = + { + "ch7xxx", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + { 0,0,0,0 } + }; + +_X_EXPORT XF86ModuleData ch7xxxModuleData = { + &ch7xxxVersRec, + ch7xxxSetup, + NULL +}; + +static pointer +ch7xxxSetup(pointer module, pointer opts, int *errmaj, int *errmin) { + return (pointer)1; +} diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h new file mode 100644 index 00000000..59de13b8 --- /dev/null +++ b/src/ch7xxx/ch7xxx_reg.h @@ -0,0 +1,91 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef CH7xxx_REG_H +#define CH7xxx_REG_H + +#define CH7xxx_REG_VID 0x4a +#define CH7xxx_REG_DID 0x4b + + +#define CH7011_VID 0x83 +#define CH7009A_VID 0x84 +#define CH7009B_VID 0x85 +#define CH7301_VID 0x95 + +#define CH7xxx_VID 0x84 +#define CH7xxx_DID 0x17 + +#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) +#define CH7xxx_INPUT_CLOCK 0x1D +#define CH7xxx_GPIO 0x1E +#define CH7xxx_IDF 0x1F + +#define CH7xxx_IDF_HSP (1<<3) +#define CH7xxx_IDF_VSP (1<<4) + +#define CH7301_CONNECTION_DETECT 0x20 +#define CH7301_DAC_CNTL 0x21 +#define CH7301_HOTPLUG 0x23 +#define CH7xxx_TCTL 0x31 +#define CH7xxx_TPCP 0x33 +#define CH7xxx_TPD 0x34 +#define CH7xxx_TPVT 0x35 +#define CH7xxx_TPF 0x36 +#define CH7301_TCT 0x37 +#define CH7301_TEST_PATTERN 0x48 +#define CH7xxx_PM 0x49 + +#define CH7xxx_PM_FPD (1<<0) +#define CH7301_PM_DACPD0 (1<<1) +#define CH7301_PM_DACPD1 (1<<2) +#define CH7301_PM_DACPD2 (1<<3) +#define CH7xxx_PM_DVIL (1<<6) +#define CH7xxx_PM_DVIP (1<<7) + +#define CH7301_SYNC_POLARITY 0x56 + +#define CH7301_SYNC_RGB_YUV (1<<0) +#define CH7301_SYNC_POL_DVI (1<<5) + + + +#endif diff --git a/src/i2c_vid.h b/src/i2c_vid.h new file mode 100644 index 00000000..fbf72842 --- /dev/null +++ b/src/i2c_vid.h @@ -0,0 +1,16 @@ +/* this needs to go in the server */ +#ifndef I2C_VID_H +#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)(void *d); + void (*RestoreRegs)(I2CDevPtr d); +} I830I2CVidOutputRec, *I830I2CVidOutputPtr; + +#endif diff --git a/src/i810_reg.h b/src/i810_reg.h index e8462f9d..275d858c 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -823,11 +823,35 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define DVOA 0x61120 #define DVOB 0x61140 #define DVOC 0x61160 -#define DVO_ENABLE (1<<31) +#define DVO_ENABLE (1 << 31) +#define DVO_PIPE_B_SELECT (1 << 30) +#define DVO_PIPE_STALL_UNUSED (0 << 28) +#define DVO_PIPE_STALL (1 << 28) +#define DVO_PIPE_STALL_TV (2 << 28) +#define DVO_USE_VGA_SYNC (1 << 15) +#define DVO_DATA_ORDER_I740 (0 << 14) +#define DVO_DATA_ORDER_FP (1 << 14) +#define DVO_VSYNC_DISABLE (1 << 11) +#define DVO_HSYNC_DISABLE (1 << 10) +#define DVO_VSYNC_TRISTATE (1 << 9) +#define DVO_HSYNC_TRISTATE (1 << 8) +#define DVO_BORDER_ENABLE (1 << 7) +#define DVO_DATA_ORDER_GBRG (1 << 6) +#define DVO_DATA_ORDER_RGGB (0 << 6) +#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6) +#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6) +#define DVO_VSYNC_ACTIVE_HIGH (1 << 4) +#define DVO_HSYNC_ACTIVE_HIGH (1 << 3) +#define DVO_BLANK_ACTIVE_HIGH (1 << 2) +#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */ +#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */ +#define DVO_PRESERVE_MASK (0x7<<24) #define DVOA_SRCDIM 0x61124 #define DVOB_SRCDIM 0x61144 #define DVOC_SRCDIM 0x61164 +#define DVO_SRCDIM_HORIZONTAL_SHIFT 12 +#define DVO_SRCDIM_VERTICAL_SHIFT 0 #define LVDS 0x61180 # define LVDS_PORT_EN (1 << 31) @@ -70,6 +70,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "common.h" #include "i830_sdvo.h" +#include "i2c_vid.h" /* I830 Video BIOS support */ @@ -182,10 +183,8 @@ struct _I830DVODriver { char *fntablename; int address; const char **symbols; -#if 0 I830I2CVidOutputRec *vid_rec; -#endif - void *devpriv; + void *dev_priv; pointer modhandle; }; @@ -593,6 +592,10 @@ extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem); extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name); +/* i830_dvo.c */ +Bool I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus, + struct _I830DVODriver **retdrv); + /* i830_memory.c */ Bool I830BindAGPMemory(ScrnInfoPtr pScrn); Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); diff --git a/src/i830_display.c b/src/i830_display.c index d31c100b..b26c09f6 100644 --- a/src/i830_display.c +++ b/src/i830_display.c @@ -258,8 +258,8 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) CARD32 dpll = 0, fp = 0, temp; CARD32 htot, hblank, hsync, vtot, vblank, vsync, dspcntr; CARD32 pipesrc, dspsize, adpa; - CARD32 sdvob = 0, sdvoc= 0; - Bool ok, is_sdvo; + CARD32 sdvob = 0, sdvoc = 0, dvo = 0; + Bool ok, is_sdvo, is_dvo; int refclk, pixel_clock, sdvo_pixel_multiply; int outputs; DisplayModePtr pMasterMode = pMode; @@ -359,9 +359,16 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) /* We'll change how we control outputs soon, but to get the SDVO code up * and running, just check for these two possibilities. */ - is_sdvo = TRUE; + if (IS_I9XX(pI830)) { + is_sdvo = TRUE; + is_dvo = FALSE; + } else { + is_dvo = TRUE; + is_sdvo = FALSE; + } } else { is_sdvo = FALSE; + is_dvo = FALSE; } htot = (pMode->CrtcHDisplay - 1) | ((pMode->CrtcHTotal - 1) << 16); @@ -471,6 +478,27 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) else dpll |= PLL_REF_INPUT_DREFCLK; + if (is_dvo) { + dpll |= DPLL_DVO_HIGH_SPEED; + + /* Save the data order, since I don't know what it should be set to. */ + dvo = INREG(DVOB) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); + dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE; + + if (pipe == 1) + dvo |= DVO_PIPE_B_SELECT; + + if (pMode->Flags & V_PHSYNC) + dvo |= DVO_HSYNC_ACTIVE_HIGH; + if (pMode->Flags & V_PVSYNC) + dvo |= DVO_VSYNC_ACTIVE_HIGH; + + if (IS_I865G(pI830)) + dvo |= DVO_OUTPUT_SOURCE_SIZE_PIXELS; + + OUTREG(DVOB, dvo & ~DVO_ENABLE); + } + if (is_sdvo) { dpll |= DPLL_DVO_HIGH_SPEED; @@ -654,6 +682,15 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe) if (outputs & PIPE_CRT_ACTIVE) OUTREG(ADPA, adpa); + if (is_dvo) { + OUTREG(DVOB_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | + (pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT)); + /* OUTREG(DVOC_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | + (pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT)); */ + OUTREG(DVOB, dvo); + /* OUTREG(DVOC, dvoc); */ + } + if (is_sdvo) { OUTREG(SDVOB, sdvob); OUTREG(SDVOC, sdvoc); diff --git a/src/i830_driver.c b/src/i830_driver.c index ca87951a..501580d0 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1053,6 +1053,7 @@ I830SetupOutputBusses(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); int i = 0; + Bool ret; /* everyone has at least a single analog output */ pI830->output[i].type = I830_OUTPUT_ANALOG; @@ -1073,6 +1074,13 @@ I830SetupOutputBusses(ScrnInfoPtr pScrn) pI830->output[i].type = I830_OUTPUT_DVO; I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOD, "DVODDC_D"); I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E"); + ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus, + &pI830->output[i].i2c_drv); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n", + pI830->output[i].i2c_drv->modulename, + pI830->output[i].pI2CBus->DriverPrivate.uval); + } i++; break; case PCI_CHIP_E7221_G: @@ -1158,22 +1166,6 @@ I830DetectMonitors(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DDC DVO %d, %08lX\n", i, pI830->output[i].pDDCBus->DriverPrivate.uval); xf86PrintEDID(pI830->output[i].MonInfo); - -#if 0 - /* if we are on an i2C bus > 0 and we see a monitor - try to - * find a controller chip - */ - if (pI830->output[i].MonInfo) { - int ret; - ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus, - &pI830->output[i].i2c_drv); - if (ret==TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n", - pI830->output[i].i2c_drv->modulename, - pI830->output[i].pI2CBus->DriverPrivate.uval); - } - } -#endif break; case I830_OUTPUT_SDVO: if (pI830->output[i].sdvo_drv != NULL) { @@ -2769,6 +2761,12 @@ SaveHWState(ScrnInfoPtr pScrn) pI830->saveSWF[16] = INREG(SWF32); for (i = 0; i < pI830->num_outputs; i++) { + if (pI830->output[i].type == I830_OUTPUT_DVO && + pI830->output[i].i2c_drv != NULL) + { + pI830->output[i].i2c_drv->vid_rec->SaveRegs( + pI830->output[i].i2c_drv->dev_priv); + } if (pI830->output[i].type == I830_OUTPUT_SDVO && pI830->output[i].sdvo_drv != NULL) { @@ -2888,6 +2886,12 @@ RestoreHWState(ScrnInfoPtr pScrn) } for (i = 0; i < pI830->num_outputs; i++) { + if (pI830->output[i].type == I830_OUTPUT_DVO && + pI830->output[i].i2c_drv != NULL) + { + pI830->output[i].i2c_drv->vid_rec->RestoreRegs( + pI830->output[i].i2c_drv->dev_priv); + } if (pI830->output[i].type == I830_OUTPUT_SDVO && pI830->output[i].sdvo_drv != NULL) { diff --git a/src/i830_dvo.c b/src/i830_dvo.c new file mode 100644 index 00000000..b82eaee2 --- /dev/null +++ b/src/i830_dvo.c @@ -0,0 +1,84 @@ +/************************************************************************** + +Copyright 2006 Dave Airlie <airlied@linux.ie> + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 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 "i830.h" + +#include "sil164/sil164.h" +#include "ch7xxx/ch7xxx.h" + +static const char *SIL164Symbols[] = { + SIL164_SYMBOL_LIST +}; +static const char *CH7xxxSymbols[] = { + CH7xxx_SYMBOL_LIST +}; + +/* driver list */ +struct _I830DVODriver i830_dvo_drivers[] = +{ + { I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput", + (SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL}, + { I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput", + (CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL} +}; + +#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver)) + +Bool +I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus, + struct _I830DVODriver **retdrv) +{ + int i; + void *ret_ptr; + struct _I830DVODriver *drv; + + for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) { + drv = &i830_dvo_drivers[i]; + drv->modhandle = xf86LoadSubModule(pScrn, drv->modulename); + if (drv->modhandle == NULL) + continue; + + xf86LoaderReqSymLists(drv->symbols, NULL); + + ret_ptr = NULL; + drv->vid_rec = LoaderSymbol(drv->fntablename); + if (drv->vid_rec != NULL) + ret_ptr = drv->vid_rec->Detect(pI2CBus, drv->address); + + if (ret_ptr != NULL) { + drv->dev_priv = ret_ptr; + *retdrv = drv; + return TRUE; + } + xf86UnloadSubModule(drv->modhandle); + } + return FALSE; +} diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am new file mode 100644 index 00000000..bb84d036 --- /dev/null +++ b/src/sil164/Makefile.am @@ -0,0 +1,16 @@ +# this is obnoxious: +# -module lets us name the module exactly how we want +# -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@ + +sil164_la_LTLIBRARIES = sil164.la +sil164_la_LDFLAGS = -module -avoid-version +sil164_ladir = @moduledir@/drivers + +sil164_la_SOURCES = \ + sil164.c \ + sil164_module.c \ + sil164.h \ + sil164_reg.h diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c new file mode 100644 index 00000000..5e35323e --- /dev/null +++ b/src/sil164/sil164.c @@ -0,0 +1,192 @@ +/************************************************************************** + +Copyright © 2006 Dave Airlie + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86Resources.h" +#include "compiler.h" +#include "miscstruct.h" +#include "xf86i2c.h" + +#include "../i2c_vid.h" +#include "sil164.h" +#include "sil164_reg.h" + +static Bool sil164ReadByte(SIL164Ptr sil, int addr, unsigned char *ch) +{ + if (!xf86I2CReadByte(&(sil->d), addr, ch)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n", sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + return FALSE; + } + return TRUE; +} + +static Bool sil164WriteByte(SIL164Ptr sil, int addr, unsigned char ch) +{ + if (!xf86I2CWriteByte(&(sil->d), addr, ch)) { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, "Unable to write to %s Slave %d.\n", sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + return FALSE; + } + return TRUE; +} + +/* Silicon Image 164 driver for chip on i2c bus */ +static void *sil164Detect(I2CBusPtr b, I2CSlaveAddr addr) +{ + /* this will detect the SIL164 chip on the specified i2c bus */ + SIL164Ptr sil; + unsigned char ch; + + xf86DrvMsg(b->scrnIndex, X_ERROR, "detecting sil164\n"); + + sil = xcalloc(1, sizeof(SIL164Rec)); + if (sil == NULL) + return NULL; + + sil->d.DevName = "SIL164 TMDS Controller"; + sil->d.SlaveAddr = addr; + sil->d.pI2CBus = b; + sil->d.StartTimeout = b->StartTimeout; + sil->d.BitTimeout = b->BitTimeout; + sil->d.AcknTimeout = b->AcknTimeout; + sil->d.ByteTimeout = b->ByteTimeout; + sil->d.DriverPrivate.ptr = sil; + + if (!sil164ReadByte(sil, SIL164_VID_LO, &ch)) + goto out; + + if (ch!=(SIL164_VID & 0xFF)) + { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, "sil164 not detected got %d: from %s Slave %d.\n", ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + goto out; + } + + + if (!sil164ReadByte(sil, SIL164_DID_LO, &ch)) + goto out; + + if (ch!=(SIL164_DID & 0xFF)) + { + xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, "sil164 not detected got %d: from %s Slave %d.\n", ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); + goto out; + } + + + if (!xf86I2CDevInit(&(sil->d))) + { + goto out; + } + + return sil; + + out: + xfree(sil); + return NULL; +} + + +static Bool sil164Init(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + + /* not much to do */ + return TRUE; +} + +static ModeStatus sil164ModeValid(I2CDevPtr d, DisplayModePtr mode) +{ + SIL164Ptr sil = SILPTR(d); + + return MODE_OK; +} + +static void sil164Mode(I2CDevPtr d, DisplayModePtr mode) +{ + SIL164Ptr sil = SILPTR(d); + + /* don't do much */ + return; +} + +/* set the SIL164 power state */ +static void sil164Power(I2CDevPtr d, Bool On) +{ + SIL164Ptr sil = SILPTR(d); + int ret; + unsigned char ch; + + ret = sil164ReadByte(sil, SIL164_REG8, &ch); + if (ret == FALSE) + return; + + if (On) + ch |= SIL164_8_PD; + else + ch &= ~SIL164_8_PD; + + sil164WriteByte(sil, SIL164_REG8, ch); + return; +} + +static void sil164PrintRegs(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); +} + +static void sil164SaveRegs(I2CDevPtr d) +{ + SIL164Ptr sil = SILPTR(d); + + if (!sil164ReadByte(sil, SIL164_FREQ_LO, &sil->SavedReg.freq_lo)) + return; + + if (!sil164ReadByte(sil, SIL164_FREQ_HI, &sil->SavedReg.freq_hi)) + return; + + if (!sil164ReadByte(sil, SIL164_REG8, &sil->SavedReg.reg8)) + return; + + if (!sil164ReadByte(sil, SIL164_REG9, &sil->SavedReg.reg9)) + return; + + if (!sil164ReadByte(sil, SIL164_REGC, &sil->SavedReg.regc)) + return; + + return; + +} + +I830I2CVidOutputRec SIL164VidOutput = { + sil164Detect, + sil164Init, + sil164ModeValid, + sil164Mode, + sil164Power, + sil164PrintRegs, + sil164SaveRegs, + NULL, +}; diff --git a/src/sil164/sil164.h b/src/sil164/sil164.h new file mode 100644 index 00000000..ea5c4c9a --- /dev/null +++ b/src/sil164/sil164.h @@ -0,0 +1,33 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef SIL164_H +#define SIL164_H + +#define SIL164_ADDR_1 0x38 + +#define SIL164_SYMBOL_LIST "SIL164VidOutput" + +#endif diff --git a/src/sil164/sil164_module.c b/src/sil164/sil164_module.c new file mode 100644 index 00000000..6778e6a1 --- /dev/null +++ b/src/sil164/sil164_module.c @@ -0,0 +1,36 @@ +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86Module.h" + +static MODULESETUPPROTO(sil164Setup); + +static XF86ModuleVersionInfo sil164VersRec = + { + "sil164", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_NONE, + { 0,0,0,0 } + }; + +_X_EXPORT XF86ModuleData sil164ModuleData = { + &sil164VersRec, + sil164Setup, + NULL +}; + +static pointer +sil164Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + return (pointer)1; +} diff --git a/src/sil164/sil164_reg.h b/src/sil164/sil164_reg.h new file mode 100644 index 00000000..879363ca --- /dev/null +++ b/src/sil164/sil164_reg.h @@ -0,0 +1,75 @@ +/************************************************************************** + + Copyright 2006 Dave Airlie <airlied@linux.ie> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef SIL164_REG_H +#define SIL164_REG_H + +#define SIL164_VID 0x0001 +#define SIL164_DID 0x0006 + +#define SIL164_VID_LO 0x00 +#define SIL164_VID_HI 0x01 +#define SIL164_DID_LO 0x02 +#define SIL164_DID_HI 0x03 +#define SIL164_REV 0x04 +#define SIL164_RSVD 0x05 +#define SIL164_FREQ_LO 0x06 +#define SIL164_FREQ_HI 0x07 + +#define SIL164_REG8 0x08 +#define SIL164_8_VEN (1<<5) +#define SIL164_8_HEN (1<<4) +#define SIL164_8_DSEL (1<<3) +#define SIL164_8_BSEL (1<<2) +#define SIL164_8_EDGE (1<<1) +#define SIL164_8_PD (1<<0) + +#define SIL164_REG9 0x09 +#define SIL164_9_VLOW (1<<7) +#define SIL164_9_MSEL_MASK (0x7<<4) +#define SIL164_9_TSEL (1<<3) +#define SIL164_9_RSEN (1<<2) +#define SIL164_9_HTPLG (1<<1) +#define SIL164_9_MDI (1<<0) + +#define SIL164_REGC 0x0c + +typedef struct _Sil164SaveRec { + CARD8 freq_lo; + CARD8 freq_hi; + CARD8 reg8; + CARD8 reg9; + CARD8 regc; +} SIL164SaveRec; + +typedef struct { + I2CDevRec d; + SIL164SaveRec SavedReg; + SIL164SaveRec ModeReg; +} SIL164Rec, *SIL164Ptr; + +#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) + +#endif |