updates needed to detect early AGP1.0 no-feature devices, and abort on PCI nVidia cards

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8290 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rudolf Cornelissen
2004-07-04 15:06:08 +00:00
parent e978056417
commit 6ca49bc0c1
+83 -18
View File
@@ -1,5 +1,9 @@
/* Author: /* Author:
Rudolf Cornelissen 6/2004 Rudolf Cornelissen 6/2004-7/2004
Note:
This stuff will probably be relocated to the AGP busmanager module later on,
but for now we have something to test with...
*/ */
#define MODULE_BIT 0x00000100 #define MODULE_BIT 0x00000100
@@ -8,6 +12,10 @@
#include "nv_std.h" #include "nv_std.h"
static void nv_agp_list_caps(agp_info ai); static void nv_agp_list_caps(agp_info ai);
static bool has_AGP_interface(agp_info *ai_card, uint8 *adress);
#define PCI_CFGR(A) (nv_pci_access.offset = A, ioctl(fd,NV_GET_PCI, &nv_pci_access, sizeof(nv_pci_access)), nv_pci_access.value)
#define PCI_CFGW(A,B) (nv_pci_access.offset = A, nv_pci_access.value = B, ioctl(fd,NV_SET_PCI,&nv_pci_access,sizeof(nv_pci_access)))
status_t nv_agp_setup(void) status_t nv_agp_setup(void)
{ {
@@ -15,14 +23,19 @@ status_t nv_agp_setup(void)
int agp_fd; int agp_fd;
agp_info ai_card, ai_bridge; agp_info ai_card, ai_bridge;
uint8 rq_depth_card, rq_depth_bridge; uint8 rq_depth_card, rq_depth_bridge;
uint8 adress;
/* check for card's AGP capabilities and list them */ /* check for card's AGP capabilities - see PCI specification */
ai_card.config.agp_cap_id = CFGR(AGPREF); /* Note:
ai_card.config.agp_stat = CFGR(AGPSTAT); * We have to iterate through the capability list as specified in the PCI spec,
ai_card.config.agp_cmd = CFGR(AGPCMD); * otherwise we cannot distinquish between nVidia PCI and AGP cards!
* (PCI cards still have AGP registers that pretend to support AGP) */
if ((ai_card.config.agp_cap_id & 0x00ff0000) && ((ai_card.config.agp_cap_id & AGP_id_mask) == AGP_id)) if (!(has_AGP_interface(&ai_card, &adress)))
{ {
LOG(4,("AGP: graphicscard is PCI type.\n"));
return B_ERROR;
}
LOG(4,("AGP: graphicscard is AGP type, supporting specification %d.%d;\n", LOG(4,("AGP: graphicscard is AGP type, supporting specification %d.%d;\n",
((ai_card.config.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift), ((ai_card.config.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift),
((ai_card.config.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift))); ((ai_card.config.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift)));
@@ -37,7 +50,7 @@ status_t nv_agp_setup(void)
{ {
LOG(4,("AGP: cannot open AGP host bridge driver, aborting!\n")); LOG(4,("AGP: cannot open AGP host bridge driver, aborting!\n"));
/* program card for PCI access */ /* program card for PCI access */
CFGW(AGPCMD, 0x00000000); PCI_CFGW((adress + 8), 0x00000000);
return B_ERROR; return B_ERROR;
} }
@@ -53,7 +66,7 @@ status_t nv_agp_setup(void)
/* close host bridge driver */ /* close host bridge driver */
close(agp_fd); close(agp_fd);
/* program card for PCI access */ /* program card for PCI access */
CFGW(AGPCMD, 0x00000000); PCI_CFGW((adress + 8), 0x00000000);
return B_ERROR; return B_ERROR;
} }
@@ -72,9 +85,24 @@ status_t nv_agp_setup(void)
/* close host bridge driver */ /* close host bridge driver */
close(agp_fd); close(agp_fd);
/* program card for PCI access */ /* program card for PCI access */
CFGW(AGPCMD, 0x00000000); PCI_CFGW((adress + 8), 0x00000000);
return B_OK; return B_ERROR;
}
/* find out if AGP modes are supported: devices exist that have the AGP style
* connector with AGP style registers, but not the features!
* (confirmed Matrox Millenium II AGP for instance) */
if (!(ai_card.config.agp_stat & AGP_rates) ||
!(ai_bridge.config.agp_stat & AGP_rates))
{
LOG(4,("AGP: no AGP modes possible, aborting AGP setup!\n"));
/* close host bridge driver */
close(agp_fd);
/* program card for PCI access */
PCI_CFGW((adress + 8), 0x00000000);
return B_ERROR;
} }
/* find out shared AGP capabilities of card and host bridge */ /* find out shared AGP capabilities of card and host bridge */
@@ -85,7 +113,7 @@ status_t nv_agp_setup(void)
/* close host bridge driver */ /* close host bridge driver */
close(agp_fd); close(agp_fd);
/* program card for PCI access */ /* program card for PCI access */
CFGW(AGPCMD, 0x00000000); PCI_CFGW((adress + 8), 0x00000000);
return B_ERROR; return B_ERROR;
} }
@@ -188,17 +216,14 @@ status_t nv_agp_setup(void)
/* note: /* note:
* the AGP standard defines that the host bridge should be enabled first. */ * the AGP standard defines that the host bridge should be enabled first. */
ioctl(agp_fd, SET_CONFIG, &ai_bridge); ioctl(agp_fd, SET_CONFIG, &ai_bridge);
CFGW(AGPCMD, ai_card.config.agp_cmd); PCI_CFGW((adress + 8), ai_card.config.agp_cmd);
LOG(4,("AGP: graphics card AGPCMD register readback $%08x\n", CFGR(AGPCMD))); LOG(4,("AGP: graphics card AGPCMD register readback $%08x\n", CFGR(AGPCMD)));
/* close host bridge driver */ /* close host bridge driver */
close(agp_fd); close(agp_fd);
}
else return B_OK;
{
LOG(4,("AGP: graphicscard is PCI type.\n"));
}
} }
static void nv_agp_list_caps(agp_info ai) static void nv_agp_list_caps(agp_info ai)
@@ -282,3 +307,43 @@ static void nv_agp_list_caps(agp_info ai)
else else
LOG(4,("AGP: this AGP interface is currently disabled.\n")); LOG(4,("AGP: this AGP interface is currently disabled.\n"));
} }
static bool has_AGP_interface(agp_info *ai_card, uint8 *adress)
{
bool has_AGP = false;
/* check if device implements a list of capabilities */
if (CFGR(DEVCTRL) & 0x00100000)
{
uint32 item;
uint8 item_adress;
/* get pointer to PCI capabilities list */
item_adress = CFGR(CFG_0) & 0x000000ff;
/* read first item from list */
item = PCI_CFGR(item_adress);
while ((item & AGP_next_ptr) && ((item & AGP_id_mask) != AGP_id))
{
/* read next item from list */
item_adress = ((item & AGP_next_ptr) >> AGP_next_ptr_shift);
item = PCI_CFGR(item_adress);
}
if ((item & AGP_id_mask) == AGP_id)
{
/* we found the AGP interface! */
has_AGP = true;
/* return the adress if the interface */
*adress = item_adress;
/* readout the AGP interface capabilities and settings */
ai_card->config.agp_cap_id = PCI_CFGR(item_adress);
ai_card->config.agp_stat = PCI_CFGR(item_adress + 4);
ai_card->config.agp_cmd = PCI_CFGR(item_adress + 8);
}
}
return has_AGP;
}
#undef PCI_CFGR
#undef PCI_CFGW