2005-11-26 05:02:56

by Calin A. Culianu

[permalink] [raw]
Subject: [PATCH] nvidiafb support for 6600 and 6200

Hi,

This patch can be applied against 2.6.15-rc1 to add support to the
nvidiafb driver for a few obscure (yet on-the-market) nvidia
boards/chipsets, including various versions of the Geforce 6600 and 6200.

This patch has been tested and allows the above-mentioned boards to get
framebuffer console support.

Thanks!

-Calin


Attachments:
nvidiafb-6600-support.patch (2.70 kB)

2005-11-26 06:26:50

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: [PATCH] nvidiafb support for 6600 and 6200

Calin A. Culianu wrote:
> Hi,
>
> This patch can be applied against 2.6.15-rc1 to add support to the
> nvidiafb driver for a few obscure (yet on-the-market) nvidia
> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>
> This patch has been tested and allows the above-mentioned boards to get
> framebuffer console support.
>

Is this a pci-e card? With a pci-e card, the actual chipset type is located
in one of the registers (instead of deriving it from the pci device id) and
will resolve into one of the supported architectures, usually an NV_ARCH_40.

Can you try this patch instead? And send me your dmesg whether it works or
not.

Thanks.

Tony

diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index b989358..7d51e3a 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -925,6 +925,7 @@ void NVCalcStateExt(struct nvidia_par *p

void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
{
+ u32 tmp;
int i;

NV_WR32(par->PMC, 0x0140, 0x00000000);
@@ -938,15 +939,25 @@ void NVLoadStateExt(struct nvidia_par *p

if (par->Architecture == NV_ARCH_04) {
NV_WR32(par->PFB, 0x0200, state->config);
- } else if ((par->Chipset & 0xfff0) == 0x0090) {
- for (i = 0; i < 15; i++) {
- NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
- NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1);
- }
- } else {
+ } else if((par->Architecture < NV_ARCH_40) ||
+ ((par->Chipset & 0xfff0) == 0x0040)) {
for (i = 0; i < 8; i++) {
NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
- NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1);
+ NV_WR32(par->PFB, 0x0244 + (i * 0x10),
+ par->FbMapSize - 1);
+ }
+ } else {
+ int regions = 12;
+
+ if(((par->Chipset & 0xfff0) == 0x0090) ||
+ ((par->Chipset & 0xfff0) == 0x01D0) ||
+ ((par->Chipset & 0xfff0) == 0x0290))
+ regions = 15;
+
+ for(i = 0; i < regions; i++) {
+ NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
+ NV_WR32(par->PFB, 0x0604 + (i * 0x10),
+ par->FbMapSize - 1);
}
}

@@ -1187,6 +1198,10 @@ void NVLoadStateExt(struct nvidia_par *p
NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);

+ tmp = NV_RD32(par->REGS, 0x1540) & 0xff;
+ for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++);
+ NV_WR32(par->PGRAPH, 0x5000, i);
+
if ((par->Chipset & 0xfff0) == 0x0040) {
NV_WR32(par->PGRAPH, 0x09b0,
0x83280fff);
@@ -1211,6 +1226,7 @@ void NVLoadStateExt(struct nvidia_par *p
0xffff7fff);
break;
case 0x00C0:
+ case 0x0120:
NV_WR32(par->PGRAPH, 0x0828,
0x007596ff);
NV_WR32(par->PGRAPH, 0x082C,
@@ -1245,6 +1261,7 @@ void NVLoadStateExt(struct nvidia_par *p
0x00100000);
break;
case 0x0090:
+ case 0x0290:
NV_WR32(par->PRAMDAC, 0x0608,
NV_RD32(par->PRAMDAC, 0x0608) |
0x00100000);
@@ -1310,14 +1327,42 @@ void NVLoadStateExt(struct nvidia_par *p
}
}

- if ((par->Chipset & 0xfff0) == 0x0090) {
- for (i = 0; i < 60; i++)
- NV_WR32(par->PGRAPH, 0x0D00 + i,
- NV_RD32(par->PFB, 0x0600 + i));
- } else {
- for (i = 0; i < 32; i++)
+ if ((par->Architecture < NV_ARCH_40) ||
+ ((par->Chipset & 0xfff0) == 0x0040)) {
+ for(i = 0; i < 32; i++) {
NV_WR32(par->PGRAPH, 0x0900 + i,
NV_RD32(par->PFB, 0x0240 + i));
+ NV_WR32(par->PGRAPH, 0x6900 + i,
+ NV_RD32(par->PFB, 0x0240 + i));
+ }
+ } else {
+ if (((par->Chipset & 0xfff0) == 0x0090) ||
+ ((par->Chipset & 0xfff0) == 0x01D0) ||
+ ((par->Chipset & 0xfff0) == 0x0290)) {
+ for(i = 0; i < 60; i++) {
+ NV_WR32(par->PGRAPH, 0x0D00+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ NV_WR32(par->PGRAPH, 0x6900+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ }
+ } else {
+ for(i = 0; i < 48; i++) {
+ NV_WR32(par->PGRAPH, 0x0900+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ if (((par->Chipset & 0xfff0) !=
+ 0x0160) &&
+ ((par->Chipset & 0xfff0) !=
+ 0x0220)) {
+ NV_WR32(par->PGRAPH,
+ 0x6900 + i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ }
+ }
+ }
}

if (par->Architecture >= NV_ARCH_40) {
@@ -1338,11 +1383,15 @@ void NVLoadStateExt(struct nvidia_par *p
NV_WR32(par->PGRAPH, 0x0868,
par->FbMapSize - 1);
} else {
- if((par->Chipset & 0xfff0) == 0x0090) {
+ if (((par->Chipset & 0xfff0)==0x0090)||
+ ((par->Chipset & 0xfff0)==0x01D0)||
+ ((par->Chipset & 0xfff0)==0x0290)){
NV_WR32(par->PGRAPH, 0x0DF0,
- NV_RD32(par->PFB, 0x0200));
+ NV_RD32(par->PFB,
+ 0x0200));
NV_WR32(par->PGRAPH, 0x0DF4,
- NV_RD32(par->PFB, 0x0204));
+ NV_RD32(par->PFB,
+ 0x0204));
} else {
NV_WR32(par->PGRAPH, 0x09F0,
NV_RD32(par->PFB, 0x0200));
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 1f06a9f..1330021 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -277,6 +277,9 @@ static void nv10GetConfig(struct nvidia_
(NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
}

+ if (par->RamAmountKBytes > 256*1024)
+ par->RamAmountKBytes = 256*1024;
+
par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
14318 : 13500;

@@ -285,7 +288,6 @@ static void nv10GetConfig(struct nvidia_
par->CrystalFreqKHz = 27000;
}

- par->CursorStart = (par->RamAmountKBytes - 96) * 1024;
par->CURSOR = NULL; /* can't set this here */
par->MinVClockFreqKHz = 12000;
par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000;
@@ -382,6 +384,8 @@ void NVCommonSetup(struct fb_info *info)
case 0x0146:
case 0x0147:
case 0x0148:
+ case 0x0098:
+ case 0x0099:
mobile = 1;
break;
default:
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 961007d..2d9152d 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1448,11 +1448,34 @@ static int __devinit nvidia_set_fbinfo(s
return nvidiafb_check_var(&info->var, info);
}

-static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
+static u32 __devinit nvidia_get_chipset(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
+ u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
+
+ printk("nvidiafb: PCI id - %x\n", id);
+ if ((id & 0xfff0) == 0x00f0) {
+ /* pci-e */
+ printk("nvidiafb: PCI-E card\n");
+ id = NV_RD32(par->REGS, 0x1800);
+
+ if ((id & 0x0000ffff) == 0x000010DE)
+ id = 0x10DE0000 | (id >> 16);
+ else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
+ id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
+ ((id >> 8) & 0x000000ff);
+ }
+
+ printk("nvidiafb: Actual id - %x\n", id);
+ return id;
+}
+
+static u32 __devinit nvidia_get_arch(struct fb_info *info)
+{
+ struct nvidia_par *par = info->par;
u32 arch = 0;

- switch (pd->device & 0x0ff0) {
+ switch (par->Chipset & 0x0ff0) {
case 0x0100: /* GeForce 256 */
case 0x0110: /* GeForce2 MX */
case 0x0150: /* GeForce2 */
@@ -1485,6 +1508,8 @@ static u32 __devinit nvidia_get_arch(str
case 0x0210:
case 0x0220:
case 0x0230:
+ case 0x0290:
+ case 0x0390:
arch = NV_ARCH_40;
break;
case 0x0020: /* TNT, TNT2 */
@@ -1533,9 +1558,6 @@ static int __devinit nvidiafb_probe(stru
goto err_out_request;
}

- par->Architecture = nvidia_get_arch(pd);
-
- par->Chipset = (pd->vendor << 16) | pd->device;
printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);

if (par->Architecture == 0) {
@@ -1570,6 +1592,8 @@ static int __devinit nvidiafb_probe(stru
goto err_out_free_base0;
}

+ par->Chipset = nvidia_get_chipset(info);
+ par->Architecture = nvidia_get_arch(info);
NVCommonSetup(info);

par->FbAddress = nvidiafb_fix.smem_start;
@@ -1581,10 +1605,15 @@ static int __devinit nvidiafb_probe(stru
if (par->FbMapSize > 64 * 1024 * 1024)
par->FbMapSize = 64 * 1024 * 1024;

- par->FbUsableSize = par->FbMapSize - (128 * 1024);
+ if(par->Architecture >= NV_ARCH_40)
+ par->FbUsableSize = par->FbMapSize - (560 * 1024);
+ else
+ par->FbUsableSize = par->FbMapSize - (128 * 1024);
+
par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
16 * 1024;
par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
+ par->CursorStart = par->FbUsableSize + (32 * 1024);
info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
info->screen_size = par->FbUsableSize;
nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;

2005-11-26 06:34:13

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: [PATCH] nvidiafb support for 6600 and 6200

Antonino A. Daplas wrote:
> Calin A. Culianu wrote:
>> Hi,
>>
>> This patch can be applied against 2.6.15-rc1 to add support to the
>> nvidiafb driver for a few obscure (yet on-the-market) nvidia
>> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>>
>> This patch has been tested and allows the above-mentioned boards to get
>> framebuffer console support.
>>
>
> Is this a pci-e card? With a pci-e card, the actual chipset type is located
> in one of the registers (instead of deriving it from the pci device id) and
> will resolve into one of the supported architectures, usually an NV_ARCH_40.
>
> Can you try this patch instead? And send me your dmesg whether it works or
> not.
>

Uhh, disregard the previous patch, try this one.

Tony

diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index b989358..7d51e3a 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -925,6 +925,7 @@ void NVCalcStateExt(struct nvidia_par *p

void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)
{
+ u32 tmp;
int i;

NV_WR32(par->PMC, 0x0140, 0x00000000);
@@ -938,15 +939,25 @@ void NVLoadStateExt(struct nvidia_par *p

if (par->Architecture == NV_ARCH_04) {
NV_WR32(par->PFB, 0x0200, state->config);
- } else if ((par->Chipset & 0xfff0) == 0x0090) {
- for (i = 0; i < 15; i++) {
- NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
- NV_WR32(par->PFB, 0x0604 + (i * 0x10), par->FbMapSize - 1);
- }
- } else {
+ } else if((par->Architecture < NV_ARCH_40) ||
+ ((par->Chipset & 0xfff0) == 0x0040)) {
for (i = 0; i < 8; i++) {
NV_WR32(par->PFB, 0x0240 + (i * 0x10), 0);
- NV_WR32(par->PFB, 0x0244 + (i * 0x10), par->FbMapSize - 1);
+ NV_WR32(par->PFB, 0x0244 + (i * 0x10),
+ par->FbMapSize - 1);
+ }
+ } else {
+ int regions = 12;
+
+ if(((par->Chipset & 0xfff0) == 0x0090) ||
+ ((par->Chipset & 0xfff0) == 0x01D0) ||
+ ((par->Chipset & 0xfff0) == 0x0290))
+ regions = 15;
+
+ for(i = 0; i < regions; i++) {
+ NV_WR32(par->PFB, 0x0600 + (i * 0x10), 0);
+ NV_WR32(par->PFB, 0x0604 + (i * 0x10),
+ par->FbMapSize - 1);
}
}

@@ -1187,6 +1198,10 @@ void NVLoadStateExt(struct nvidia_par *p
NV_WR32(par->PGRAPH, 0x0090, 0x00008000);
NV_WR32(par->PGRAPH, 0x0610, 0x00be3c5f);

+ tmp = NV_RD32(par->REGS, 0x1540) & 0xff;
+ for(i = 0; tmp && !(tmp & 1); tmp >>= 1, i++);
+ NV_WR32(par->PGRAPH, 0x5000, i);
+
if ((par->Chipset & 0xfff0) == 0x0040) {
NV_WR32(par->PGRAPH, 0x09b0,
0x83280fff);
@@ -1211,6 +1226,7 @@ void NVLoadStateExt(struct nvidia_par *p
0xffff7fff);
break;
case 0x00C0:
+ case 0x0120:
NV_WR32(par->PGRAPH, 0x0828,
0x007596ff);
NV_WR32(par->PGRAPH, 0x082C,
@@ -1245,6 +1261,7 @@ void NVLoadStateExt(struct nvidia_par *p
0x00100000);
break;
case 0x0090:
+ case 0x0290:
NV_WR32(par->PRAMDAC, 0x0608,
NV_RD32(par->PRAMDAC, 0x0608) |
0x00100000);
@@ -1310,14 +1327,42 @@ void NVLoadStateExt(struct nvidia_par *p
}
}

- if ((par->Chipset & 0xfff0) == 0x0090) {
- for (i = 0; i < 60; i++)
- NV_WR32(par->PGRAPH, 0x0D00 + i,
- NV_RD32(par->PFB, 0x0600 + i));
- } else {
- for (i = 0; i < 32; i++)
+ if ((par->Architecture < NV_ARCH_40) ||
+ ((par->Chipset & 0xfff0) == 0x0040)) {
+ for(i = 0; i < 32; i++) {
NV_WR32(par->PGRAPH, 0x0900 + i,
NV_RD32(par->PFB, 0x0240 + i));
+ NV_WR32(par->PGRAPH, 0x6900 + i,
+ NV_RD32(par->PFB, 0x0240 + i));
+ }
+ } else {
+ if (((par->Chipset & 0xfff0) == 0x0090) ||
+ ((par->Chipset & 0xfff0) == 0x01D0) ||
+ ((par->Chipset & 0xfff0) == 0x0290)) {
+ for(i = 0; i < 60; i++) {
+ NV_WR32(par->PGRAPH, 0x0D00+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ NV_WR32(par->PGRAPH, 0x6900+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ }
+ } else {
+ for(i = 0; i < 48; i++) {
+ NV_WR32(par->PGRAPH, 0x0900+i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ if (((par->Chipset & 0xfff0) !=
+ 0x0160) &&
+ ((par->Chipset & 0xfff0) !=
+ 0x0220)) {
+ NV_WR32(par->PGRAPH,
+ 0x6900 + i,
+ NV_RD32(par->PFB,
+ 0x0600 + i));
+ }
+ }
+ }
}

if (par->Architecture >= NV_ARCH_40) {
@@ -1338,11 +1383,15 @@ void NVLoadStateExt(struct nvidia_par *p
NV_WR32(par->PGRAPH, 0x0868,
par->FbMapSize - 1);
} else {
- if((par->Chipset & 0xfff0) == 0x0090) {
+ if (((par->Chipset & 0xfff0)==0x0090)||
+ ((par->Chipset & 0xfff0)==0x01D0)||
+ ((par->Chipset & 0xfff0)==0x0290)){
NV_WR32(par->PGRAPH, 0x0DF0,
- NV_RD32(par->PFB, 0x0200));
+ NV_RD32(par->PFB,
+ 0x0200));
NV_WR32(par->PGRAPH, 0x0DF4,
- NV_RD32(par->PFB, 0x0204));
+ NV_RD32(par->PFB,
+ 0x0204));
} else {
NV_WR32(par->PGRAPH, 0x09F0,
NV_RD32(par->PFB, 0x0200));
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 1f06a9f..1330021 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -277,6 +277,9 @@ static void nv10GetConfig(struct nvidia_
(NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
}

+ if (par->RamAmountKBytes > 256*1024)
+ par->RamAmountKBytes = 256*1024;
+
par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
14318 : 13500;

@@ -285,7 +288,6 @@ static void nv10GetConfig(struct nvidia_
par->CrystalFreqKHz = 27000;
}

- par->CursorStart = (par->RamAmountKBytes - 96) * 1024;
par->CURSOR = NULL; /* can't set this here */
par->MinVClockFreqKHz = 12000;
par->MaxVClockFreqKHz = par->twoStagePLL ? 400000 : 350000;
@@ -382,6 +384,8 @@ void NVCommonSetup(struct fb_info *info)
case 0x0146:
case 0x0147:
case 0x0148:
+ case 0x0098:
+ case 0x0099:
mobile = 1;
break;
default:
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 961007d..19ab162 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1448,11 +1448,34 @@ static int __devinit nvidia_set_fbinfo(s
return nvidiafb_check_var(&info->var, info);
}

-static u32 __devinit nvidia_get_arch(struct pci_dev *pd)
+static u32 __devinit nvidia_get_chipset(struct fb_info *info)
{
+ struct nvidia_par *par = info->par;
+ u32 id = (par->pci_dev->vendor << 16) | par->pci_dev->device;
+
+ printk("nvidiafb: PCI id - %x\n", id);
+ if ((id & 0xfff0) == 0x00f0) {
+ /* pci-e */
+ printk("nvidiafb: PCI-E card\n");
+ id = NV_RD32(par->REGS, 0x1800);
+
+ if ((id & 0x0000ffff) == 0x000010DE)
+ id = 0x10DE0000 | (id >> 16);
+ else if ((id & 0xffff0000) == 0xDE100000) /* wrong endian */
+ id = 0x10DE0000 | ((id << 8) & 0x0000ff00) |
+ ((id >> 8) & 0x000000ff);
+ }
+
+ printk("nvidiafb: Actual id - %x\n", id);
+ return id;
+}
+
+static u32 __devinit nvidia_get_arch(struct fb_info *info)
+{
+ struct nvidia_par *par = info->par;
u32 arch = 0;

- switch (pd->device & 0x0ff0) {
+ switch (par->Chipset & 0x0ff0) {
case 0x0100: /* GeForce 256 */
case 0x0110: /* GeForce2 MX */
case 0x0150: /* GeForce2 */
@@ -1485,6 +1508,8 @@ static u32 __devinit nvidia_get_arch(str
case 0x0210:
case 0x0220:
case 0x0230:
+ case 0x0290:
+ case 0x0390:
arch = NV_ARCH_40;
break;
case 0x0020: /* TNT, TNT2 */
@@ -1533,16 +1558,8 @@ static int __devinit nvidiafb_probe(stru
goto err_out_request;
}

- par->Architecture = nvidia_get_arch(pd);
-
- par->Chipset = (pd->vendor << 16) | pd->device;
printk(KERN_INFO PFX "nVidia device/chipset %X\n", par->Chipset);

- if (par->Architecture == 0) {
- printk(KERN_ERR PFX "unknown NV_ARCH\n");
- goto err_out_free_base0;
- }
-
sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);

par->FlatPanel = flatpanel;
@@ -1570,6 +1587,14 @@ static int __devinit nvidiafb_probe(stru
goto err_out_free_base0;
}

+ par->Chipset = nvidia_get_chipset(info);
+ par->Architecture = nvidia_get_arch(info);
+
+ if (par->Architecture == 0) {
+ printk(KERN_ERR PFX "unknown NV_ARCH\n");
+ goto err_out_arch;
+ }
+
NVCommonSetup(info);

par->FbAddress = nvidiafb_fix.smem_start;
@@ -1581,10 +1606,15 @@ static int __devinit nvidiafb_probe(stru
if (par->FbMapSize > 64 * 1024 * 1024)
par->FbMapSize = 64 * 1024 * 1024;

- par->FbUsableSize = par->FbMapSize - (128 * 1024);
+ if(par->Architecture >= NV_ARCH_40)
+ par->FbUsableSize = par->FbMapSize - (560 * 1024);
+ else
+ par->FbUsableSize = par->FbMapSize - (128 * 1024);
+
par->ScratchBufferSize = (par->Architecture < NV_ARCH_10) ? 8 * 1024 :
16 * 1024;
par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
+ par->CursorStart = par->FbUsableSize + (32 * 1024);
info->screen_base = ioremap(nvidiafb_fix.smem_start, par->FbMapSize);
info->screen_size = par->FbUsableSize;
nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
@@ -1640,21 +1670,22 @@ static int __devinit nvidiafb_probe(stru
NVTRACE_LEAVE();
return 0;

- err_out_iounmap_fb:
+err_out_iounmap_fb:
iounmap(info->screen_base);
- err_out_free_base1:
+err_out_free_base1:
fb_destroy_modedb(info->monspecs.modedb);
nvidia_delete_i2c_busses(par);
+err_out_arch:
iounmap(par->REGS);
- err_out_free_base0:
+err_out_free_base0:
pci_release_regions(pd);
- err_out_request:
+err_out_request:
pci_disable_device(pd);
- err_out_enable:
+err_out_enable:
kfree(info->pixmap.addr);
- err_out_kfree:
+err_out_kfree:
framebuffer_release(info);
- err_out:
+err_out:
return -ENODEV;
}

2005-11-26 21:52:03

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: [PATCH] nvidiafb support for 6600 and 6200

Antonino A. Daplas wrote:
> Calin A. Culianu wrote:
>> Hi,
>>
>> This patch can be applied against 2.6.15-rc1 to add support to the
>> nvidiafb driver for a few obscure (yet on-the-market) nvidia
>> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>>
>> This patch has been tested and allows the above-mentioned boards to get
>> framebuffer console support.
>>
>
> Is this a pci-e card? With a pci-e card, the actual chipset type is located
> in one of the registers (instead of deriving it from the pci device id) and
> will resolve into one of the supported architectures, usually an NV_ARCH_40.
>
> Can you try this patch instead? And send me your dmesg whether it works or
> not.

Forgot to mention that you still have to add your device to nvidiafb_pci_tbl
after applying this patch.

Tony

2005-11-28 10:35:45

by Marc Burkhardt

[permalink] [raw]
Subject: nvidia fb flicker (was: Re: [PATCH] nvidiafb support for 6600 and 6200)

* Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:

> Hi,
>
> This patch can be applied against 2.6.15-rc1 to add support to the
> nvidiafb driver for a few obscure (yet on-the-market) nvidia
> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>
> This patch has been tested and allows the above-mentioned boards to get
> framebuffer console support.
>
> Thanks!
>
> -Calin

Hi all,

yesterday I compiled a 2.6.15-rc2 on one of my Inspirons (NVIDIA GeForce2 Go)
with nvidiafb. I just changed the fb to some 1600x1200 mode and thus seems to
work (the source states GeForce2 Go is supported and known). However, the
letters seems to 'flicker' in some way. Uhm, it's not really flickering, it's
more like the sinle dots a letter is made of seem to randomly turn on an off. I
one takes a closer look it seems like the whole screen is 'fluent' or something.
Does anybody know how to handle that? I didn't specify a video mode, but
'video=vesafb:mtrr:3'.

Regards,
Marc

2005-11-28 12:32:15

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: nvidia fb flicker

Marc Koschewski wrote:
> * Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:
>
>> Hi,
>>
>> This patch can be applied against 2.6.15-rc1 to add support to the
>> nvidiafb driver for a few obscure (yet on-the-market) nvidia
>> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>>
>> This patch has been tested and allows the above-mentioned boards to get
>> framebuffer console support.
>>
>> Thanks!
>>
>> -Calin
>
> Hi all,
>
> yesterday I compiled a 2.6.15-rc2 on one of my Inspirons (NVIDIA GeForce2 Go)
> with nvidiafb. I just changed the fb to some 1600x1200 mode and thus seems to
> work (the source states GeForce2 Go is supported and known). However, the
> letters seems to 'flicker' in some way. Uhm, it's not really flickering, it's
> more like the sinle dots a letter is made of seem to randomly turn on an off. I

Can you try booting with video=nvidiafb:1600x1200MR@60?

If that still does not work, can you open drivers/video/fbmon.c then change
the line #undef DEBUG to #define DEBUG, recompile, reboot and post your
dmesg?

> one takes a closer look it seems like the whole screen is 'fluent' or something.
> Does anybody know how to handle that? I didn't specify a video mode, but
> 'video=vesafb:mtrr:3'.
>

No, remove any vga= and video=vesafb: strings in your boot options.

Tony

2005-11-28 13:20:25

by Marc Burkhardt

[permalink] [raw]
Subject: Re: nvidia fb flicker

* Antonino A. Daplas <[email protected]> [2005-11-28 20:31:30 +0800]:

> Marc Koschewski wrote:
> > * Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:
> >
> >> Hi,
> >>
> >> This patch can be applied against 2.6.15-rc1 to add support to the
> >> nvidiafb driver for a few obscure (yet on-the-market) nvidia
> >> boards/chipsets, including various versions of the Geforce 6600 and 6200.
> >>
> >> This patch has been tested and allows the above-mentioned boards to get
> >> framebuffer console support.
> >>
> >> Thanks!
> >>
> >> -Calin
> >
> > Hi all,
> >
> > yesterday I compiled a 2.6.15-rc2 on one of my Inspirons (NVIDIA GeForce2 Go)
> > with nvidiafb. I just changed the fb to some 1600x1200 mode and thus seems to
> > work (the source states GeForce2 Go is supported and known). However, the
> > letters seems to 'flicker' in some way. Uhm, it's not really flickering, it's
> > more like the sinle dots a letter is made of seem to randomly turn on an off. I
>
> Can you try booting with video=nvidiafb:1600x1200MR@60?
>
> If that still does not work, can you open drivers/video/fbmon.c then change
> the line #undef DEBUG to #define DEBUG, recompile, reboot and post your
> dmesg?
>
> > one takes a closer look it seems like the whole screen is 'fluent' or something.
> > Does anybody know how to handle that? I didn't specify a video mode, but
> > 'video=vesafb:mtrr:3'.
> >
>
> No, remove any vga= and video=vesafb: strings in your boot options.

So, I just booted with the parameter given by you (and without vga= as usual), as
well as without any parameter. No change though.

Here's my relevant messages stuff with DEBUG enabled:

Nov 28 14:02:31 stiffy kernel: nvidiafb: nVidia device/chipset 10DE0112
Nov 28 14:02:31 stiffy kernel: nvidiafb: EDID found from BUS2
Nov 28 14:02:31 stiffy kernel: ========================================
Nov 28 14:02:31 stiffy kernel: Display Information (EDID)
Nov 28 14:02:31 stiffy kernel: ========================================
Nov 28 14:02:31 stiffy kernel: EDID Version 1.3
Nov 28 14:02:31 stiffy kernel: Manufacturer: SHP
Nov 28 14:02:31 stiffy kernel: Model: 138e
Nov 28 14:02:31 stiffy kernel: Serial#: 0
Nov 28 14:02:31 stiffy kernel: Year: 1990 Week 0
Nov 28 14:02:31 stiffy kernel: Display Characteristics:
Nov 28 14:02:32 stiffy kernel: Monitor Operating Limits: Detailed Timings
Nov 28 14:02:32 stiffy kernel: 160 MHz 1600 1664 1856 2112 1200 1201 1204 1250 -HSync -VSync
Nov 28 14:02:32 stiffy kernel:
Nov 28 14:02:32 stiffy kernel: Supported VESA Modes
Nov 28 14:02:32 stiffy kernel: Manufacturer's mask: 0
Nov 28 14:02:32 stiffy kernel: Standard Timings
Nov 28 14:02:32 stiffy kernel: 1600x1200@60Hz
Nov 28 14:02:32 stiffy kernel: Extrapolated
Nov 28 14:02:32 stiffy kernel: H: 75-75KHz V: 60-60Hz DCLK: 162MHz
Nov 28 14:02:32 stiffy kernel: Digital Display Input

Marc

2005-11-28 14:01:36

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: nvidia fb flicker

Marc Koschewski wrote:
> * Antonino A. Daplas <[email protected]> [2005-11-28 20:31:30 +0800]:
>
>> Marc Koschewski wrote:
>>> * Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:
>>>
>>>> Hi,
>>>>
>>>> This patch can be applied against 2.6.15-rc1 to add support to the
>>>> nvidiafb driver for a few obscure (yet on-the-market) nvidia
>>>> boards/chipsets, including various versions of the Geforce 6600 and 6200.
>>>>
>>>> This patch has been tested and allows the above-mentioned boards to get
>>>> framebuffer console support.
>>>>
>>>> Thanks!
>>>>
>>>> -Calin
>>> Hi all,
>>>
>>> yesterday I compiled a 2.6.15-rc2 on one of my Inspirons (NVIDIA GeForce2 Go)
>>> with nvidiafb. I just changed the fb to some 1600x1200 mode and thus seems to
>>> work (the source states GeForce2 Go is supported and known). However, the
>>> letters seems to 'flicker' in some way. Uhm, it's not really flickering, it's
>>> more like the sinle dots a letter is made of seem to randomly turn on an off. I
>> Can you try booting with video=nvidiafb:1600x1200MR@60?
>>
>> If that still does not work, can you open drivers/video/fbmon.c then change
>> the line #undef DEBUG to #define DEBUG, recompile, reboot and post your
>> dmesg?
>>
>>> one takes a closer look it seems like the whole screen is 'fluent' or something.
>>> Does anybody know how to handle that? I didn't specify a video mode, but
>>> 'video=vesafb:mtrr:3'.
>>>
>> No, remove any vga= and video=vesafb: strings in your boot options.
>
> So, I just booted with the parameter given by you (and without vga= as usual), as
> well as without any parameter. No change though.
>

Try again with CONFIG_FB_NVIDIA_I2C = n in your kernel config.

Tony

2005-11-28 21:24:10

by Marc Burkhardt

[permalink] [raw]
Subject: Re: nvidia fb flicker

* Antonino A. Daplas <[email protected]> [2005-11-28 22:00:41 +0800]:

> Marc Koschewski wrote:
> > * Antonino A. Daplas <[email protected]> [2005-11-28 20:31:30 +0800]:
> >
> >> Marc Koschewski wrote:
> >>> * Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:
> >>>
> >>>> Hi,
> >>>>
> >>>> This patch can be applied against 2.6.15-rc1 to add support to the
> >>>> nvidiafb driver for a few obscure (yet on-the-market) nvidia
> >>>> boards/chipsets, including various versions of the Geforce 6600 and 6200.
> >>>>
> >>>> This patch has been tested and allows the above-mentioned boards to get
> >>>> framebuffer console support.
> >>>>
> >>>> Thanks!
> >>>>
> >>>> -Calin
> >>> Hi all,
> >>>
> >>> yesterday I compiled a 2.6.15-rc2 on one of my Inspirons (NVIDIA GeForce2 Go)
> >>> with nvidiafb. I just changed the fb to some 1600x1200 mode and thus seems to
> >>> work (the source states GeForce2 Go is supported and known). However, the
> >>> letters seems to 'flicker' in some way. Uhm, it's not really flickering, it's
> >>> more like the sinle dots a letter is made of seem to randomly turn on an off. I
> >> Can you try booting with video=nvidiafb:1600x1200MR@60?
> >>
> >> If that still does not work, can you open drivers/video/fbmon.c then change
> >> the line #undef DEBUG to #define DEBUG, recompile, reboot and post your
> >> dmesg?
> >>
> >>> one takes a closer look it seems like the whole screen is 'fluent' or something.
> >>> Does anybody know how to handle that? I didn't specify a video mode, but
> >>> 'video=vesafb:mtrr:3'.
> >>>
> >> No, remove any vga= and video=vesafb: strings in your boot options.
> >
> > So, I just booted with the parameter given by you (and without vga= as usual), as
> > well as without any parameter. No change though.
> >
>
> Try again with CONFIG_FB_NVIDIA_I2C = n in your kernel config.
>
> Tony

Tony,
it works. Could you explain me, what the difference is? :/

Marc

2005-11-28 22:21:03

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: nvidia fb flicker

Marc Koschewski wrote:
> * Antonino A. Daplas <[email protected]> [2005-11-28 22:00:41 +0800]:
>
>> Marc Koschewski wrote:
>>> * Antonino A. Daplas <[email protected]> [2005-11-28 20:31:30 +0800]:
>>>
>>>> Marc Koschewski wrote:
>>>>> * Calin A. Culianu <[email protected]> [2005-11-26 00:02:46 -0500]:
>>>>>
>>>
>> Try again with CONFIG_FB_NVIDIA_I2C = n in your kernel config.
>>
>> Tony
>
> Tony,
> it works. Could you explain me, what the difference is? :/
>

The problem is nvidiafb trusts the EDID block as gospel truth :-)

You happen to have an EDID block which left the most important fields
blank -- the hsync and vsync range. So the EDID parser extrapolated
the ranges, but since the block has only a single mode entry, 1600x1200@60,
what you get is this:

Nov 28 14:02:32 stiffy kernel: Extrapolated
Nov 28 14:02:32 stiffy kernel: H: 75-75KHz V: 60-60Hz DCLK: 162MHz

Since the min and max value of the sync timings are equal, nvidiafb has
no room left to verify the timings, and will _always_ reject any timings even
if they are valid.

So, try this patch, we make nvidiafb less restrictive by ignoring the
hsync and vsync ranges if the min and max values are equal. This should
make your hardware display properly even if CONFIG_FB_NVIDIA_I2c = y.

Tony


diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 961007d..ff28610 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1239,7 +1239,9 @@ static int nvidiafb_check_var(struct fb_
}
}

- if (!mode_valid && info->monspecs.modedb_len)
+ if (!mode_valid && info->monspecs.modedb_len &&
+ !(info->monspecs.hfmin == info->monspecs.hfmax &&
+ info->monspecs.vfmin == info->monspecs.vfmax))
return -EINVAL;

if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||

2005-11-28 23:01:40

by Linus Torvalds

[permalink] [raw]
Subject: Re: nvidia fb flicker



On Tue, 29 Nov 2005, Antonino A. Daplas wrote:
>
> Nov 28 14:02:32 stiffy kernel: Extrapolated
> Nov 28 14:02:32 stiffy kernel: H: 75-75KHz V: 60-60Hz DCLK: 162MHz
>
> Since the min and max value of the sync timings are equal, nvidiafb has
> no room left to verify the timings, and will _always_ reject any timings even
> if they are valid.
>
> So, try this patch, we make nvidiafb less restrictive by ignoring the
> hsync and vsync ranges if the min and max values are equal. This should
> make your hardware display properly even if CONFIG_FB_NVIDIA_I2c = y.

Tony,

may I suggestinstead making the verifier allow a small error?

I don't find it at all unlikely that some EDID blocks might say that only
a 60Hz refresh rate is allowed. A lot of LCD's are literally specced for
that (just read their manuals), even though they often in practice allow
other frequencies (often _wildly_ different - most modern LCD's are
perfectly happy to sync up with almost anything).

And if a monitor says that it wants a vertical frequency of 60Hz, a mode
that has a frequency of 59 should certainly be accepted.

So it sounds like something has marked a perfectly valid mode as invalid,
just because it's not _exactly_ at the frequency.

So how about allowing a small error in the frequencies in
fb_validate_mode()? And make sure to try to round the divisions to
nearest, not down. Something like the appended (totally untested)..

Linus

----
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index fc7965b..15b0e7e 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -1261,10 +1261,15 @@ int fb_validate_mode(const struct fb_var
if (var->vmode & FB_VMODE_DOUBLE)
vtotal *= 2;

- hfreq = pixclock/htotal;
+ hfreq = (pixclock + htotal/2) / htotal;
hfreq = (hfreq + 500) / 1000 * 1000;

- vfreq = hfreq/vtotal;
+ vfreq = (hfreq + vtotal/2) / vtotal;
+
+ /* Allow a 3% error */
+ vfmin -= vfmin >> 5; vfmax += vfmax >> 5;
+ hfmin -= hfmin >> 5; hfmax += hfmax >> 5;
+

return (vfreq < vfmin || vfreq > vfmax ||
hfreq < hfmin || hfreq > hfmax ||

2005-11-29 00:14:13

by Antonino A. Daplas

[permalink] [raw]
Subject: Re: nvidia fb flicker

Linus Torvalds wrote:
>
> On Tue, 29 Nov 2005, Antonino A. Daplas wrote:
>> Nov 28 14:02:32 stiffy kernel: Extrapolated
>> Nov 28 14:02:32 stiffy kernel: H: 75-75KHz V: 60-60Hz DCLK: 162MHz
>>
>> Since the min and max value of the sync timings are equal, nvidiafb has
>> no room left to verify the timings, and will _always_ reject any timings even
>> if they are valid.
>>
>> So, try this patch, we make nvidiafb less restrictive by ignoring the
>> hsync and vsync ranges if the min and max values are equal. This should
>> make your hardware display properly even if CONFIG_FB_NVIDIA_I2c = y.
>
> Tony,
>
> may I suggestinstead making the verifier allow a small error?
>
> I don't find it at all unlikely that some EDID blocks might say that only
> a 60Hz refresh rate is allowed. A lot of LCD's are literally specced for
> that (just read their manuals), even though they often in practice allow
> other frequencies (often _wildly_ different - most modern LCD's are
> perfectly happy to sync up with almost anything).
>
> And if a monitor says that it wants a vertical frequency of 60Hz, a mode
> that has a frequency of 59 should certainly be accepted.
>
> So it sounds like something has marked a perfectly valid mode as invalid,
> just because it's not _exactly_ at the frequency.
>
> So how about allowing a small error in the frequencies in
> fb_validate_mode()? And make sure to try to round the divisions to
> nearest, not down. Something like the appended (totally untested)..
>

Yes, your patch looks good, and will fix some of the reports I've received.

However, after giving it some more thought, I believe my original
reasoning is probably incorrect. Because if nvidiafb rejected the
mode timings, nvidiafb would not have loaded at all, but it did.

Which leads me to conclude that Calin's display EDID, specifically the
timing information, is totally garbage.

Calin, can you verify? Set CONFIG_FB_NVIDIA_I2C = y.

First, apply Linus' patch, then boot without any options. If you get a
nice display, then my original reasoning is correct, and Linus' patch
is all we need.

Secondly, if you get a corrupt display after doing the above, then apply
my patch and boot without any options. If you get a working display,
something is wrong with Linus' patch :-) But most probably you'll also get
a corrupt display, so...

Finally, boot with video=nvidiafb:1600x1200MR@60. If you reach this stage
and you get a working display, then the conclusion is that you have a
garbage EDID block :-). And we will need both Linus' patch plus another
patch, perhaps a boot option that tells nvidiafb to totally ignore the
EDID block. (We don't want to disable the i2c bus because this is still
useful in userspace).

Tony