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