diff --git a/src/add-ons/accelerants/nvidia/Jamfile b/src/add-ons/accelerants/nvidia/Jamfile
index 881fa26d25..a23fa61676 100644
--- a/src/add-ons/accelerants/nvidia/Jamfile
+++ b/src/add-ons/accelerants/nvidia/Jamfile
@@ -4,6 +4,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders graphics ;
UsePrivateHeaders [ FDirName graphics nvidia ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
UseHeaders [ FDirName $(SUBDIR) engine ] ;
Addon nvidia.accelerant :
@@ -18,7 +19,7 @@ Addon nvidia.accelerant :
Overlay.c
ProposeDisplayMode.c
SetDisplayMode.c
- : libnvidia_engine.a
+ : libnvidia_engine.a libaccelerantscommon.a
;
Package haiku-nvidia-cvs :
diff --git a/src/add-ons/accelerants/nvidia/acc_std.h b/src/add-ons/accelerants/nvidia/acc_std.h
index 560ab04a67..273b055bfe 100644
--- a/src/add-ons/accelerants/nvidia/acc_std.h
+++ b/src/add-ons/accelerants/nvidia/acc_std.h
@@ -8,9 +8,15 @@
#include
#include
+
+/* DDC/EDID library */
+//#include
+#include
+//#include
+
+/* Nvidia driver */
#include "DriverInterface.h"
#include "nv_globals.h"
-//apsed #include "nv_extern.h"
#include "nv_proto.h"
#include "be_driver_proto.h"
diff --git a/src/add-ons/accelerants/nvidia/engine/Jamfile b/src/add-ons/accelerants/nvidia/engine/Jamfile
index 7b0d849b7a..6c1c598d5b 100644
--- a/src/add-ons/accelerants/nvidia/engine/Jamfile
+++ b/src/add-ons/accelerants/nvidia/engine/Jamfile
@@ -4,6 +4,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders graphics ;
UsePrivateHeaders [ FDirName graphics nvidia ] ;
+UsePrivateHeaders [ FDirName graphics common ] ;
StaticLibrary libnvidia_engine.a :
nv_acc.c
@@ -20,4 +21,5 @@ StaticLibrary libnvidia_engine.a :
nv_i2c.c
nv_info.c
nv_support.c
- ;
+ :
+;
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_general.c b/src/add-ons/accelerants/nvidia/engine/nv_general.c
index 296df34829..6aa9543c59 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_general.c
+++ b/src/add-ons/accelerants/nvidia/engine/nv_general.c
@@ -92,7 +92,7 @@ status_t nv_general_powerup()
{
status_t status;
- LOG(1,("POWERUP: Haiku nVidia Accelerant 0.88 running.\n"));
+ LOG(1,("POWERUP: Haiku nVidia Accelerant 0.89 running.\n"));
/* log VBLANK INT usability status */
if (si->ps.int_assigned)
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c
index 1106604377..93b9ad77cc 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_i2c.c
+++ b/src/add-ons/accelerants/nvidia/engine/nv_i2c.c
@@ -2,7 +2,7 @@
* i2c interface.
* Bus should be run at max. 100kHz: see original Philips I2C specification
*
- * Rudolf Cornelissen 12/2002-10/2005
+ * Rudolf Cornelissen 12/2002-5/2009
*/
#define MODULE_BIT 0x00004000
@@ -340,5 +340,244 @@ status_t i2c_init(void)
LOG(4,("I2C: bus #%d wiring check: failed\n", bus));
}
+ i2c_TestEDID();
+
return result;
}
+
+/*** DDC/EDID library use ***/
+typedef struct {
+ uint32 port;
+} ddc_port_info;
+
+/* Dump EDID info in driver's logfile */
+static void
+i2c_edid_dump(edid1_info *edid)
+{
+ int i, j;
+
+ LOG(4,("Vendor: %s\n", edid->vendor.manufacturer));
+ LOG(4,("Product ID: %d\n", (int)edid->vendor.prod_id));
+ LOG(4,("Serial #: %d\n", (int)edid->vendor.serial));
+ LOG(4,("Produced in week/year: %d/%d\n", edid->vendor.week, edid->vendor.year));
+
+ LOG(4,("EDID version: %d.%d\n", edid->version.version, edid->version.revision));
+
+ LOG(4,("Type: %s\n", edid->display.input_type ? "Digital" : "Analog"));
+ LOG(4,("Size: %d cm x %d cm\n", edid->display.h_size, edid->display.v_size));
+ LOG(4,("Gamma=%.3f\n", (edid->display.gamma + 100) / 100.0));
+ LOG(4,("White (X,Y)=(%.3f,%.3f)\n", edid->display.white_x / 1024.0,
+ edid->display.white_y / 1024.0));
+
+ LOG(4,("Supported Future Video Modes:\n"));
+ for (i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
+ if (edid->std_timing[i].h_size <= 256)
+ continue;
+
+ LOG(4,("%dx%d@%dHz (id=%d)\n",
+ edid->std_timing[i].h_size, edid->std_timing[i].v_size,
+ edid->std_timing[i].refresh, edid->std_timing[i].id));
+ }
+
+ LOG(4,("Supported VESA Video Modes:\n"));
+ if (edid->established_timing.res_720x400x70)
+ LOG(4,("720x400@70\n"));
+ if (edid->established_timing.res_720x400x88)
+ LOG(4,("720x400@88\n"));
+ if (edid->established_timing.res_640x480x60)
+ LOG(4,("640x480@60\n"));
+ if (edid->established_timing.res_640x480x67)
+ LOG(4,("640x480x67\n"));
+ if (edid->established_timing.res_640x480x72)
+ LOG(4,("640x480x72\n"));
+ if (edid->established_timing.res_640x480x75)
+ LOG(4,("640x480x75\n"));
+ if (edid->established_timing.res_800x600x56)
+ LOG(4,("800x600@56\n"));
+ if (edid->established_timing.res_800x600x60)
+ LOG(4,("800x600@60\n"));
+
+ if (edid->established_timing.res_800x600x72)
+ LOG(4,("800x600@72\n"));
+ if (edid->established_timing.res_800x600x75)
+ LOG(4,("800x600@75\n"));
+ if (edid->established_timing.res_832x624x75)
+ LOG(4,("832x624@75\n"));
+ if (edid->established_timing.res_1024x768x87i)
+ LOG(4,("1024x768@87 interlaced\n"));
+ if (edid->established_timing.res_1024x768x60)
+ LOG(4,("1024x768@60\n"));
+ if (edid->established_timing.res_1024x768x70)
+ LOG(4,("1024x768@70\n"));
+ if (edid->established_timing.res_1024x768x75)
+ LOG(4,("1024x768@75\n"));
+ if (edid->established_timing.res_1280x1024x75)
+ LOG(4,("1280x1024@75\n"));
+
+ if (edid->established_timing.res_1152x870x75)
+ LOG(4,("1152x870@75\n"));
+
+ for (i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i) {
+ edid1_detailed_monitor *monitor = &edid->detailed_monitor[i];
+
+ switch(monitor->monitor_desc_type) {
+ case EDID1_SERIAL_NUMBER:
+ LOG(4,("Serial Number: %s\n", monitor->data.serial_number));
+ break;
+
+ case EDID1_ASCII_DATA:
+ LOG(4,(" %s\n", monitor->data.serial_number));
+ break;
+
+ case EDID1_MONITOR_RANGES:
+ {
+ edid1_monitor_range monitor_range = monitor->data.monitor_range;
+
+ LOG(4,("Horizontal frequency range = %d..%d kHz\n",
+ monitor_range.min_h, monitor_range.max_h));
+ LOG(4,("Vertical frequency range = %d..%d Hz\n",
+ monitor_range.min_v, monitor_range.max_v));
+ LOG(4,("Maximum pixel clock = %d MHz\n", (uint16)monitor_range.max_clock * 10));
+ break;
+ }
+
+ case EDID1_MONITOR_NAME:
+ LOG(4,("Monitor Name: %s\n", monitor->data.monitor_name));
+ break;
+
+ case EDID1_ADD_COLOUR_POINTER:
+ {
+ for (j = 0; j < EDID1_NUM_EXTRA_WHITEPOINTS; ++j) {
+ edid1_whitepoint *whitepoint = &monitor->data.whitepoint[j];
+
+ if (whitepoint->index == 0)
+ continue;
+
+ LOG(4,("Additional whitepoint: (X,Y)=(%f,%f) gamma=%f index=%i\n",
+ whitepoint->white_x / 1024.0,
+ whitepoint->white_y / 1024.0,
+ (whitepoint->gamma + 100) / 100.0,
+ whitepoint->index));
+ }
+ break;
+ }
+
+ case EDID1_ADD_STD_TIMING:
+ {
+ for (j = 0; j < EDID1_NUM_EXTRA_STD_TIMING; ++j) {
+ edid1_std_timing *timing = &monitor->data.std_timing[j];
+
+ if (timing->h_size <= 256)
+ continue;
+
+ LOG(4,("%dx%d@%dHz (id=%d)\n",
+ timing->h_size, timing->v_size,
+ timing->refresh, timing->id));
+ }
+ break;
+ }
+
+ case EDID1_IS_DETAILED_TIMING:
+ {
+ edid1_detailed_timing *timing = &monitor->data.detailed_timing;
+
+ LOG(4,("Additional Video Mode:\n"));
+ LOG(4,("clock=%f MHz\n", timing->pixel_clock / 100.0));
+ LOG(4,("h: (%d, %d, %d, %d)\n",
+ timing->h_active, timing->h_active + timing->h_sync_off,
+ timing->h_active + timing->h_sync_off + timing->h_sync_width,
+ timing->h_active + timing->h_blank));
+ LOG(4,("v: (%d, %d, %d, %d)\n",
+ timing->v_active, timing->v_active + timing->v_sync_off,
+ timing->v_active + timing->v_sync_off + timing->v_sync_width,
+ timing->v_active + timing->v_blank));
+ LOG(4,("size: %.1f cm x %.1f cm\n",
+ timing->h_size / 10.0, timing->v_size / 10.0));
+ LOG(4,("border: %.1f cm x %.1f cm\n",
+ timing->h_border / 10.0, timing->v_border / 10.0));
+ break;
+ }
+ }
+ }
+}
+
+/* callback for getting signals from I2C bus */
+static status_t
+get_signals(void *cookie, int *clk, int *data)
+{
+ ddc_port_info *info = (ddc_port_info *)cookie;
+
+ *clk = *data = 0x0000;
+ if (InSCL(info->port)) *clk = 0x0001;
+ if (InSDA(info->port)) *data = 0x0001;
+
+ return B_OK;
+}
+
+/* callback for setting signals on I2C bus */
+static status_t
+set_signals(void *cookie, int clk, int data)
+{
+ ddc_port_info *info = (ddc_port_info *)cookie;
+
+ if (clk)
+ OutSCL(info->port, true);
+ else
+ OutSCL(info->port, false);
+
+ if (data)
+ OutSDA(info->port, true);
+ else
+ OutSDA(info->port, false);
+
+ return B_OK;
+}
+
+/* Read EDID information from monitor via the display data channel (DDC) */
+status_t
+i2c_ReadEDID(uint8 BusNR, edid1_info *edid)
+{
+ i2c_bus bus;
+ ddc_port_info info;
+
+ info.port = BusNR;
+
+ bus.cookie = &info;
+ bus.set_signals = &set_signals;
+ bus.get_signals = &get_signals;
+ ddc2_init_timing(&bus);
+
+ /* select GPU I/O pins set */
+ i2c_select_bus_set(BusNR & 0x02);
+
+ /* enable access to primary head */
+ set_crtc_owner(0);
+
+ if (ddc2_read_edid1(&bus, edid, NULL, NULL) == B_OK) {
+ LOG(4,("I2C: EDID succesfully read from monitor at bus %d\n", BusNR));
+ LOG(4,("I2C: EDID dump follows (bus %d):\n", BusNR));
+// has_edid = true;
+ i2c_edid_dump(edid);
+ LOG(4,("I2C: end EDID dump (bus %d).\n", BusNR));
+ } else {
+ LOG(4,("I2C: reading EDID failed at bus %d!\n", BusNR));
+ return B_ERROR;
+ }
+
+ return B_OK;
+}
+
+void i2c_TestEDID(void)
+{
+ uint8 bus, buses;
+
+ /* set number of buses to test for */
+ buses = 2;
+ if (si->ps.secondary_head) buses = 4;
+
+ /* test bus */
+ for (bus = 0; bus < buses; bus++) {
+ edid1_info edid;
+ i2c_ReadEDID(bus, &edid);
+ }
+}
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_proto.h b/src/add-ons/accelerants/nvidia/engine/nv_proto.h
index 42dc7a9d9e..193532823a 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_proto.h
+++ b/src/add-ons/accelerants/nvidia/engine/nv_proto.h
@@ -34,6 +34,8 @@ bool i2c_writebyte (uint8 BusNR, uint8 byte);
void i2c_readbuffer (uint8 BusNR, uint8* buf, uint8 size);
void i2c_writebuffer (uint8 BusNR, uint8* buf, uint8 size);
status_t i2c_init(void);
+status_t i2c_ReadEDID(uint8 BusNR, edid1_info *edid);
+void i2c_TestEDID(void);
/* card info functions */
status_t parse_pins(void);
diff --git a/src/add-ons/accelerants/nvidia/engine/nv_std.h b/src/add-ons/accelerants/nvidia/engine/nv_std.h
index cc21aaecb0..c3e84f0cbd 100644
--- a/src/add-ons/accelerants/nvidia/engine/nv_std.h
+++ b/src/add-ons/accelerants/nvidia/engine/nv_std.h
@@ -2,9 +2,15 @@
#include
#include
#include
+
+/* DDC/EDID library */
+//#include
+#include
+//#include
+
+/* Nvidia driver */
#include "DriverInterface.h"
#include "nv_globals.h"
-//apsed #include "nv_extern.h"
#include "nv_proto.h"
#include "nv_macros.h"
#include "nv_acc.h"
diff --git a/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html b/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html
index 466f44fc5e..12ff62d46c 100644
--- a/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html
+++ b/src/add-ons/kernel/drivers/graphics/nvidia/UPDATE.html
@@ -4,7 +4,7 @@
Changes done for each driverversion:
-head (SVN 0.88, Rudolf)
+head (SVN 0.89, Rudolf)
- Fixed driver assuming enabling AGP mode succeeded on some occasions if it did not block it itself. Blocking AGP mode completely via the AGP busmanager (option 'block_agp') resulted in a crashing acceleration engine because it was setup for AGP transfers instead of using PCI transfers. Error was solved with help from user kraton.
- Fixed shared_info struct problem occuring when 3D 'accelerant' is used (tested Alpha 4.1): the TVencoder type definition list apparantly gets some memory assigned these days when done inside the definition of shared_info. Moved encoder list outside the shared_info definition.
@@ -18,6 +18,7 @@
- Added 'block_acc' option in nvidia.settings to completely disable the acceleration engine. Use this as a work-around if the acceleration engine misbehaves.
- Fixed card/system hanging after trying to log LVDS/TMDS distinction info. This (at least) fixes one NV34 trying to startup after a failed kernel VESA modeswitch without using the driver's coldstart option. Might very well help on other type cards too.
- HDTV video upto/including 1920x1080p can now be played back using overlay on Geforce cards where overlay is supported. On TNT1/TNT2/TNT2-M64 this can't be done and bitmap output is used.
+
- Added partial DDC/EDID support: dumping monitor specs to logfile only for now.
nv_driver 0.80 (Rudolf)