Fixed problem with getting parent block from paths that contain parent
[tangerine.git] / arch / common / hidd.radeon / radeon_bios.c
bloba84e2f6f913332a97c126f49a175a293daf2f79c
1 /*
2 Copyright © 2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: ATI radeon driver. BIOS part.
6 Lang: English
7 */
9 /*
10 * This file is a derived version of the XFree86 ATI driver (radeon_bios.c file)
13 #include <exec/types.h>
14 #include <exec/memory.h>
16 #include <hidd/hidd.h>
17 #include <hidd/graphics.h>
19 #include <proto/exec.h>
20 #include <proto/oop.h>
21 #include <proto/utility.h>
23 //#include <asm/io.h>
25 #include "ati.h"
26 #include "radeon.h"
27 #include "radeon_reg.h"
28 #include "radeon_macros.h"
29 #include "radeon_bios.h"
31 #define DEBUG 1
32 #include <aros/debug.h>
34 #undef HiddPCIDeviceAttrBase
35 #undef HiddGfxAttrBase
36 #undef HiddPixFmtAttrBase
37 #undef HiddSyncAttrBase
38 #undef HiddBitMapAttrBase
39 #define SysBase (sd->sysbase)
40 #define HiddPCIDeviceAttrBase (sd->pciAttrBase)
41 #define HiddATIBitMapAttrBase (sd->atiBitMapAttrBase)
42 #define HiddBitMapAttrBase (sd->bitMapAttrBase)
43 #define HiddPixFmtAttrBase (sd->pixFmtAttrBase)
44 #define HiddGfxAttrBase (sd->gfxAttrBase)
45 #define HiddSyncAttrBase (sd->syncAttrBase)
47 #ifndef MAX
48 #define MAX(a,b) ((a)>(b)?(a):(b))
49 #endif
50 #ifndef MIN
51 #define MIN(a,b) ((a)>(b)?(b):(a))
52 #endif
55 /* Read the Video BIOS block and the FP registers (if applicable). */
56 BOOL RADEONGetBIOSInfo(struct ati_staticdata *sd)
58 int tmp;
60 if (sd->Card.VBIOS[0] != 0x55 || sd->Card.VBIOS[1] != 0xaa) {
61 D(bug("[ATI] Video BIOS not detected in PCI space!\n"));
62 D(bug("[ATI] Attempting to read Video BIOS from legacy ISA space!\n"));
63 sd->Card.VBIOS = AllocPooled(sd->memPool, 65536);
64 CopyMemQuick((APTR)0x000c0000, sd->Card.VBIOS, 65536);
67 if (sd->Card.VBIOS[0] != 0x55 || sd->Card.VBIOS[1] != 0xaa) {
68 D(bug("[ATI] Unrecognized BIOS signature, BIOS data will not be used\n"));
69 if (sd->Card.VBIOS != sd->Card.vbios_org)
70 FreePooled(sd->memPool, sd->Card.VBIOS, 65536);
71 sd->Card.VBIOS = NULL;
72 return FALSE;
75 if (sd->Card.VBIOS) sd->Card.ROMHeaderStart = RADEON_BIOS16(0x48);
77 if(!sd->Card.ROMHeaderStart) {
78 D(bug("[ATI] Invalid ROM pointer, BIOS data will not be used\n"));
79 if (sd->Card.VBIOS != sd->Card.vbios_org)
80 FreePooled(sd->memPool, sd->Card.VBIOS, 65536);
81 sd->Card.VBIOS = NULL;
82 return FALSE;
85 tmp = sd->Card.ROMHeaderStart + 4;
86 if ((RADEON_BIOS8(tmp) == 'A' &&
87 RADEON_BIOS8(tmp+1) == 'T' &&
88 RADEON_BIOS8(tmp+2) == 'O' &&
89 RADEON_BIOS8(tmp+3) == 'M') ||
90 (RADEON_BIOS8(tmp) == 'M' &&
91 RADEON_BIOS8(tmp+1) == 'O' &&
92 RADEON_BIOS8(tmp+2) == 'T' &&
93 RADEON_BIOS8(tmp+3) == 'A'))
94 sd->Card.IsAtomBios = TRUE;
95 else
96 sd->Card.IsAtomBios = FALSE;
98 if (sd->Card.IsAtomBios)
99 sd->Card.MasterDataStart = RADEON_BIOS16 (sd->Card.ROMHeaderStart + 32);
101 D(bug("[ATI] %s BIOS detected\n", sd->Card.IsAtomBios ? "ATOM":"Legacy"));
103 return TRUE;
106 BOOL RADEONGetConnectorInfoFromBIOS(struct ati_staticdata *sd)
108 int i = 0, j, tmp, tmp0=0, tmp1=0;
110 if(!sd->Card.VBIOS) return FALSE;
112 if (sd->Card.IsAtomBios) {
113 if((tmp = RADEON_BIOS16 (sd->Card.MasterDataStart + 22))) {
114 int crtc = 0, id[2];
115 tmp1 = RADEON_BIOS16 (tmp + 4);
116 for (i=0; i<8; i++) {
117 if(tmp1 & (1<<i)) {
118 UWORD portinfo = RADEON_BIOS16(tmp+6+i*2);
119 if (crtc < 2) {
120 if ((i==2) || (i==6)) continue; /* ignore TV here */
122 if (crtc == 1) {
123 /* sharing same port with id[0] */
124 if (((portinfo>>8) & 0xf) == id[0]) {
125 if (i == 3)
126 sd->Card.PortInfo[0].TMDSType = TMDS_INT;
127 else if (i == 7)
128 sd->Card.PortInfo[0].TMDSType = TMDS_EXT;
130 if (sd->Card.PortInfo[0].DACType == DAC_UNKNOWN)
131 sd->Card.PortInfo[0].DACType = (portinfo & 0xf) - 1;
132 continue;
135 id[crtc] = (portinfo>>8) & 0xf;
136 sd->Card.PortInfo[crtc].DACType = (portinfo & 0xf) - 1;
137 sd->Card.PortInfo[crtc].ConnectorType = (portinfo>>4) & 0xf;
138 if (i == 3)
139 sd->Card.PortInfo[crtc].TMDSType = TMDS_INT;
140 else if (i == 7)
141 sd->Card.PortInfo[crtc].TMDSType = TMDS_EXT;
143 if((tmp0 = RADEON_BIOS16 (sd->Card.MasterDataStart + 24)) && id[crtc]) {
144 switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4)
146 case RADEON_GPIO_MONID:
147 sd->Card.PortInfo[crtc].DDCType = DDC_MONID;
148 break;
149 case RADEON_GPIO_DVI_DDC:
150 sd->Card.PortInfo[crtc].DDCType = DDC_DVI;
151 break;
152 case RADEON_GPIO_VGA_DDC:
153 sd->Card.PortInfo[crtc].DDCType = DDC_VGA;
154 break;
155 case RADEON_GPIO_CRT2_DDC:
156 sd->Card.PortInfo[crtc].DDCType = DDC_CRT2;
157 break;
158 default:
159 sd->Card.PortInfo[crtc].DDCType = DDC_NONE;
160 break;
163 } else {
164 sd->Card.PortInfo[crtc].DDCType = DDC_NONE;
166 crtc++;
167 } else {
168 /* we have already had two CRTCs assigned. the rest may share the same
169 * port with the existing connector, fill in them accordingly.
171 for (j=0; j<2; j++) {
172 if (((portinfo>>8) & 0xf) == id[j]) {
173 if (i == 3)
174 sd->Card.PortInfo[j].TMDSType = TMDS_INT;
175 else if (i == 7)
176 sd->Card.PortInfo[j].TMDSType = TMDS_EXT;
178 if (sd->Card.PortInfo[j].DACType == DAC_UNKNOWN)
179 sd->Card.PortInfo[j].DACType = (portinfo & 0xf) - 1;
186 for (i=0; i<2; i++) {
187 D(bug("[ATI] Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
188 i, sd->Card.PortInfo[i].DDCType, sd->Card.PortInfo[i].DACType,
189 sd->Card.PortInfo[i].TMDSType, sd->Card.PortInfo[i].ConnectorType));
191 } else {
192 D(bug("[ATI] No Device Info Table found!\n"));
193 return FALSE;
195 } else {
196 /* Some laptops only have one connector (VGA) listed in the connector table,
197 * we need to add LVDS in as a non-DDC display.
198 * Note, we can't assume the listed VGA will be filled in PortInfo[0],
199 * when walking through connector table. connector_found has following meaning:
200 * 0 -- nothing found,
201 * 1 -- only PortInfo[0] filled,
202 * 2 -- only PortInfo[1] filled,
203 * 3 -- both are filled.
205 int connector_found = 0;
207 if ((tmp = RADEON_BIOS16(sd->Card.ROMHeaderStart + 0x50))) {
208 for (i = 1; i < 4; i++) {
210 if (!RADEON_BIOS8(tmp + i*2) && i > 1) break; /* end of table */
212 tmp0 = RADEON_BIOS16(tmp + i*2);
213 if (((tmp0 >> 12) & 0x0f) == 0) continue; /* no connector */
214 if (connector_found > 0) {
215 if (sd->Card.PortInfo[tmp1].DDCType == ((tmp0 >> 8) & 0x0f))
216 continue; /* same connector */
219 /* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */
220 tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */
222 sd->Card.PortInfo[tmp1].DDCType = (tmp0 >> 8) & 0x0f;
223 if (sd->Card.PortInfo[tmp1].DDCType > DDC_CRT2) sd->Card.PortInfo[tmp1].DDCType = DDC_NONE_DETECTED;
224 sd->Card.PortInfo[tmp1].DACType = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
225 sd->Card.PortInfo[tmp1].ConnectorType = (tmp0 >> 12) & 0x0f;
226 if (sd->Card.PortInfo[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED) sd->Card.PortInfo[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;
227 sd->Card.PortInfo[tmp1].TMDSType = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;
229 /* some sanity checks */
230 if (((sd->Card.PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_D) &&
231 (sd->Card.PortInfo[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&
232 sd->Card.PortInfo[tmp1].TMDSType == TMDS_INT)
233 sd->Card.PortInfo[tmp1].TMDSType = TMDS_UNKNOWN;
235 connector_found += (tmp1 + 1);
237 } else {
238 D(bug("[ATI] No Connector Info Table found!\n"));
239 return FALSE;
241 if (sd->Card.IsMobility) {
242 /* For the cases where only one VGA connector is found,
243 we assume LVDS is not listed in the connector table,
244 add it in here as the first port.
246 if ((connector_found < 3) && (sd->Card.PortInfo[tmp1].ConnectorType == CONNECTOR_CRT)) {
247 if (connector_found == 1) {
248 memcpy (&sd->Card.PortInfo[1], &sd->Card.PortInfo[0],
249 sizeof (sd->Card.PortInfo[0]));
251 sd->Card.PortInfo[0].DACType = DAC_TVDAC;
252 sd->Card.PortInfo[0].TMDSType = TMDS_UNKNOWN;
253 sd->Card.PortInfo[0].DDCType = DDC_NONE_DETECTED;
254 sd->Card.PortInfo[0].ConnectorType = CONNECTOR_PROPRIETARY;
256 D(bug("[ATI] LVDS port is not in connector table, added in.\n"));
257 if (connector_found == 0) connector_found = 1;
258 else connector_found = 3;
261 if ((tmp = RADEON_BIOS16(sd->Card.ROMHeaderStart + 0x42))) {
262 if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
263 if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {
264 sd->Card.PortInfo[0].DDCType = tmp1;
265 D(bug("[ATI] LCD DDC Info Table found!\n"));
269 } else if (connector_found == 2) {
270 memcpy (&sd->Card.PortInfo[0], &sd->Card.PortInfo[1],
271 sizeof (sd->Card.PortInfo[0]));
272 sd->Card.PortInfo[1].DACType = DAC_UNKNOWN;
273 sd->Card.PortInfo[1].TMDSType = TMDS_UNKNOWN;
274 sd->Card.PortInfo[1].DDCType = DDC_NONE_DETECTED;
275 sd->Card.PortInfo[1].ConnectorType = CONNECTOR_NONE;
276 connector_found = 1;
279 if (connector_found == 0) {
280 D(bug("[ATI] No connector found in Connector Info Table.\n"));
281 } else {
282 D(bug("[ATI] Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
283 sd->Card.PortInfo[0].DDCType, sd->Card.PortInfo[0].DACType,
284 sd->Card.PortInfo[0].TMDSType, sd->Card.PortInfo[0].ConnectorType));
286 if (connector_found == 3) {
287 D(bug("[ATI] Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
288 sd->Card.PortInfo[1].DDCType, sd->Card.PortInfo[1].DACType,
289 sd->Card.PortInfo[1].TMDSType, sd->Card.PortInfo[1].ConnectorType));
292 return TRUE;
295 /* Read PLL parameters from BIOS block. Default to typical values if there
296 is no BIOS. */
297 BOOL RADEONGetClockInfoFromBIOS(struct ati_staticdata *sd)
299 RADEONPLLRec *pll = &sd->Card.pll;
300 UWORD pll_info_block;
302 if (!sd->Card.VBIOS) {
303 return FALSE;
304 } else {
305 if (sd->Card.IsAtomBios) {
306 pll_info_block = RADEON_BIOS16 (sd->Card.MasterDataStart + 12);
308 pll->reference_freq = RADEON_BIOS16 (pll_info_block + 82);
309 pll->reference_div = 0; /* Need to derive from existing setting
310 or use a new algorithm to calculate
311 from min_input and max_input
313 pll->min_pll_freq = RADEON_BIOS16 (pll_info_block + 78);
314 pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 32);
315 pll->xclk = RADEON_BIOS16 (pll_info_block + 72);
317 sd->Card.sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0;
318 sd->Card.mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0;
319 if (sd->Card.sclk == 0) sd->Card.sclk = 200;
320 if (sd->Card.mclk == 0) sd->Card.mclk = 200;
322 D(bug("[ATI] ref_freq: %d, min_pll: %ld, max_pll: %ld, xclk: %d, sclk: %f, mclk: %f\n",
323 pll->reference_freq, pll->min_pll_freq, pll->max_pll_freq, pll->xclk, sd->Card.sclk, sd->Card.mclk));
325 } else {
326 pll_info_block = RADEON_BIOS16 (sd->Card.ROMHeaderStart + 0x30);
328 pll->reference_freq = RADEON_BIOS16 (pll_info_block + 0x0e);
329 pll->reference_div = RADEON_BIOS16 (pll_info_block + 0x10);
330 pll->min_pll_freq = RADEON_BIOS32 (pll_info_block + 0x12);
331 pll->max_pll_freq = RADEON_BIOS32 (pll_info_block + 0x16);
332 pll->xclk = RADEON_BIOS16 (pll_info_block + 0x08);
334 sd->Card.sclk = RADEON_BIOS16(pll_info_block + 8) / 100.0;
335 sd->Card.mclk = RADEON_BIOS16(pll_info_block + 10) / 100.0;
339 return TRUE;