diff --git a/src/VIDEO/vid_nv_riva128.c b/src/VIDEO/vid_nv_riva128.c index 5b9b7a986..243fd59b2 100644 --- a/src/VIDEO/vid_nv_riva128.c +++ b/src/VIDEO/vid_nv_riva128.c @@ -213,8 +213,16 @@ typedef struct riva128_t { int scl; int sda; + int busy; + unsigned addrbits; + unsigned databits; uint8_t addr; //actually 7 bits uint8_t data; + struct + { + uint8_t addr; + uint8_t edid_rom[128]; + } edid_rom; } i2c; int mtime, mfreq; @@ -2133,6 +2141,22 @@ static uint8_t riva128_in(uint16_t addr, void *p) switch(svga->crtcreg) { case 0x3e: + if(riva128->i2c.busy == 2) + { + if(riva128->i2c.addr == 0xA1) + { + pclog("RIVA 128 Read EDID %02x %02x\n", riva128->i2c.edid_rom.addr, riva128->i2c.edid_rom.edid_rom[riva128->i2c.edid_rom.addr]); + riva128->i2c.data <<= 1; + riva128->i2c.data |= (riva128->i2c.edid_rom.edid_rom[riva128->i2c.edid_rom.addr] & (1 << riva128->i2c.databits)) >> riva128->i2c.databits; + } + riva128->i2c.databits++; + if(riva128->i2c.databits == 8) + { + riva128->i2c.databits = 0; + riva128->i2c.edid_rom.addr++; + riva128->i2c.busy = 0; + } + } ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); break; case 0x28: @@ -2213,8 +2237,44 @@ static void riva128_out(uint16_t addr, uint8_t val, void *p) riva128->rma.mode = val & 0xf; break; case 0x3f: + if((val & 0x20) && (riva128->i2c.sda == 0) && (val & 0x10)) + { + //I2C Start Condition. + riva128->i2c.busy = 1; + } + if((val & 0x20) && (riva128->i2c.sda == 1) && !(val & 0x10)) + { + //I2C Stop Condition. + riva128->i2c.busy = 0; + } riva128->i2c.scl = (val & 0x20) ? 1 : 0; riva128->i2c.sda = (val & 0x10) ? 1 : 0; + if(riva128->i2c.busy == 1) + { + riva128->i2c.addr <<= 1; + riva128->i2c.addr |= riva128->i2c.sda; + riva128->i2c.addrbits++; + if(riva128->i2c.addrbits = 8) + { + riva128->i2c.busy = 2; + riva128->i2c.addrbits = 0; + } + } + if(riva128->i2c.busy == 2) + { + riva128->i2c.data <<= 1; + riva128->i2c.addr |= riva128->i2c.sda; + riva128->i2c.databits++; + if(riva128->i2c.databits == 8) + { + if(riva128->i2c.addr == 0xA0) + { + pclog("RIVA 128 Write EDID Address %02x\n", riva128->i2c.data); + riva128->i2c.edid_rom.addr = riva128->i2c.data; + } + riva128->i2c.databits = 0; + } + } break; } //if(svga->crtcreg > 0x18) @@ -2777,8 +2837,6 @@ static void *riva128_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - riva128->pci_regs[0x3c] = device_get_config_int("irq"); - riva128->pmc.intr = 0; riva128->pbus.intr = 0; riva128->pfifo.intr = 0; @@ -2799,6 +2857,34 @@ static void *riva128_init() riva128->pramdac.nv_n = 0xc2; riva128->pramdac.nv_p = 0x0d; + riva128->i2c.addrbits = 0; + riva128->i2c.databits = 0; + + uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, + 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, + 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; + + { + int i = 0; + for(;i<128;i++) + { + riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; + } + } + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); @@ -2977,8 +3063,6 @@ static void *rivatnt_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - riva128->pci_regs[0x3c] = device_get_config_int("irq"); - riva128->pmc.intr = 0; riva128->pbus.intr = 0; riva128->pfifo.intr = 0; @@ -2995,6 +3079,34 @@ static void *rivatnt_init() riva128->pramdac.nv_n = 0xc2; riva128->pramdac.nv_p = 0x0d; + riva128->i2c.addrbits = 0; + riva128->i2c.databits = 0; + + uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, + 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, + 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; + + { + int i = 0; + for(;i<128;i++) + { + riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; + } + } + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); @@ -3151,8 +3263,6 @@ static void *rivatnt2_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - riva128->pci_regs[0x3c] = device_get_config_int("irq"); - riva128->pmc.intr = 0; riva128->pbus.intr = 0; riva128->pfifo.intr = 0; @@ -3169,6 +3279,34 @@ static void *rivatnt2_init() riva128->pramdac.nv_n = 0xc2; riva128->pramdac.nv_p = 0x0d; + riva128->i2c.addrbits = 0; + riva128->i2c.databits = 0; + + uint8_t edid_rom[128] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x04, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x08, 0x01, 0x03, 0x81, 0x32, 0x26, 0x78, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0x08, 0x00, 0x61, 0x40, + 0x45, 0x40, 0x31, 0x40, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, + 0x00, 0xfd, 0x00, 0x01, 0xff, 0x01, 0xff, 0xff, + 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec}; + + { + int i = 0; + for(;i<128;i++) + { + riva128->i2c.edid_rom.edid_rom[i] = edid_rom[i]; + } + } + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128);