From 6f5b352e7757f581f629ca8d75cfd73c1a31baf2 Mon Sep 17 00:00:00 2001
From: Rudolf Cornelissen
Date: Tue, 11 Apr 2006 10:51:47 +0000
Subject: [PATCH] AGP busmanager updated: the order of programming devices did
not adhere to the AGP specification, in case PCI mode was entered (while AGP
mode was active before). This fixes the last trouble with (at least) nVidia
GeForce 4 MX 4000 cards attempting to coldstart with AGP mode.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17070 a95241bf-73f2-0310-859d-f6bbb57e9c96
---
.../kernel/bus_managers/agp/UPDATE.html | 4 +
src/add-ons/kernel/bus_managers/agp/agp.cpp | 86 +++++++++++++------
2 files changed, 66 insertions(+), 24 deletions(-)
diff --git a/src/add-ons/kernel/bus_managers/agp/UPDATE.html b/src/add-ons/kernel/bus_managers/agp/UPDATE.html
index 8727783a3e..2d7dfd89d4 100644
--- a/src/add-ons/kernel/bus_managers/agp/UPDATE.html
+++ b/src/add-ons/kernel/bus_managers/agp/UPDATE.html
@@ -4,6 +4,10 @@
Changes done for each module version:
+agp_module 0.02, (Rudolf)
+
+ - Reversed order of programming devices when AGP mode is requested to be disabled. The order of programming devices now adheres to the official AGP specification (missed this item before). This fixes potential coldstart trouble on nVidia cards at least (confirmed a GeForce 4 MX4000).
+
agp_module 0.01, (Rudolf)
- Initial release.
diff --git a/src/add-ons/kernel/bus_managers/agp/agp.cpp b/src/add-ons/kernel/bus_managers/agp/agp.cpp
index ffdca7fc74..978383c691 100644
--- a/src/add-ons/kernel/bus_managers/agp/agp.cpp
+++ b/src/add-ons/kernel/bus_managers/agp/agp.cpp
@@ -1,5 +1,5 @@
/*
- written by Rudolf Cornelissen 7/2004
+ written by Rudolf Cornelissen 7/2004-4/2006
*/
/*
@@ -343,36 +343,74 @@ void enable_agp (uint32 *command)
* registers simultanously with the other bits if a single 32bit write
* to each register is used. */
- /* first program all bridges */
- for (count = 0; count < pd->count; count++)
+ /* the order of programming differs for enabling/disabling AGP mode (see AGP specification) */
+ if (*command & AGP_enable)
{
- if (pd->di[count].agpi.class_base == PCI_bridge)
+ /* first program all bridges */
+ for (count = 0; count < pd->count; count++)
{
- pcii = &(pd->di[count].pcii);
- /* program bridge, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~(AGP_rate_rev | AGP_RQ)));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ if (pd->di[count].agpi.class_base == PCI_bridge)
+ {
+ pcii = &(pd->di[count].pcii);
+ /* program bridge, making sure not-implemented bits are written as zeros */
+ set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~(AGP_rate_rev | AGP_RQ)));
+ /* update our agp_cmd info with read back setting from register just programmed */
+ pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ }
+ }
+
+ /* wait 10mS for the bridges to recover (failsafe!) */
+ /* note:
+ * some SiS bridge chipsets apparantly require 5mS to recover or the
+ * master (graphics card) cannot be initialized correctly! */
+ snooze(10000);
+
+ /* _now_ program all graphicscards */
+ for (count = 0; count < pd->count; count++)
+ {
+ if (pd->di[count].agpi.class_base == PCI_display)
+ {
+ pci_info *pcii = &(pd->di[count].pcii);
+ /* program graphicscard, making sure not-implemented bits are written as zeros */
+ set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~AGP_rate_rev));
+ /* update our agp_cmd info with read back setting from register just programmed */
+ pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ }
}
}
-
- /* wait 10mS for the bridges to recover (failsafe!) */
- /* note:
- * some SiS bridge chipsets apparantly require 5mS to recover or the
- * master (graphics card) cannot be initialized correctly! */
- snooze(10000);
-
- /* _now_ program all graphicscards */
- for (count = 0; count < pd->count; count++)
+ else
{
- if (pd->di[count].agpi.class_base == PCI_display)
+ /* first program all graphicscards */
+ for (count = 0; count < pd->count; count++)
{
- pci_info *pcii = &(pd->di[count].pcii);
- /* program graphicscard, making sure not-implemented bits are written as zeros */
- set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~AGP_rate_rev));
- /* update our agp_cmd info with read back setting from register just programmed */
- pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ if (pd->di[count].agpi.class_base == PCI_display)
+ {
+ pci_info *pcii = &(pd->di[count].pcii);
+ /* program graphicscard, making sure not-implemented bits are written as zeros */
+ set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~AGP_rate_rev));
+ /* update our agp_cmd info with read back setting from register just programmed */
+ pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ }
}
+
+ /* _now_ program all bridges */
+ for (count = 0; count < pd->count; count++)
+ {
+ if (pd->di[count].agpi.class_base == PCI_bridge)
+ {
+ pcii = &(pd->di[count].pcii);
+ /* program bridge, making sure not-implemented bits are written as zeros */
+ set_pci(pd->di[count].agp_adress + 8, 4, (*command & ~(AGP_rate_rev | AGP_RQ)));
+ /* update our agp_cmd info with read back setting from register just programmed */
+ pd->di[count].agpi.interface.agp_cmd = get_pci(pd->di[count].agp_adress + 8, 4);
+ }
+ }
+
+ /* wait 10mS for the bridges to recover (failsafe!) */
+ /* note:
+ * some SiS bridge chipsets apparantly require 5mS to recover or the
+ * master (graphics card) cannot be initialized correctly! */
+ snooze(10000);
}
}