xref: /haiku/src/add-ons/accelerants/nvidia/engine/nv_agp.c (revision 0b2dbe7d46ee888392907c60131b7f7652314175)
1 /* Author:
2    Rudolf Cornelissen 6/2004-5/2005
3 */
4 
5 #define MODULE_BIT 0x00000100
6 
7 #include <unistd.h>
8 #include "nv_std.h"
9 
10 static void nv_agp_list_info(agp_info ai);
11 static void nv_agp_list_active(uint32 cmd);
12 
13 status_t nv_agp_setup(void)
14 {
15 	nv_nth_agp_info nai;
16 	nv_cmd_agp nca;
17 	uint8 index;
18 	agp_info nv_ai;
19 	bool agp = false;
20 
21 	/* preset we are running in PCI mode: so acc engine may not use AGP transfers */
22 	si->engine.agp_mode = false;
23 
24 	/* first try to enable FW support on our card if user requested this
25 	 * ('unsupported' tweak!)
26 	 * This has no effect on PCI cards. */
27 	if (si->settings.unhide_fw)
28 	{
29 		uint32 reg;
30 
31 		LOG(4, ("AGP: STRAPINFO2 contains $%08x\n", NV_REG32(NV32_NVSTRAPINFO2)));
32 
33 		LOG(4, ("AGP: attempting to enable fastwrite support..\n"));
34 		/* 'force' FW support */
35 		reg = (NV_REG32(NV32_NVSTRAPINFO2) & ~0x00000800);
36 		/* enable strapinfo overwrite */
37 		NV_REG32(NV32_NVSTRAPINFO2) = (reg | 0x80000000);
38 
39 		LOG(4, ("AGP: STRAPINFO2 now contains $%08x\n", NV_REG32(NV32_NVSTRAPINFO2)));
40 	}
41 
42 	/* set the magic number so the nvidia kerneldriver knows we're for real */
43 	nca.magic = nai.magic = NV_PRIVATE_DATA_MAGIC;
44 
45 	/* contact driver and get a pointer to the registers and shared data */
46 	for (index = 0; index < 8; index++)
47 	{
48 		/* get nth AGP device info */
49 		nai.index = index;
50 		ioctl(fd, NV_GET_NTH_AGP_INFO, &nai, sizeof(nai));
51 
52 		/* abort if no agp busmanager found */
53 		if (!nai.agp_bus)
54 		{
55 			LOG(4,("AGP: no AGP busmanager found.\n"));
56 			/* don't touch AGP command register, we don't know what has been setup:
57 			 * touching it anyway might 'hang' the graphics card! */
58 
59 			return B_ERROR;
60 		}
61 
62 		/* exit if we didn't get device info for this index */
63 		if (!nai.exist)
64 		{
65 			if (index != 0)
66 				LOG(4,("AGP: end of AGP capable devices list.\n"));
67 			else
68 				LOG(4,("AGP: no AGP capable devices found.\n"));
69 			break;
70 		}
71 
72 		LOG(4,("AGP: AGP capable device #%d:\n", (index + 1)));
73 
74 		/* see if we are this one */
75 		if ((nai.agpi.device_id == si->device_id) &&
76 			(nai.agpi.vendor_id == si->vendor_id) &&
77 			(nai.agpi.bus == si->bus) &&
78 			(nai.agpi.device == si->device) &&
79 			(nai.agpi.function == si->function))
80 		{
81 			LOG(4,("AGP: (this is the device this accelerant controls)\n"));
82 			agp = true;
83 			/* remember our info */
84 			nv_ai = nai.agpi;
85 		}
86 
87 		/* log capabilities */
88 		nv_agp_list_info(nai.agpi);
89 	}
90 
91 	/* if our card is not an AGP type, abort here */
92 	/* Note:
93 	 * We have to iterate through the capability list as specified in the PCI spec
94 	 * one way or the other, otherwise we cannot distinquish between nVidia PCI and
95 	 * AGP type cards as nVidia PCI cards still have AGP registers that pretend to
96 	 * support AGP.
97 	 * We rely on the AGP busmanager to iterate trough this list for us. */
98 	if (!agp)
99 	{
100 		LOG(4,("AGP: the graphicscard this accelerant controls is PCI type.\n"));
101 
102 		/* make sure card is set for PCI access */
103 		CFGW(AGPCMD, 0x00000000);
104 
105 		return B_ERROR;
106 	}
107 
108 	if (si->settings.force_pci)
109 	{
110 		/* set PCI mode if specified by user in nv.settings */
111 		LOG(4,("AGP: forcing PCI mode (specified in nv.settings)\n"));
112 
113 		/* let the AGP busmanager setup PCI mode.
114 		 * (the AGP speed scheme is of no consequence now) */
115 		nca.cmd = 0x00000000;
116 		ioctl(fd, NV_ENABLE_AGP, &nca, sizeof(nca));
117 	}
118 	else
119 	{
120 		/* activate AGP mode */
121 		LOG(4,("AGP: activating AGP mode...\n"));
122 
123 		/* let the AGP busmanager worry about what mode to set.. */
124 		nca.cmd = 0xfffffff7;
125 		/* ..but we do need to select the right speed scheme fetched from our card */
126 		if (nv_ai.interface.agp_stat & AGP_rate_rev) nca.cmd |= AGP_rate_rev;
127 		ioctl(fd, NV_ENABLE_AGP, &nca, sizeof(nca));
128 		/* tell the engine in may use AGP transfers */
129 		si->engine.agp_mode = true;
130 	}
131 
132 	/* list mode now activated,
133 	 * make sure we have the correct speed scheme for logging */
134 	nv_agp_list_active(nca.cmd | (nv_ai.interface.agp_stat & AGP_rate_rev));
135 
136 	/* extra check */
137 	LOG(4,("AGP: graphics card AGPCMD register readback $%08x\n", CFGR(AGPCMD)));
138 	return B_OK;
139 }
140 
141 static void nv_agp_list_info(agp_info ai)
142 {
143 	/*
144 		list device
145 	*/
146 	if (ai.class_base == PCI_display)
147 		LOG(4,("AGP: device is a graphicscard, subclass ID is $%02x\n", ai.class_sub));
148 	else
149 		LOG(4,("AGP: device is a hostbridge, subclass ID is $%02x\n", ai.class_sub));
150 	LOG(4,("AGP: vendor ID $%04x\n", ai.vendor_id));
151 	LOG(4,("AGP: device ID $%04x\n", ai.device_id));
152 	LOG(4,("AGP: bus %d, device %d, function %d\n", ai.bus, ai.device, ai.function));
153 
154 	/*
155 		list capabilities
156 	*/
157 	LOG(4,("AGP: this device supports AGP specification %d.%d;\n",
158 		((ai.interface.agp_cap_id & AGP_rev_major) >> AGP_rev_major_shift),
159 		((ai.interface.agp_cap_id & AGP_rev_minor) >> AGP_rev_minor_shift)));
160 
161 	/* the AGP devices determine AGP speed scheme version used on power-up/reset */
162 	if (!(ai.interface.agp_stat & AGP_rate_rev))
163 	{
164 		/* AGP 2.0 scheme applies */
165 		if (ai.interface.agp_stat & AGP_2_1x)
166 			LOG(4,("AGP: AGP 2.0 1x mode is available\n"));
167 		if (ai.interface.agp_stat & AGP_2_2x)
168 			LOG(4,("AGP: AGP 2.0 2x mode is available\n"));
169 		if (ai.interface.agp_stat & AGP_2_4x)
170 			LOG(4,("AGP: AGP 2.0 4x mode is available\n"));
171 	}
172 	else
173 	{
174 		/* AGP 3.0 scheme applies */
175 		if (ai.interface.agp_stat & AGP_3_4x)
176 			LOG(4,("AGP: AGP 3.0 4x mode is available\n"));
177 		if (ai.interface.agp_stat & AGP_3_8x)
178 			LOG(4,("AGP: AGP 3.0 8x mode is available\n"));
179 	}
180 	if (ai.interface.agp_stat & AGP_FW) LOG(4,("AGP: fastwrite transfers are supported\n"));
181 	if (ai.interface.agp_stat & AGP_SBA) LOG(4,("AGP: sideband adressing is supported\n"));
182 	LOG(4,("AGP: %d queued AGP requests can be handled.\n",
183 		(((ai.interface.agp_stat & AGP_RQ) >> AGP_RQ_shift) + 1)));
184 
185 	/*
186 		list current settings,
187 		make sure we have the correct speed scheme for logging
188 	 */
189 	nv_agp_list_active(ai.interface.agp_cmd | (ai.interface.agp_stat & AGP_rate_rev));
190 }
191 
192 static void nv_agp_list_active(uint32 cmd)
193 {
194 	LOG(4,("AGP: listing settings now in use:\n"));
195 	if (!(cmd & AGP_rate_rev))
196 	{
197 		/* AGP 2.0 scheme applies */
198 		if (cmd & AGP_2_1x)
199 			LOG(4,("AGP: AGP 2.0 1x mode is set\n"));
200 		if (cmd & AGP_2_2x)
201 			LOG(4,("AGP: AGP 2.0 2x mode is set\n"));
202 		if (cmd & AGP_2_4x)
203 			LOG(4,("AGP: AGP 2.0 4x mode is set\n"));
204 	}
205 	else
206 	{
207 		/* AGP 3.0 scheme applies */
208 		if (cmd & AGP_3_4x)
209 			LOG(4,("AGP: AGP 3.0 4x mode is set\n"));
210 		if (cmd & AGP_3_8x)
211 			LOG(4,("AGP: AGP 3.0 8x mode is set\n"));
212 	}
213 	if (cmd & AGP_FW) LOG(4,("AGP: fastwrite transfers are enabled\n"));
214 	if (cmd & AGP_SBA) LOG(4,("AGP: sideband adressing is enabled\n"));
215 	LOG(4,("AGP: max. AGP queued request depth is set to %d\n",
216 		(((cmd & AGP_RQ) >> AGP_RQ_shift) + 1)));
217 	if (cmd & AGP_enable)
218 		LOG(4,("AGP: the AGP interface is enabled.\n"));
219 	else
220 		LOG(4,("AGP: the AGP interface is disabled.\n"));
221 }
222