xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon_hd/driver.cpp (revision 778611c7e6a61b8ba072212756ce53eda826360a)
1 /*
2  * Copyright (c) 2002, Thomas Kurschel
3  * Copyright 2004-2011 Haiku, Inc. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  *
6  * Authors:
7  *		Thomas Kurschel
8  *		Clemens Zeidler, <haiku@clemens-zeidler.de>
9  *		Alexander von Gluck IV, kallisti5@unixzen.com
10  */
11 
12 
13 #include "driver.h"
14 #include "device.h"
15 #include "lock.h"
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 
21 #include <AGP.h>
22 #include <KernelExport.h>
23 #include <OS.h>
24 #include <PCI.h>
25 #include <SupportDefs.h>
26 
27 
28 #define TRACE_DRIVER
29 #ifdef TRACE_DRIVER
30 #	define TRACE(x...) dprintf("radeon_hd: " x)
31 #else
32 #	define TRACE(x...) ;
33 #endif
34 
35 #define ERROR(x...) dprintf("radeon_hd: " x)
36 
37 #define MAX_CARDS 1
38 
39 
40 // ATI / AMD cards starting at the Radeon X700 have an AtomBIOS
41 
42 // list of supported devices
43 const struct supported_device {
44 	uint32		pciID;
45 	uint8		dceMajor;	// Display block family
46 	uint8		dceMinor;	// Display block family
47 	uint16		chipsetID;
48 	uint32		chipsetFlags;
49 	const char*	deviceName;
50 } kSupportedDevices[] = {
51 	// Marketing Names: Radeon X?00
52 	// Intorduced: 2004
53 	// Codename: Loki
54 	// R420 Series  (Radeon) DCE 0.0 (*very* early AtomBIOS)
55 
56 	// Marketing Names: Radeon X1?00
57 	// Introduced: 2005
58 	// Codename: Fudo
59 	#if 0
60 	{0x791e, 1, 0, RADEON_RS690, CHIP_IGP, "Radeon X1200"},
61 	{0x791f, 1, 0, RADEON_RS690, CHIP_IGP, "Radeon X1200"},
62 	{0x793f, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1200"},
63 	{0x7941, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1200"},
64 	{0x7942, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1250"},
65 	{0x796c, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"},
66 	{0x796d, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"},
67 	{0x796e, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon 2100"},
68 	{0x796f, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"},
69 	{0x7140, 1, 0, RADEON_RV515, CHIP_STD, "Radeon X1600"},
70 	{0x7100, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
71 	{0x7104, 1, 0, RADEON_R520,  CHIP_STD, "FireGL v7200"},
72 	{0x7109, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
73 	{0x710a, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
74 	{0x710b, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
75 	{0x710c, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
76 	{0x7120, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
77 	{0x7129, 1, 0, RADEON_R520,  CHIP_STD, "Radeon X1800"},
78 	#endif
79 
80 	// Marketing Names: Radeon HD 24xx - HD 42xx
81 	// Introduced: 2006
82 	// Codename: Pele
83 	// Process: 55 nm
84 	{0x94c7, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2350"},
85 	{0x94c1, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 2400"},
86 	{0x94c3, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2400"},
87 	{0x94cc, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2400"},
88 	{0x9519, 2, 0, RADEON_RV630, CHIP_STD, "AMD FireStream 9170"},
89 	{0x9586, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600"},
90 	{0x9588, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600"},
91 	{0x958a, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600 X2"},
92 	//	Radeon 2700		- RV630
93 	{0x9400, 2, 0, RADEON_R600,  CHIP_STD, "Radeon HD 2900"},
94 	{0x9401, 2, 0, RADEON_R600,  CHIP_STD, "Radeon HD 2900"},
95 	{0x9402, 2, 0, RADEON_R600,  CHIP_STD, "Radeon HD 2900"},
96 	{0x9403, 2, 0, RADEON_R600,  CHIP_STD, "Radeon HD 2900 Pro"},
97 	{0x9405, 2, 0, RADEON_R600,  CHIP_STD, "Radeon HD 2900"},
98 	{0x940a, 2, 0, RADEON_R600,  CHIP_STD, "Radeon FireGL V8650"},
99 	{0x940b, 2, 0, RADEON_R600,  CHIP_STD, "Radeon FireGL V8600"},
100 	{0x940f, 2, 0, RADEON_R600,  CHIP_STD, "Radeon FireGL V7600"},
101 	{0x9616, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3000"},
102 	{0x9611, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 3100"},
103 	{0x9613, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 3100"},
104 	{0x9610, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"},
105 	{0x9612, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"},
106 	{0x9615, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"},
107 	{0x9614, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3300"},
108 	//  Radeon 3430		- RV620
109 	{0x95c2, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3430"},
110 	{0x95c5, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"},
111 	{0x95c6, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"},
112 	{0x95c7, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"},
113 	{0x95c9, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"},
114 	{0x95c4, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3470"},
115 	{0x95c0, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3550"},
116 	{0x9581, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"},
117 	{0x9583, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"},
118 	{0x9598, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"},
119 	{0x9591, 3, 0, RADEON_RV635, CHIP_STD, "Radeon HD 3600"},
120 	{0x9589, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3610"},
121 	//  Radeon 3650		- RV635
122 	//  Radeon 3670		- RV635
123 	{0x9507, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3830"},
124 	{0x9505, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850"},
125 	{0x9513, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850 X2"},
126 	{0x9515, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850"},
127 	{0x9501, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3870"},
128 	{0x950F, 2, 0, RADEON_RV670, CHIP_STD | CHIP_X2, "Radeon HD 3870 X2"},
129 	{0x9710, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4200"},
130 	{0x9715, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4250"},
131 	{0x9712, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4270"},
132 	{0x9714, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4290"},
133 
134 	// Marketing Names: Radeon HD 4330 - HD 4890, HD 51xx, HD 5xxV
135 	// Introduced: 2008
136 	// Codename: Wekiva
137 	// Process: 55 nm
138 	//	Radeon 4330		- RV710
139 	{0x954f, 3, 2, RADEON_RV710, CHIP_IGP, "Radeon HD 4300"},
140 	{0x9552, 3, 2, RADEON_RV710, CHIP_IGP, "Radeon HD 4300"},
141 	{0x9553, 3, 2, RADEON_RV710, CHIP_IGP, "Radeon HD 4500"},
142 	{0x9555, 3, 2, RADEON_RV710, CHIP_STD, "Radeon HD 4350"},
143 	{0x9540, 3, 2, RADEON_RV710, CHIP_STD, "Radeon HD 4550"},
144 	{0x9452, 3, 2, RADEON_RV730, CHIP_STD, "AMD FireStream 9250"},
145 	{0x9480, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4650"},
146 	{0x9488, 3, 2, RADEON_RV730, CHIP_MOBILE, "Radeon HD 4650"},
147 	{0x9498, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4650"},
148 	{0x94b4, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4700"},
149 	{0x9490, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4710"},
150 	{0x94b3, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4770"},
151 	{0x94b5, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4770"},
152 	{0x9450, 3, 1, RADEON_RV770, CHIP_STD, "AMD FireStream 9270"},
153 	{0x944a, 3, 1, RADEON_RV770, CHIP_MOBILE, "Radeon HD 4850"},
154 	{0x944e, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4810"},
155 	{0x944c, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4830"},
156 	{0x9442, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4850"},
157 	{0x9443, 3, 1, RADEON_RV770, CHIP_STD | CHIP_X2, "Radeon HD 4850 X2"},
158 	{0x94a1, 3, 1, RADEON_RV770, CHIP_IGP, "Radeon HD 4860"},
159 	{0x9440, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4870"},
160 	{0x9441, 3, 1, RADEON_RV770, CHIP_STD | CHIP_X2, "Radeon HD 4870 X2"},
161 	{0x9460, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4890"},
162 
163 	// From here on AMD no longer used numeric identifiers
164 	// Marketing names can collide for different generations of cards
165 	// as such we should ignore them at all costs (besides the card name)
166 
167 	// Introduced: 2009
168 	// Codename: Evergreen
169 	// Process: 40 nm
170 	//  Cedar
171 	{0x68e1, 4, 0, RADEON_CEDAR, CHIP_STD, "Radeon HD 5430"},
172 	{0x68f9, 4, 0, RADEON_CEDAR, CHIP_STD, "Radeon HD 5450"},
173 	{0x68e0, 4, 0, RADEON_CEDAR, CHIP_IGP, "Radeon HD 5470"},
174 	{0x68e4, 4, 0, RADEON_CEDAR, CHIP_MOBILE, "Radeon HD 6370"},
175 	//  Redwood
176 	{0x68da, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5500"},
177 	{0x68d9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5570"},
178 	{0x675f, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5570"},
179 	{0x68b9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5600"},
180 	{0x68c1, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5650"},
181 	{0x68d8, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5670"},
182 	//  Juniper
183 	{0x68be, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 5700"},
184 	{0x68b8, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 5770"},
185 	//  Juniper LE / XT (67X0 is rebranded 57X0 + tweaks)
186 	{0x68bf, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 6750"},
187 	{0x68ba, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 6770"},
188 	//  Cypress
189 	{0x689e, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5800"},
190 	{0x6899, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5850"},
191 	{0x6898, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5870"},
192 	//  Hemlock
193 	{0x689c, 4, 0, RADEON_HEMLOCK, CHIP_STD | CHIP_X2, "Radeon HD 5900 X2"},
194 	{0x689d, 4, 0, RADEON_HEMLOCK, CHIP_STD | CHIP_X2, "Radeon HD 5900 X2"},
195 	// Fusion APUS
196 	//  Palm
197 	{0x9804, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6250"},
198 	{0x9805, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6290"},
199 	{0x9807, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6290"},
200 	{0x9802, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6310"},
201 	{0x9803, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6310"},
202 	{0x9806, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6320"},
203 	//  Sumo (no VGA / LVDS!, only DP)
204 	{0x9640, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6550D"},
205 	{0x9641, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD Sumo"},
206 	{0x9647, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6520G"},
207 	{0x9648, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6480G"},
208 	{0x964a, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6530D"},
209 	{0x964e, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD Sumo"},
210 	{0x964f, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD Sumo"},
211 	//  Sumo2 (no VGA / LVDS!, only DP)
212 	{0x9642, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD 6370D"},
213 	{0x9643, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD Sumo2"},
214 	{0x9644, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD 6410D"},
215 	{0x9645, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD Sumo2"},
216 
217 	// Introduced: 2010
218 	// Codename: Nothern Islands
219 	// Process: 40 nm
220 	//  Caicos
221 	{0x6760, 5, 0, RADEON_CAICOS, CHIP_MOBILE, "Radeon HD 6470"},
222 	{0x6761, 5, 0, RADEON_CAICOS, CHIP_MOBILE, "Radeon HD 6430"},
223 	{0x6762, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
224 	{0x6763, 5, 0, RADEON_CAICOS, CHIP_DISCREET, "Radeon HD E6460"},
225 	{0x6764, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
226 	{0x6765, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
227 	{0x6766, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
228 	{0x6767, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
229 	{0x6768, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
230 	{0x6770, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 6400"},
231 	{0x6778, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD Caicos"},
232 	{0x6779, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 6450"},
233 	{0x68fa, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 7350"},
234 	{0x68f9, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 7350"},
235 	{0x677b, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 7400"},
236 	{0x6772, 5, 0, RADEON_CAICOS, CHIP_APU, "Radeon HD 7400A"},
237 	//  Turks
238 	{0x6740, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6770M"},
239 	{0x6741, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6650M"},
240 	{0x6742, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6625M"},
241 	{0x6743, 5, 0, RADEON_TURKS, CHIP_DISCREET, "Radeon HD E6760"},
242 	{0x6744, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD Turks"},
243 	{0x6745, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD Turks"},
244 	{0x6746, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD Turks"},
245 	{0x6747, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD Turks"},
246 	{0x6748, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD Turks"},
247 	{0x6749, 5, 0, RADEON_TURKS, CHIP_STD, "FirePro v4900"},
248 	{0x6750, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6500"},
249 	{0x6758, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6670"},
250 	{0x6759, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6570/7570"},
251 	{0x6850, 6, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 7570"},
252 	{0x6840, 6, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 7670"},
253 	//  Barts
254 	{0x673e, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6790"},
255 	{0x6739, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6850"},
256 	{0x6738, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6870"},
257 	//  Cayman
258 	{0x6700, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
259 	{0x6701, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
260 	{0x6702, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
261 	{0x6703, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
262 	{0x6704, 5, 0, RADEON_CAYMAN, CHIP_STD, "FirePro v????"},
263 	{0x6705, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
264 	{0x6706, 5, 0, RADEON_CAYMAN, CHIP_STD, "FirePro v????"},
265 	{0x6707, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
266 	{0x6708, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
267 	{0x6709, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
268 	{0x6718, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6970"},
269 	{0x6719, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6950"},
270 	{0x671c, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD Cayman"},
271 	{0x671f, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6900"},
272 	//  Antilles (Top, Dual GPU)
273 	{0x671d, 5, 0, RADEON_ANTILLES, CHIP_STD, "Radeon HD 6990"},
274 
275 
276 	// Introduced: Late 2011
277 	// Codename: Southern Islands
278 	// Process: 28 nm
279 	//  Cape Verde
280 	{0x6820, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
281 	{0x6821, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
282 	{0x6823, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
283 	{0x6824, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
284 	{0x6825, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
285 	{0x6826, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
286 	{0x6827, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
287 	{0x6828, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
288 	{0x6829, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
289 	{0x682a, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
290 	{0x682b, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
291 	{0x682d, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
292 	{0x682f, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
293 	{0x6830, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
294 	{0x6831, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
295 	{0x6835, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
296 	{0x6837, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
297 	{0x6838, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
298 	{0x6839, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
299 	{0x683b, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD Verde"},
300 	{0x683d, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD 7770"},
301 	{0x683f, 6, 0, RADEON_CAPEVERDE, CHIP_STD, "Radeon HD 7750"},
302 	//  Pitcairn
303 	{0x6800, 6, 0, RADEON_PITCAIRN, CHIP_MOBILE, "Radeon HD 7970"},
304 	{0x6801, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
305 	{0x6802, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
306 	{0x6806, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
307 	{0x6808, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
308 	{0x6809, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
309 	{0x6810, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
310 	{0x6811, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
311 	{0x6816, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
312 	{0x6817, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
313 	{0x6818, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD 7870"},
314 	{0x6819, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD 7800"},
315 	{0x684c, 6, 0, RADEON_PITCAIRN, CHIP_STD, "Radeon HD Pitcairn"},
316 	//  Tahiti
317 	{0x6780, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
318 	{0x6784, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
319 	{0x6788, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
320 	{0x678a, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
321 	{0x6790, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
322 	{0x679e, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
323 	{0x679f, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD Tahiti"},
324 	{0x679a, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7950"},
325 	{0x6798, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7970"},
326 	{0x6799, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7990"},
327 	//  Aruba   DCE 6.1 Trinity / Richland
328 	{0x9900, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7660"},
329 	{0x9901, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7660"},
330 	{0x9903, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7640"},
331 	{0x9904, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7560"},
332 	{0x9905, 6, 1, RADEON_ARUBA, CHIP_APU, "FirePro A300"},
333 	{0x9906, 6, 1, RADEON_ARUBA, CHIP_APU, "FirePro A300"},
334 	{0x9907, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7560"},
335 	{0x9908, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7620"},
336 	{0x9909, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7500"},
337 	{0x990a, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7500"},
338 	{0x990b, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8650"},
339 	{0x990d, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8550"},
340 	{0x990f, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8610"},
341 	{0x9910, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7660"},
342 	{0x9913, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7640"},
343 	{0x9917, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7620"},
344 	{0x9918, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7600"},
345 	{0x9919, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7500"},
346 	{0x9990, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7920"},
347 	{0x9991, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7540"},
348 	{0x9992, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7420"},
349 #if 0
350 	// Known not to work: https://dev.haiku-os.org/ticket/10606
351 	{0x9993, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7480"},
352 #endif
353 	{0x9994, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7400"},
354 	{0x9995, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8450"},
355 	{0x9996, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8470"},
356 	{0x9997, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8350"},
357 	{0x9998, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8730"},
358 	{0x999a, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8410"},
359 	{0x999b, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8310"},
360 	{0x999c, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8650"},
361 	{0x999d, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 8550"},
362 	{0x99a0, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7520"},
363 	{0x99a2, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7420"},
364 	{0x99a4, 6, 1, RADEON_ARUBA, CHIP_APU, "Radeon HD 7400"},
365 	//  Oland   DCE 6,4
366 	{0x990c, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD 8670"},
367 	{0x990e, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD 8570"},
368 	{0x6600, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
369 	{0x6601, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
370 	{0x6602, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
371 	{0x6603, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
372 	{0x6606, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
373 	{0x6607, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
374 	{0x6610, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
375 	{0x6611, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
376 	{0x6613, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
377 	{0x6620, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
378 	{0x6621, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
379 	{0x6623, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
380 	{0x6631, 6, 4, RADEON_OLAND, CHIP_STD, "Radeon HD Oland"},
381 	//  Hainan  NODCE. No display hardware, OpenCL 3D engine.
382 
383 	// Introduced: Late 2013
384 	// Codename: Sea Islands
385 	// Process: 28 nm
386 	//  Kaveri DCE 8.1
387 	{0x1304, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
388 	{0x1305, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
389 	{0x1306, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
390 	{0x1307, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
391 	{0x1308, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
392 	{0x1309, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
393 	{0x130a, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
394 	{0x130b, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
395 	{0x130c, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
396 	{0x130d, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
397 	{0x130e, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
398 	{0x130f, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
399 	{0x1310, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
400 	{0x1311, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
401 	{0x1312, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
402 	{0x1313, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
403 	{0x1314, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
404 	{0x1315, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
405 	{0x1316, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
406 	{0x1317, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
407 	{0x131b, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
408 	{0x131c, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
409 	{0x131d, 8, 1, RADEON_KAVERI, CHIP_STD, "Radeon HD Kaveri"},
410 	//  Bonaire DCE 8.2
411 	{0x6640, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
412 	{0x6641, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
413 	{0x6649, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
414 	{0x6650, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
415 	{0x6651, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
416 	{0x6658, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
417 	{0x665c, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD 7790"},
418 	{0x665d, 8, 2, RADEON_BONAIRE, CHIP_STD, "Radeon HD Bonaire"},
419 	//  Kabini DCE 8.3
420 	{0x9830, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8400"},
421 	{0x9831, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8400"},
422 	{0x9832, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8330"},
423 	{0x9833, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8330"},
424 	{0x9834, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8210"},
425 	{0x9835, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8210"},
426 	{0x9836, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8280"},
427 	{0x9837, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8280"},
428 	{0x9838, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8240"},
429 	{0x9839, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8180"},
430 	{0x983a, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD Kabini"},
431 	{0x983b, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD Kabini"},
432 	{0x983c, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD Kabini"},
433 	{0x983d, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD 8250"},
434 	{0x983e, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD Kabini"},
435 	{0x983f, 8, 3, RADEON_KABINI, CHIP_STD, "Radeon HD Kabini"},
436 	//  Mullins DCE 8.3
437 	{0x9850, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R3"},
438 	{0x9851, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
439 	{0x9852, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
440 	{0x9853, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
441 	{0x9854, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
442 	{0x9855, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R3"},
443 	{0x9856, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
444 	{0x9857, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD R2"},
445 	{0x9858, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
446 	{0x9859, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
447 	{0x985a, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
448 	{0x985b, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
449 	{0x985c, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
450 	{0x985d, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
451 	{0x985e, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
452 	{0x985f, 8, 3, RADEON_MULLINS, CHIP_STD, "Radeon HD Mullins"},
453 
454 	// Introduced: 2014?
455 	// Codename: Volcanic Islands
456 	// Process: 20 nm
457 
458 	// Introduced: 2015?
459 	// Codename: Pirate Islands
460 	// Process: ?? nm
461 };
462 
463 
464 int32 api_version = B_CUR_DRIVER_API_VERSION;
465 
466 
467 char* gDeviceNames[MAX_CARDS + 1];
468 radeon_info* gDeviceInfo[MAX_CARDS];
469 pci_module_info* gPCI;
470 mutex gLock;
471 
472 
473 static status_t
474 get_next_radeon_hd(int32* _cookie, pci_info &info, uint32 &type)
475 {
476 	int32 index = *_cookie;
477 
478 	// find devices
479 
480 	for (; gPCI->get_nth_pci_info(index, &info) == B_OK; index++) {
481 		// check vendor
482 		if (info.vendor_id != VENDOR_ID_ATI
483 			|| info.class_base != PCI_display
484 			|| info.class_sub != PCI_vga)
485 			continue;
486 
487 		// check device
488 		for (uint32 i = 0; i < sizeof(kSupportedDevices)
489 				/ sizeof(kSupportedDevices[0]); i++) {
490 			if (info.device_id == kSupportedDevices[i].pciID) {
491 				type = i;
492 				*_cookie = index + 1;
493 				return B_OK;
494 			}
495 		}
496 	}
497 
498 	return B_ENTRY_NOT_FOUND;
499 }
500 
501 
502 extern "C" const char**
503 publish_devices(void)
504 {
505 	TRACE("%s\n", __func__);
506 	return (const char**)gDeviceNames;
507 }
508 
509 
510 extern "C" status_t
511 init_hardware(void)
512 {
513 	TRACE("%s\n", __func__);
514 
515 	status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI);
516 	if (status != B_OK) {
517 		ERROR("%s: ERROR: pci module unavailable\n", __func__);
518 		return status;
519 	}
520 
521 	int32 cookie = 0;
522 	uint32 type;
523 	pci_info info;
524 	status = get_next_radeon_hd(&cookie, info, type);
525 
526 	put_module(B_PCI_MODULE_NAME);
527 	return status;
528 }
529 
530 
531 extern "C" status_t
532 init_driver(void)
533 {
534 	TRACE("%s\n", __func__);
535 
536 	status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI);
537 	if (status != B_OK) {
538 		ERROR("%s: ERROR: pci module unavailable\n", __func__);
539 		return status;
540 	}
541 
542 	mutex_init(&gLock, "radeon hd ksync");
543 
544 	// find devices
545 
546 	int32 found = 0;
547 
548 	for (int32 cookie = 0; found < MAX_CARDS;) {
549 		pci_info* info = (pci_info*)malloc(sizeof(pci_info));
550 		if (info == NULL)
551 			break;
552 
553 		uint32 type;
554 		status = get_next_radeon_hd(&cookie, *info, type);
555 		if (status < B_OK) {
556 			free(info);
557 			break;
558 		}
559 
560 		// create device names & allocate device info structure
561 
562 		char name[64];
563 		sprintf(name, "graphics/radeon_hd_%02x%02x%02x",
564 			info->bus, info->device,
565 			info->function);
566 
567 		gDeviceNames[found] = strdup(name);
568 		if (gDeviceNames[found] == NULL)
569 			break;
570 
571 		gDeviceInfo[found] = (radeon_info*)malloc(sizeof(radeon_info));
572 		if (gDeviceInfo[found] == NULL) {
573 			free(gDeviceNames[found]);
574 			break;
575 		}
576 
577 		// initialize the structure for later use
578 
579 		memset(gDeviceInfo[found], 0, sizeof(radeon_info));
580 		gDeviceInfo[found]->init_status = B_NO_INIT;
581 		gDeviceInfo[found]->id = found;
582 		gDeviceInfo[found]->pci = info;
583 		gDeviceInfo[found]->registers = info->u.h0.base_registers[0];
584 		gDeviceInfo[found]->pciID = kSupportedDevices[type].pciID;
585 		gDeviceInfo[found]->deviceName = kSupportedDevices[type].deviceName;
586 		gDeviceInfo[found]->chipsetID = kSupportedDevices[type].chipsetID;
587 		gDeviceInfo[found]->dceMajor = kSupportedDevices[type].dceMajor;
588 		gDeviceInfo[found]->dceMinor = kSupportedDevices[type].dceMinor;
589 		gDeviceInfo[found]->chipsetFlags = kSupportedDevices[type].chipsetFlags;
590 
591 		ERROR("%s: GPU(%ld) %s, revision = 0x%x\n", __func__, found,
592 			kSupportedDevices[type].deviceName, info->revision);
593 
594 		found++;
595 	}
596 
597 	gDeviceNames[found] = NULL;
598 
599 	if (found == 0) {
600 		mutex_destroy(&gLock);
601 		put_module(B_AGP_GART_MODULE_NAME);
602 		put_module(B_PCI_MODULE_NAME);
603 		ERROR("%s: no supported devices found\n", __func__);
604 		return ENODEV;
605 	}
606 
607 	return B_OK;
608 }
609 
610 
611 extern "C" void
612 uninit_driver(void)
613 {
614 	TRACE("%s\n", __func__);
615 
616 	mutex_destroy(&gLock);
617 
618 	// free device related structures
619 	char* name;
620 	for (int32 index = 0; (name = gDeviceNames[index]) != NULL; index++) {
621 		free(gDeviceInfo[index]);
622 		free(name);
623 	}
624 
625 	put_module(B_PCI_MODULE_NAME);
626 }
627 
628 
629 extern "C" device_hooks*
630 find_device(const char* name)
631 {
632 	int index;
633 
634 	TRACE("%s\n", __func__);
635 
636 	for (index = 0; gDeviceNames[index] != NULL; index++) {
637 		if (!strcmp(name, gDeviceNames[index]))
638 			return &gDeviceHooks;
639 	}
640 
641 	ERROR("%s: %s wasn't found!\n", __func__, name);
642 	return NULL;
643 }
644 
645