From 15b4879f7148f742c0b710bd561e50bcd1b0c5c8 Mon Sep 17 00:00:00 2001 From: Rudolf Cornelissen Date: Tue, 27 Sep 2005 10:25:49 +0000 Subject: [PATCH] added I2C bus wiring checks, and bumped version to 0.54. Note: the driver is tested on TNT1, the new code has not been tested for newer cards yet. Note also: the driver is now nolonger binary compatible with the 3D add-on alpha2, 2.5 and 3 (modified driverinterface). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14249 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../accelerants/nvidia/engine/nv_general.c | 27 +- .../accelerants/nvidia/engine/nv_i2c.c | 305 +++--------------- .../accelerants/nvidia/engine/nv_info.c | 3 +- 3 files changed, 70 insertions(+), 265 deletions(-) diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c index 042d30c76d..e9df2a68b3 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_general.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c @@ -1,7 +1,7 @@ /* Authors: Mark Watson 12/1999, Apsed, - Rudolf Cornelissen 10/2002-6/2005 + Rudolf Cornelissen 10/2002-9/2005 */ #define MODULE_BIT 0x00008000 @@ -10,6 +10,7 @@ static status_t test_ram(void); static status_t nvxx_general_powerup (void); +static void unlock_card(void); static status_t nv_general_bios_to_powergraphics(void); static void nv_dump_configuration_space (void) @@ -90,7 +91,7 @@ status_t nv_general_powerup() { status_t status; - LOG(1,("POWERUP: Haiku nVidia Accelerant 0.53 running.\n")); + LOG(1,("POWERUP: Haiku nVidia Accelerant 0.54 running.\n")); /* preset no laptop */ si->ps.laptop = false; @@ -1104,6 +1105,8 @@ static status_t nvxx_general_powerup() LOG(2, ("INIT: Skipping card coldstart!\n")); } + unlock_card(); + /* get RAM size and fake panel startup (panel init code is still missing) */ fake_panel_start(); @@ -1195,14 +1198,8 @@ status_t nv_general_head_select(bool cross) } } -/* basic change of card state from VGA to enhanced mode: - * Should work from VGA BIOS POST init state. */ -static status_t nv_general_bios_to_powergraphics() +static void unlock_card(void) { - /* let acc engine make power off/power on cycle to start 'fresh' */ - NV_REG32(NV32_PWRUPCTRL) = 0x13110011; - snooze(1000); - /* power-up all nvidia hardware function blocks */ /* bit 28: OVERLAY ENGINE (BES), * bit 25: CRTC2, (> NV04A) @@ -1231,6 +1228,18 @@ static status_t nv_general_bios_to_powergraphics() CRTC2W(LOCK, 0x57); CRTC2W(VSYNCE ,(CRTCR(VSYNCE) & 0x7f)); } +} + +/* basic change of card state from VGA to enhanced mode: + * Should work from VGA BIOS POST init state. */ +static status_t nv_general_bios_to_powergraphics() +{ + /* let acc engine make power off/power on cycle to start 'fresh' */ + NV_REG32(NV32_PWRUPCTRL) = 0x13110011; + snooze(1000); + NV_REG32(NV32_PWRUPCTRL) = 0x13111111; + + unlock_card(); /* turn off both displays and the hardcursors (also disables transfers) */ head1_dpms(false, false, false); diff --git a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c index 3d189eb51c..c6e8cbf23a 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c @@ -1,14 +1,7 @@ /* - * i2c interface for the G400 MAVEN under BeOS - * - * Provides I2CR,I2CW - functions to parallel DACW,DACR + * i2c interface. * Bus should be run at max. 100kHz: see original Philips I2C specification * - * Much help was provided by observing the Linux i2c code, - * so thanks go to: Gerd Knorr - * - * Other authors: - * Mark Watson 6/2000, * Rudolf Cornelissen 12/2002-9/2005 */ @@ -16,36 +9,6 @@ #include "nv_std.h" -int i2c_set_lines(int clock, int data); -int i2c_get_data(void); -void i2c_start(void); -void i2c_stop(void); -void i2c_high(void); -void i2c_low(void); -int i2c_get_ack(void); -void i2c_send_ack(void); -int i2c_sendbyte(unsigned char data); - -/*which device on the bus is the MAVEN?*/ -#define MAVEN_WRITE (0x1B<<1) -#define MAVEN_READ ((0x1B<<1)|1) - -#define I2C_CLOCK 0x20 -#define I2C_DATA 0x10 - -/* NV-TVO I2C for G200, G400 */ -#define I2C_CLOCK 0x20 -#define I2C_DATA 0x10 -/* primary head DDC for Mystique(?), G100, G200, G400 */ -#define DDC1_CLK 0x08 -#define DDC1_DATA 0x02 -/* primary head DDC for Millennium, Millennium II */ -#define DDC1B_CLK 0x10 -#define DDC1B_DATA 0x04 -/* secondary head DDC for G400, G450 and G550 */ -#define DDC2_CLK 0x04 -#define DDC2_DATA 0x01 - status_t i2c_sec_tv_adapter() { status_t result = B_ERROR; @@ -75,194 +38,6 @@ status_t i2c_sec_tv_adapter() return result; } -/*----------------------------- - *low level hardware access - */ -#define I2C_DELAY 2 -#define I2C_TIMEOUT 100 -int i2c_set_lines(int clock,int data) -{ - int count=0; - int program; - int required; - - /*work out which bits to zero*/ - program = - (clock ? 0 : I2C_CLOCK)| - (data ? 0 : I2C_DATA); - - /*what value do I require on data lines*/ - required = - (clock ? I2C_CLOCK : 0); - - /*set the bits to zero*/ -// DXIW(GENIOCTRL,program); /*drive these bits*/ -// DXIW(GENIODATA,0x00); /*to zero*/ - - /*wait a bit*/ - delay(I2C_DELAY); - - /*loop until the clock is as required*/ -// while ((DXIR(GENIODATA)&I2C_CLOCK)!=required) - { - delay(I2C_DELAY); - count++; - if (count>I2C_TIMEOUT) - { -// LOG(8,("I2C: Timeout on set lines - clock:%d data:%d actual:%x\n",clock,data,DXIR(GENIODATA))); - return -1; - } - } - - return 0; -} - -int i2c_get_data() -{ - int data = 0; - int clock; - int count=0; - - do - { - /*read the data and clock lines*/ -// data = DXIR(GENIODATA); - clock = (data&I2C_CLOCK) ? 1 : 0; - data = (data&I2C_DATA) ? 1 : 0; - - /*manage timeout*/ - count++; - if (count>I2C_TIMEOUT) - { - return -1; - } - - /*wait a bit, so not hammering bus*/ - delay(I2C_DELAY); - - }while (!clock); /*wait for high clock*/ - - return data; -} - - -/*----------------------- - *Standard I2C operations - */ -void i2c_start() -{ - int error=0; - - error+= i2c_set_lines(0,1); - error+= i2c_set_lines(1,1); - error+= i2c_set_lines(1,0); - error+= i2c_set_lines(0,0); - - if (error) - { - LOG(8,("I2C: start - %d\n",error)); - } -} - -void i2c_stop() -{ - int error=0; - - error+= i2c_set_lines(0,0); - error+= i2c_set_lines(1,0); - error+= i2c_set_lines(1,1); - error+= i2c_set_lines(0,1); - - if (error) - { - LOG(8,("I2C: stop - %d\n",error)); - } -} - -void i2c_high() -{ - int error=0; - - error+= i2c_set_lines(0,1); - error+= i2c_set_lines(1,1); - error+= i2c_set_lines(0,1); - - if (error) - { - LOG(8,("I2C: high - %d\n",error)); - } -} - -void i2c_low() -{ - int error=0; - - error+= i2c_set_lines(0,0); - error+= i2c_set_lines(1,0); - error+= i2c_set_lines(0,0); - - if (error) - { - LOG(8,("I2C: low - %d\n",error)); - } -} - -int i2c_get_ack() -{ - int error=0; - int ack; - - error+= i2c_set_lines(0,1); - error+= i2c_set_lines(1,1); - ack = i2c_get_data(); - error+= i2c_set_lines(0,1); - - if (error) - { - LOG(8,("I2C: get_ack - %d value:%x\n",error,ack)); - } - - return ack; -} - -void i2c_send_ack() -{ - int error=0; - - error+= i2c_set_lines(0,0); - error+= i2c_set_lines(1,0); - error+= i2c_set_lines(0,0); - - if (error) - { - LOG(8,("I2C: send_ack - %d\n",error)); - } -} - -/*------------------------------ - *use above functions to send and receive bytes - */ - -int i2c_sendbyte(unsigned char data) -{ - int i; - - for (i=7; i>=0; i--) - { - if (data&(1<0) LOG(8,("I2C: MAVR ERROR - %x\n",error)); return data; } @@ -501,7 +278,7 @@ int i2c_maven_read(unsigned char address) void i2c_maven_write(unsigned char address, unsigned char data) { int error=0; - +/* i2c_start(); { error+=i2c_sendbyte(MAVEN_WRITE); @@ -509,35 +286,53 @@ void i2c_maven_write(unsigned char address, unsigned char data) error+=i2c_sendbyte(data); } i2c_stop(); +*/ if (error>0) LOG(8,("I2C: MAVW ERROR - %x\n",error)); } status_t i2c_init(void) { - /*init g400 i2c*/ -// DXIW(GENIODATA,0x00); /*to zero*/ -// DXIW(GENIOCTRL,0x30); /*drive clock and data*/ -// DXIW(GENIOCTRL,0x00); /*stop driving*/ + uint8 bus; + bool *i2c_bus = &(si->ps.i2c_bus0); + + LOG(4,("I2C: searching for wired I2C buses...\n")); + + /* preset no board wired buses */ + si->ps.i2c_bus0 = false; + si->ps.i2c_bus1 = false; + + /* find existing buses */ + for (bus = 0; bus < 2; bus++) + { + /* reset status */ + FlagIICError (-1); + snooze(6); + /* init and/or stop I2C bus */ + bstop(bus); + /* check for hardware coupling of SCL and SDA -out and -in lines */ + snooze(6); + OutSCL(bus, false); + OutSDA(bus, true); + snooze(3); + if (InSCL(bus) || !InSDA(bus)) continue; + snooze(3); + OutSCL(bus, true); + OutSDA(bus, false); + snooze(3); + if (!InSCL(bus) || InSDA(bus)) continue; + i2c_bus[bus] = true; + snooze(3); + /* re-init bus */ + bstop(bus); + } + + for (bus = 0; bus < 2; bus++) + { + if (i2c_bus[bus]) + LOG(4,("I2C: bus #%d wiring check: passed\n", bus)); + else + LOG(4,("I2C: bus #%d wiring check: failed\n", bus)); + } return B_OK; } - -status_t i2c_maven_probe(void) -{ - int ack; - - /*scan the bus for the MAVEN*/ - i2c_start(); - { - ack = i2c_sendbyte(MAVEN_READ); - } - i2c_stop(); - if (ack==0) - { - return B_OK; - } - else - { - return B_ERROR; - } -} diff --git a/src/add-ons/accelerants/nvidia/engine/nv_info.c b/src/add-ons/accelerants/nvidia/engine/nv_info.c index 488191236a..2c1b3b5823 100644 --- a/src/add-ons/accelerants/nvidia/engine/nv_info.c +++ b/src/add-ons/accelerants/nvidia/engine/nv_info.c @@ -1,7 +1,7 @@ /* Read initialisation information from card */ /* some bits are hacks, where PINS is not known */ /* Author: - Rudolf Cornelissen 7/2003-6/2005 + Rudolf Cornelissen 7/2003-9/2005 */ #define MODULE_BIT 0x00002000 @@ -2131,6 +2131,7 @@ void fake_panel_start(void) si->ps.tvout = false; si->ps.tvout_chip_type = NONE; //fixme ;-) + i2c_init(); /* if (i2c_maven_probe() == B_OK) { si->ps.tvout = true;