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