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
10static void eng_agp_list_info(agp_info ai);
11static void eng_agp_list_active(uint32 cmd);
12
13status_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
136static 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
187static 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