Page 1 of 1

How to Access the I2C bus (eventually for reading the EDID)?

Posted: Sat Jul 31, 2010 4:34 am
by blobmiester
Okay. I've looked -everywhere- (I can think of at least) to find out where the SDA and SDC bits are mapped to on the x86 architecture.

I've found the I2C specification and several tutorials, and I understand it so far as I could work it if I could figure out the location of the SDA/SDC bits.

I found this in RBIL (I'm really close I think):

Code: Select all

Bitfields for S3 Local Peripheral Bus serial-port register:
Bit(s)	Description	(Table M0079)
 0	I2C clock line [SCL] (write)
	=1 tri-state SCL, allowing other devices to pull it low
 1	I2C data line [SDA] (write)
	=1 tri-state SDA, allowing other devices to pull it low
 2	I2C clock line (read)
	this bit reflect the actual state of the SCL line
 3	I2C data line (read)
	this bit reflect the actual state of the SDA line
 4	enable I2C interface
	=0 disable bits 0/1, forcing both SCL and SDA to be tri-stated
 15-5	reserved (unused)
 20-16	mirrors of bits 4-0
	(these bits are on the data bus' byte lane 2 to make them accessible
	  via I/O port 00E2h)
Notes:	see file I2C.LST for details of the I2C device registers accessible
	  through this interface (VPX3220A for Stealth64 Video 2001TV)
	when the feature connector is disabled on the Stealth64 Video, these
	  bits are connected to the monitor's DDC data and clock lines
	the official documentation erroneously lists the mirrors in bits 12-8
	  instead of 20-16
SeeAlso: #M0073,PORT 00E2h,#P0677
But I also found this (in RBIL):

Code: Select all

the access method for communicating with an I2C device is
	  implementation-dependent; for example, recent S3 chipsets supporting
	  the "Scenic Highway" Local Peripheral Bus access the I2C bus via
	  bit-banging of memory-mapped I/O register FF20h
	  (see MEM A000h:FF00h"S3").  On the Zoran ZR36057 used by the
	  Miro DC-30, the I2C bus is accessed by bit-banging memory-mapped
	  register 17 (at offset 0x44).	 On the Cirrus Logic GD7556, extended
	  sequencer register 8 is used (see #P0677).
So I'm worried about how 'standard' the memory mapped register at 0xFF20 is.

Also am I going about this the correct way? Or is there possibly a different way to access the I2C bus for every video card? (meh... now that I think of it, this would probably just *happen* to be it)

Or is it something different entirely if my purpose is to use DDC1/DDC2B/DDC2B+/etc and get the EDID?

My OS is 64-bit so I can't use VBE in protected mode (by doing a virtual 8086 monitor).

Thanks in advance.

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sat Jul 31, 2010 5:16 am
by Owen
The only portable way to get EDID information is VBE. Otherwise, you need a video card driver

(Anyway - if you don't have VBE, how are you intending to set the modes?)

For a decent real mode emulator, look up x86emu.

(By the way - particularly for older monitors, you have to use the DDC1 method, which involves reading a bitstream clocked by (IIRC) the hsync signal)

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sat Jul 31, 2010 10:57 am
by blobmiester
Owen wrote:The only portable way to get EDID information is VBE. Otherwise, you need a video card driver

(Anyway - if you don't have VBE, how are you intending to set the modes?)

For a decent real mode emulator, look up x86emu.
I don't want to use VBE, because I don't want to have to route calls through an emulator or a virtual 8086 monitor. I'll figure out setting modes when I get there. :)
Owen wrote:(By the way - particularly for older monitors, you have to use the DDC1 method, which involves reading a bitstream clocked by (IIRC) the hsync signal)
Awesome. So where could I find this bitstream? Let me guess, it is completely video-card dependent? (That's not a bad thing)

I think I can wrap my head around poking the I2C bus through a video card. I need to enum the video card from the PCI/AGP bus. Then use some video card specific way of getting the SDA/SDC bit locations.

Is that the only way? If it is, it makes it slightly easier at any rate. For some reason, I'm thinking that a monitor has specific I/O ports somewhere on the system that I would have to detect who-knows-how. But now that I think about it, a monitor is connected to a video card so probably not.

Thanks for the input.

UPDATE:

Okay I've figured out how to access the uber-neccessary SDA/SDC bits for DDC2B, DDC2B+, and DDC/CI. There is a video-card specific I/O port / MMIO somewhere if the video card supports it.

How old is old monitors for DDC1? Do I need to concern myself with it? I'm thinking not... but I would like some input. Thanks.

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sat Jul 31, 2010 1:51 pm
by Owen
blobmiester wrote:
Owen wrote:The only portable way to get EDID information is VBE. Otherwise, you need a video card driver

(Anyway - if you don't have VBE, how are you intending to set the modes?)

For a decent real mode emulator, look up x86emu.
I don't want to use VBE, because I don't want to have to route calls through an emulator or a virtual 8086 monitor. I'll figure out setting modes when I get there. :)
Setting modes = coding a video card driver = significantly more work than using x86emu
Owen wrote:(By the way - particularly for older monitors, you have to use the DDC1 method, which involves reading a bitstream clocked by (IIRC) the hsync signal)
Awesome. So where could I find this bitstream? Let me guess, it is completely video-card dependent? (That's not a bad thing)
Its just the EDID info. Yes, how you get the data into your machine is card dependent
I think I can wrap my head around poking the I2C bus through a video card. I need to enum the video card from the PCI/AGP bus. Then use some video card specific way of getting the SDA/SDC bit locations.
Correct. Good luck finding documentation, and then coding up about 50 different drivers
Is that the only way? If it is, it makes it slightly easier at any rate. For some reason, I'm thinking that a monitor has specific I/O ports somewhere on the system that I would have to detect who-knows-how. But now that I think about it, a monitor is connected to a video card so probably not.
The monitor doesn't have any connection to the system bus. Its driven only by the video timer (VGA/DVI) or bit-stream generator (DisplayPort)
UPDATE:

Okay I've figured out how to access the uber-neccessary SDA/SDC bits for DDC2B, DDC2B+, and DDC/CI. There is a video-card specific I/O port / MMIO somewhere if the video card supports it.

How old is old monitors for DDC1? Do I need to concern myself with it? I'm thinking not... but I would like some input. Thanks.
Not that old. Many VGA only monitors unfortunately still ship without DDC2 support; also, most graphics cards have multiple connectors, which are on separate buses.

And good luck finding the I²C pins for a DisplayPort connector. there isn't one! (The DDC signal is encapsulated in the DisplayPort data)

Summarising: Outsource video configuration to the display driver, then write a simple VESA driver. Other drivers can come later...

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sat Jul 31, 2010 3:43 pm
by blobmiester
Setting modes = coding a video card driver = significantly more work than using x86emu
How would I go about using an emulator? Would I have to link something equivalent to BOCHS in my kernel? I'd rather not.

In my interwebs crawling, I've learned a few things.

Putting aside insufficient documentation, NVIDIA video cards are classified by series and the same driver should work for all cards in a series. And the same driver for series 10 should work on series 20 cards because of backwards compatibility. The differences between the series (driver-wise) at a core level are minuscule and there could be -one- core driver.

ATI video cards... well I haven't really looked into them yet as I have no ATI cards on hand so no way to test if my theories are crazy or not. I'll do ATI last, and hopefully get help here on testing.

Intel cards, I know even less about than ATI cards - but I've heard that documentation is openly available for them. (I could be dead wrong, I think I heard this awhile ago).

The only other driver I would need is for CIRRUS cards (only because of QEMU / BOCHS) and I'm looking at the technical specifications right now.

Thats not that many drivers. And it just seems more proper-er than doing some fancy x86 emulation in 64-bit mode.
The monitor doesn't have any connection to the system bus. Its driven only by the video timer (VGA/DVI) or bit-stream generator (DisplayPort)
Thank you for confirming this. I thought so... but I just couldn't get a feeling out of my head that I would need to do fancy monitor I/O like for video cards.
And good luck finding the I²C pins for a DisplayPort connector. there isn't one! (The DDC signal is encapsulated in the DisplayPort data)
That's because the DisplayPort connector doesn't use I2C. It uses a bidirectional auxiliary channel that's defined in (a legacy way) E-DDC 1.2 (and more properly in DisplayID). And besides, that's -way- too new for me to worry about right now.

Thanks a lot for your help. I'm just stubborn, and don't want to use a faulty/annoying VBE interface that I can barely access from protected mode, let alone long mode.

PS:

If all I am caring about is EDID, then I could (theoretically) put the ports for SDA/SDC in a table for each video card. (Of course that wouldn't work for DisplayPort and the fancy channel it uses)

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sat Jul 31, 2010 8:00 pm
by Owen
Your expectations of the backwards compatibility between card models, and the difficulty of writing drivers for them, do not match reality.

x86emu is pretty poorly documented, but has a rather simple interface, and is seriously your best bet.

Re: How to Access the I2C bus (eventually for reading the ED

Posted: Sun Aug 01, 2010 3:26 am
by djmauretto
Hello :D
Unfortunately there is no standard way to control the SDA / SCL lines, if you're lucky that your graphics card supports the functions VBE / SCI you can control your monitor via this interface with the technique of Bit-banging .
For example I have an nVidia card that supports this extension and I can play with MCCS command, on another computer with ATI this interface is not available. I tried different computers with different graphics cards and the percentage of support for this extension is very low.