Rev 1407 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1029 | serge | 1 | /* |
2 | * Copyright 2007 Luc Verhaegen |
||
3 | * Copyright 2007 Matthias Hopf |
||
4 | * Copyright 2007 Egbert Eich |
||
5 | * Copyright 2007 Advanced Micro Devices, Inc. |
||
6 | * |
||
7 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
8 | * copy of this software and associated documentation files (the "Software"), |
||
9 | * to deal in the Software without restriction, including without limitation |
||
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
11 | * and/or sell copies of the Software, and to permit persons to whom the |
||
12 | * Software is furnished to do so, subject to the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included in |
||
15 | * all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
20 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
23 | * OTHER DEALINGS IN THE SOFTWARE. |
||
24 | */ |
||
25 | |||
26 | //ld -T ld.x -s --shared --image-base 0 --file-alignment 32 -o test.exe test.obj core.lib |
||
27 | |||
28 | #include "common.h" |
||
29 | #include "rhd.h" |
||
30 | #include "edid.h" |
||
31 | |||
32 | #include "rhd_atombios.h" |
||
33 | #include "rhd_regs.h" |
||
34 | #include "rhd_mc.h" |
||
35 | #include "rhd_atombios.h" |
||
36 | #include "rhd_connector.h" |
||
37 | #include "rhd_output.h" |
||
38 | #include "rhd_biosscratch.h" |
||
39 | #include "rhd_card.h" |
||
40 | #include "rhd_vga.h" |
||
41 | #include "rhd_crtc.h" |
||
42 | #include "rhd_monitor.h" |
||
43 | #include "rhd_modes.h" |
||
44 | #include "rhd_pll.h" |
||
45 | #include "rhd_lut.h" |
||
46 | #include "rhd_i2c.h" |
||
47 | |||
48 | #define PG_SW 0x003 |
||
49 | #define PG_NOCACHE 0x018 |
||
50 | |||
51 | void sysSetScreen(int width, int height); |
||
52 | |||
53 | static void rhdModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); |
||
54 | static void rhdSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode); |
||
55 | static void RHDAdjustFrame(RHDPtr rhdPtr, int x, int y, int flags); |
||
56 | static Bool rhdMapFB(RHDPtr rhdPtr); |
||
57 | static void rhdGetIGPNorthBridgeInfo(RHDPtr rhdPtr); |
||
58 | |||
59 | Bool OldSetupConnectors(RHDPtr rhdPtr); |
||
60 | Bool OldConnectorsInit(RHDPtr rhdPtr); |
||
61 | |||
62 | int rhdInitHeap(RHDPtr rhdPtr); |
||
63 | |||
64 | static enum rhdCardType rhdGetCardType(RHDPtr rhdPtr); |
||
65 | |||
66 | |||
67 | static u32_t _PciApi(int cmd); |
||
68 | static int SupportedModes; |
||
69 | |||
70 | int __stdcall drvEntry(int)__asm__("_drvEntry"); |
||
71 | |||
72 | typedef struct |
||
73 | { |
||
74 | unsigned handle; |
||
75 | unsigned io_code; |
||
76 | void *input; |
||
77 | int inp_size; |
||
78 | void *output; |
||
79 | int out_size; |
||
80 | }ioctl_t; |
||
81 | |||
82 | typedef int (_stdcall *srv_proc_t)(ioctl_t *); |
||
83 | |||
84 | int _stdcall srv_proc(ioctl_t *io); |
||
85 | |||
86 | extern PciChipset_t RHDPCIchipsets[]; |
||
87 | extern struct rhdCard *RHDCardIdentify(RHDPtr rhdPtr); |
||
88 | |||
89 | static struct RHDRec rhd; |
||
90 | static struct _ScrnInfoRec Scrn; |
||
91 | |||
92 | void sysSetScreen(int width, int height) |
||
93 | { |
||
94 | asm __volatile__ |
||
95 | ( |
||
96 | "dec eax \n\t" |
||
97 | "dec edx \n\t" |
||
98 | "call [DWORD PTR __imp__SetScreen] \n\t" |
||
99 | : |
||
100 | :"a" (width),"d"(height) |
||
101 | :"memory","cc" |
||
102 | ); |
||
103 | } |
||
104 | |||
105 | static int RegService(char *name, srv_proc_t proc) |
||
106 | { |
||
107 | int retval; |
||
108 | |||
109 | asm __volatile__ |
||
110 | ( |
||
111 | "push %[t] \n\t" |
||
112 | "push %[t1] \n\t" |
||
113 | "call [DWORD PTR __imp__RegService] \n\t" |
||
114 | :"=eax" (retval) |
||
115 | :[t] "g" (proc),[t1] "g" (name) |
||
116 | :"memory", "ebx" |
||
117 | ); |
||
118 | return retval; |
||
119 | }; |
||
120 | |||
121 | static u32_t _PciApi(int cmd) |
||
122 | { |
||
123 | u32_t retval; |
||
124 | |||
125 | asm __volatile__ |
||
126 | ( |
||
127 | "call [DWORD PTR __imp__PciApi]" |
||
128 | :"=eax" (retval) |
||
129 | :"a" (cmd) |
||
130 | :"memory" |
||
131 | ); |
||
132 | return retval; |
||
133 | }; |
||
134 | |||
135 | const PciChipset_t *PciDevMatch(CARD16 dev,const PciChipset_t *list) |
||
136 | { |
||
137 | while(list->device) |
||
138 | { |
||
139 | if(dev==list->device) |
||
140 | return list; |
||
141 | list++; |
||
142 | } |
||
143 | return 0; |
||
144 | } |
||
145 | |||
146 | const char * |
||
147 | xf86TokenToString(SymTabPtr table, int token) |
||
148 | { |
||
149 | int i; |
||
150 | |||
151 | for (i = 0; table[i].token >= 0 && table[i].token != token; i++){}; |
||
152 | |||
153 | if (table[i].token < 0) |
||
154 | return NULL; |
||
155 | else |
||
156 | return(table[i].name); |
||
157 | } |
||
158 | |||
159 | int FindPciDevice() |
||
160 | { |
||
161 | const PciChipset_t *dev; |
||
162 | u32_t bus, last_bus; |
||
163 | |||
164 | if( (last_bus = _PciApi(1))==-1) |
||
165 | return 0; |
||
166 | |||
167 | for(bus=0;bus<=last_bus;bus++) |
||
168 | { |
||
169 | u32_t devfn; |
||
170 | |||
171 | for(devfn=0;devfn<256;devfn++) |
||
172 | { |
||
173 | u32_t id; |
||
174 | id = PciRead32(bus,devfn, 0); |
||
175 | |||
176 | if( (CARD16)id != VENDOR_ATI) |
||
177 | continue; |
||
178 | |||
179 | if( (dev=PciDevMatch(id>>16,RHDPCIchipsets))!=0) |
||
180 | { |
||
181 | |||
182 | rhd.PciDeviceID = (id>>16); |
||
183 | |||
184 | rhd.bus = bus; |
||
185 | rhd.pci.bus = bus; |
||
186 | rhd.devfn = devfn; |
||
187 | rhd.pci.devfn = devfn; |
||
188 | rhd.PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
||
189 | |||
190 | rhd.ChipSet = dev->family; |
||
191 | // rhd.IsMobility = dev->mobility; |
||
192 | // rhd.IsIGP = dev->igp; |
||
193 | // rhd.HasCRTC2 = !dev->nocrtc2; |
||
194 | // rhd.HasSingleDAC = dev->singledac; |
||
195 | // rhd.InternalTVOut = !dev->nointtvout; |
||
196 | |||
197 | pciGetInfo(&rhd.pci); |
||
198 | |||
199 | rhd.subvendor_id = rhd.pci.subsysVendor; |
||
200 | rhd.subdevice_id = rhd.pci.subsysCard; |
||
201 | |||
202 | //rhd.chipset = (char*)xf86TokenToString(RADEONChipsets, rhd.device_id); |
||
203 | |||
204 | return 1; |
||
205 | }; |
||
206 | }; |
||
207 | }; |
||
208 | |||
209 | dbgprintf("Device not found\n"); |
||
210 | |||
211 | return 0; |
||
212 | } |
||
213 | |||
214 | |||
215 | static Bool |
||
216 | rhdMapMMIO() |
||
217 | { |
||
218 | |||
219 | rhd.MMIOMapSize = 1 << rhd.pci.size[RHD_MMIO_BAR]; |
||
220 | rhd.MMIOBase = MapIoMem(rhd.pci.memBase[RHD_MMIO_BAR], |
||
221 | rhd.MMIOMapSize,PG_SW+PG_NOCACHE); |
||
222 | if( !rhd.MMIOBase) |
||
223 | return 0; |
||
224 | |||
225 | DBG(dbgprintf("Mapped IO at %x (size %x)\n", rhd.MMIOBase, rhd.MMIOMapSize)); |
||
226 | |||
227 | return 1; |
||
228 | } |
||
229 | |||
230 | #define RADEON_NB_TOM 0x15c |
||
231 | static CARD32 |
||
232 | rhdGetVideoRamSize(RHDPtr rhdPtr) |
||
233 | { |
||
234 | CARD32 RamSize, BARSize; |
||
235 | |||
236 | if (rhdPtr->ChipSet == RHD_RS690) |
||
237 | RamSize = (_RHDRegRead(rhdPtr, R5XX_CONFIG_MEMSIZE))>>10; |
||
238 | else |
||
239 | if (rhdPtr->IsIGP) |
||
240 | { |
||
241 | CARD32 tom = _RHDRegRead(rhdPtr, RADEON_NB_TOM); |
||
242 | RamSize = (((tom >> 16) - (tom & 0xffff) + 1) << 6); |
||
243 | _RHDRegWrite(rhdPtr,R5XX_CONFIG_MEMSIZE, RamSize<<10); |
||
244 | } |
||
245 | else |
||
246 | { |
||
247 | if (rhdPtr->ChipSet < RHD_R600) |
||
248 | { |
||
249 | RamSize = (_RHDRegRead(rhdPtr, R5XX_CONFIG_MEMSIZE)) >> 10; |
||
250 | if(RamSize==0) RamSize=8192; |
||
251 | } |
||
252 | else |
||
253 | RamSize = (_RHDRegRead(rhdPtr, R6XX_CONFIG_MEMSIZE)) >> 10; |
||
254 | }; |
||
255 | |||
256 | BARSize = 1 << (rhdPtr->pci.size[RHD_FB_BAR] - 10); |
||
257 | if(BARSize==0) |
||
258 | BARSize = 0x20000; |
||
259 | |||
260 | if (RamSize > BARSize) { |
||
261 | DBG(dbgprintf("The detected amount of videoram" |
||
262 | " exceeds the PCI BAR aperture.\n")); |
||
263 | DBG(dbgprintf("Using only %dkB of the total " |
||
264 | "%dkB.\n", (int) BARSize, (int) RamSize)); |
||
265 | return BARSize; |
||
266 | } |
||
267 | else return RamSize; |
||
268 | } |
||
269 | |||
270 | |||
271 | Bool RHDScalePolicy(struct rhdMonitor *Monitor, struct rhdConnector *Connector) |
||
272 | { |
||
273 | if (!Monitor || !Monitor->UseFixedModes || !Monitor->NativeMode) |
||
274 | return FALSE; |
||
275 | |||
276 | if (Connector->Type != RHD_CONNECTOR_PANEL) |
||
277 | return FALSE; |
||
278 | |||
279 | return TRUE; |
||
280 | } |
||
281 | |||
282 | static void |
||
283 | rhdOutputConnectorCheck(struct rhdConnector *Connector) |
||
284 | { |
||
285 | struct rhdOutput *Output; |
||
286 | int i; |
||
287 | |||
288 | /* First, try to sense */ |
||
289 | for (i = 0; i < 2; i++) { |
||
290 | Output = Connector->Output[i]; |
||
291 | if (Output && Output->Sense) { |
||
292 | /* |
||
293 | * This is ugly and needs to change when the TV support patches are in. |
||
294 | * The problem here is that the Output struct can be used for two connectors |
||
295 | * and thus two different devices |
||
296 | */ |
||
297 | if (Output->SensedType == RHD_SENSED_NONE) { |
||
298 | /* Do this before sensing as AtomBIOS sense needs this info */ |
||
299 | if ((Output->SensedType = Output->Sense(Output, Connector)) != RHD_SENSED_NONE) { |
||
300 | RHDOutputPrintSensedType(Output); |
||
301 | Output->Connector = Connector; |
||
302 | break; |
||
303 | } |
||
304 | } |
||
305 | } |
||
306 | } |
||
307 | |||
308 | if (i == 2) { |
||
309 | /* now just enable the ones without sensing */ |
||
310 | for (i = 0; i < 2; i++) { |
||
311 | Output = Connector->Output[i]; |
||
312 | if (Output && !Output->Sense) { |
||
313 | Output->Connector = Connector; |
||
314 | break; |
||
315 | } |
||
316 | } |
||
317 | } |
||
318 | } |
||
319 | |||
320 | /* |
||
321 | * |
||
322 | */ |
||
323 | static Bool |
||
324 | rhdModeLayoutSelect(RHDPtr rhdPtr) |
||
325 | { |
||
326 | struct rhdOutput *Output; |
||
327 | struct rhdConnector *Connector; |
||
328 | Bool Found = FALSE; |
||
329 | char *ignore = NULL; |
||
330 | Bool ConnectorIsDMS59 = FALSE; |
||
331 | int i = 0; |
||
332 | |||
333 | RHDFUNC(rhdPtr); |
||
334 | |||
335 | /* housekeeping */ |
||
336 | rhdPtr->Crtc[0]->PLL = rhdPtr->PLLs[0]; |
||
337 | rhdPtr->Crtc[0]->LUT = rhdPtr->LUT[0]; |
||
338 | |||
339 | rhdPtr->Crtc[1]->PLL = rhdPtr->PLLs[1]; |
||
340 | rhdPtr->Crtc[1]->LUT = rhdPtr->LUT[1]; |
||
341 | |||
342 | /* start layout afresh */ |
||
343 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
344 | { |
||
345 | Output->Active = FALSE; |
||
346 | Output->Crtc = NULL; |
||
347 | Output->Connector = NULL; |
||
348 | } |
||
349 | |||
350 | /* quick and dirty option so that some output choice exists */ |
||
351 | // ignore = xf86GetOptValString(rhdPtr->Options, OPTION_IGNORECONNECTOR); |
||
352 | |||
353 | /* handle cards with DMS-59 connectors appropriately. The DMS-59 to VGA |
||
354 | adapter does not raise HPD at all, so we need a fallback there. */ |
||
355 | if (rhdPtr->Card) |
||
356 | { |
||
357 | ConnectorIsDMS59 = rhdPtr->Card->flags & RHD_CARD_FLAG_DMS59; |
||
358 | if (ConnectorIsDMS59) |
||
359 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "Card %s has a DMS-59" |
||
360 | " connector.\n", rhdPtr->Card->name); |
||
361 | } |
||
362 | |||
363 | /* Check on the basis of Connector->HPD */ |
||
364 | for (i = 0; i < RHD_CONNECTORS_MAX; i++) |
||
365 | { |
||
366 | Connector = rhdPtr->Connector[i]; |
||
367 | |||
368 | if (!Connector) |
||
369 | continue; |
||
370 | |||
371 | |||
372 | if (Connector->HPDCheck) { |
||
373 | if (Connector->HPDCheck(Connector)) { |
||
374 | Connector->HPDAttached = TRUE; |
||
375 | rhdOutputConnectorCheck(Connector); |
||
376 | } else { |
||
377 | Connector->HPDAttached = FALSE; |
||
378 | if (ConnectorIsDMS59) |
||
379 | rhdOutputConnectorCheck(Connector); |
||
380 | } |
||
381 | } else |
||
382 | rhdOutputConnectorCheck(Connector); |
||
383 | } |
||
384 | |||
385 | i = 0; /* counter for CRTCs */ |
||
386 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
387 | if (Output->Connector) { |
||
388 | struct rhdMonitor *Monitor = NULL; |
||
389 | |||
390 | Connector = Output->Connector; |
||
391 | |||
392 | Monitor = RHDMonitorInit(Connector); |
||
393 | |||
394 | if (!Monitor && (Connector->Type == RHD_CONNECTOR_PANEL)) { |
||
395 | xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "Unable to attach a" |
||
396 | " monitor to connector \"%s\"\n", Connector->Name); |
||
397 | Output->Active = FALSE; |
||
398 | } else if (!Output->AllocFree || Output->AllocFree(Output, RHD_OUTPUT_ALLOC)){ |
||
399 | Connector->Monitor = Monitor; |
||
400 | |||
401 | Output->Active = TRUE; |
||
402 | |||
403 | Output->Crtc = rhdPtr->Crtc[i & 1]; /* ;) */ |
||
404 | i++; |
||
405 | |||
406 | Output->Crtc->Active = TRUE; |
||
407 | |||
408 | if (RHDScalePolicy(Monitor, Connector)) { |
||
409 | Output->Crtc->ScaledToMode = RHDModeCopy(Monitor->NativeMode); |
||
410 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, |
||
411 | "Crtc[%i]: found native mode from Monitor[%s]: ", |
||
412 | Output->Crtc->Id, Monitor->Name); |
||
413 | RHDPrintModeline(Output->Crtc->ScaledToMode); |
||
414 | } |
||
415 | Found = TRUE; |
||
416 | |||
417 | if (Monitor) { |
||
418 | /* If this is a DVI attached monitor, enable reduced blanking. |
||
419 | * TODO: iiyama vm pro 453: CRT with DVI-D == No reduced. |
||
420 | */ |
||
421 | if ((Output->Id == RHD_OUTPUT_TMDSA) || |
||
422 | (Output->Id == RHD_OUTPUT_LVTMA) || |
||
423 | (Output->Id == RHD_OUTPUT_KLDSKP_LVTMA) || |
||
424 | (Output->Id == RHD_OUTPUT_UNIPHYA) || |
||
425 | (Output->Id == RHD_OUTPUT_UNIPHYB)) |
||
426 | Monitor->ReducedAllowed = TRUE; |
||
427 | |||
428 | /* allow user to override settings globally */ |
||
429 | if (rhdPtr->forceReduced.set) |
||
430 | Monitor->ReducedAllowed = rhdPtr->forceReduced.val.bool; |
||
431 | |||
432 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, |
||
433 | "Connector \"%s\" uses Monitor \"%s\":\n", |
||
434 | Connector->Name, Monitor->Name); |
||
435 | RHDMonitorPrint(Monitor); |
||
436 | } else |
||
437 | xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, |
||
438 | "Connector \"%s\": Failed to retrieve Monitor" |
||
439 | " information.\n", Connector->Name); |
||
440 | } |
||
441 | } |
||
442 | |||
443 | /* Now validate the scaled modes attached to crtcs */ |
||
444 | for (i = 0; i < 2; i++) { |
||
445 | struct rhdCrtc *crtc = rhdPtr->Crtc[i]; |
||
446 | if (crtc->ScaledToMode && RHDValidateScaledToMode(crtc, crtc->ScaledToMode) != MODE_OK) { |
||
447 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "Crtc[%i]: scaled mode invalid.\n", crtc->Id); |
||
448 | xfree(crtc->ScaledToMode); |
||
449 | crtc->ScaledToMode = NULL; |
||
450 | } |
||
451 | } |
||
452 | return Found; |
||
453 | } |
||
454 | |||
455 | /* |
||
456 | * |
||
457 | */ |
||
458 | static void |
||
459 | rhdModeLayoutPrint(RHDPtr rhdPtr) |
||
460 | { |
||
461 | struct rhdCrtc *Crtc; |
||
462 | struct rhdOutput *Output; |
||
463 | Bool Found; |
||
464 | |||
465 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "Listing modesetting layout:\n\n"); |
||
466 | |||
467 | /* CRTC 1 */ |
||
468 | Crtc = rhdPtr->Crtc[0]; |
||
469 | if (Crtc->Active) { |
||
470 | xf86Msg(X_NONE, "\t%s: tied to %s and %s:\n", |
||
471 | Crtc->Name, Crtc->PLL->Name, Crtc->LUT->Name); |
||
472 | |||
473 | Found = FALSE; |
||
474 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
475 | if (Output->Active && (Output->Crtc == Crtc)) { |
||
476 | if (!Found) { |
||
477 | xf86Msg(X_NONE, "\t\tOutputs: %s (%s)", |
||
478 | Output->Name, Output->Connector->Name); |
||
479 | Found = TRUE; |
||
480 | } else |
||
481 | xf86Msg(X_NONE, ", %s (%s)", Output->Name, |
||
482 | Output->Connector->Name); |
||
483 | } |
||
484 | |||
485 | if (!Found) |
||
486 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, |
||
487 | "%s is active without outputs\n", Crtc->Name); |
||
488 | else |
||
489 | xf86Msg(X_NONE, "\n"); |
||
490 | } else |
||
491 | xf86Msg(X_NONE, "\t%s: unused\n", Crtc->Name); |
||
492 | xf86Msg(X_NONE, "\n"); |
||
493 | |||
494 | /* CRTC 2 */ |
||
495 | Crtc = rhdPtr->Crtc[1]; |
||
496 | if (Crtc->Active) { |
||
497 | xf86Msg(X_NONE, "\t%s: tied to %s and %s:\n", |
||
498 | Crtc->Name, Crtc->PLL->Name, Crtc->LUT->Name); |
||
499 | |||
500 | Found = FALSE; |
||
501 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
502 | if (Output->Active && (Output->Crtc == Crtc)) { |
||
503 | if (!Found) { |
||
504 | xf86Msg(X_NONE, "\t\tOutputs: %s (%s)", |
||
505 | Output->Name, Output->Connector->Name); |
||
506 | Found = TRUE; |
||
507 | } else |
||
508 | xf86Msg(X_NONE, ", %s (%s)", Output->Name, |
||
509 | Output->Connector->Name); |
||
510 | } |
||
511 | |||
512 | if (!Found) |
||
513 | xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, |
||
514 | "%s is active without outputs\n", Crtc->Name); |
||
515 | else |
||
516 | xf86Msg(X_NONE, "\n"); |
||
517 | } else |
||
518 | xf86Msg(X_NONE, "\t%s: unused\n", Crtc->Name); |
||
519 | xf86Msg(X_NONE, "\n"); |
||
520 | |||
521 | /* Print out unused Outputs */ |
||
522 | Found = FALSE; |
||
523 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
524 | if (!Output->Active) { |
||
525 | if (!Found) { |
||
526 | xf86Msg(X_NONE, "\t\tUnused Outputs: %s", Output->Name); |
||
527 | Found = TRUE; |
||
528 | } else |
||
529 | xf86Msg(X_NONE, ", %s", Output->Name); |
||
530 | } |
||
531 | |||
532 | if (Found) |
||
533 | xf86Msg(X_NONE, "\n"); |
||
534 | xf86Msg(X_NONE, "\n"); |
||
535 | } |
||
536 | |||
537 | |||
538 | DisplayModePtr |
||
539 | rhdCreateModesListAndValidate(ScrnInfoPtr pScrn, Bool Silent); |
||
540 | void RHDPrintModeline(DisplayModePtr mode); |
||
541 | |||
542 | int RHDPreInit() |
||
543 | { |
||
544 | RHDI2CDataArg i2cArg; |
||
545 | RHDPtr rhdPtr = &rhd; |
||
546 | |||
547 | /* We need access to IO space already */ |
||
548 | if (!rhdMapMMIO()) { |
||
549 | dbgprintf("Failed to map MMIO.\n"); |
||
550 | return 0; |
||
551 | }; |
||
552 | |||
553 | |||
554 | if (RHDIsIGP(rhd.ChipSet)) |
||
555 | rhdGetIGPNorthBridgeInfo(&rhd); |
||
556 | |||
557 | rhd.Card = RHDCardIdentify(&rhd); |
||
558 | if (rhd.Card) |
||
559 | dbgprintf("Detected an %s on a %s\n", rhd.chipset_name, rhd.Card->name); |
||
560 | else |
||
561 | dbgprintf("Detected an %s on an unidentified card\n", rhd.chipset_name); |
||
562 | |||
563 | if (rhdPtr->Card && rhdPtr->Card->flags & RHD_CARD_FLAG_HPDSWAP && |
||
564 | rhdPtr->hpdUsage == RHD_HPD_USAGE_AUTO) |
||
565 | rhdPtr->hpdUsage = RHD_HPD_USAGE_AUTO_SWAP; |
||
566 | if (rhdPtr->Card && rhdPtr->Card->flags & RHD_CARD_FLAG_HPDOFF && |
||
567 | rhdPtr->hpdUsage == RHD_HPD_USAGE_AUTO) |
||
568 | rhdPtr->hpdUsage = RHD_HPD_USAGE_AUTO_OFF; |
||
569 | |||
570 | rhdPtr->cardType = rhdGetCardType(rhdPtr); |
||
571 | |||
572 | |||
573 | { |
||
574 | AtomBiosArgRec atomBiosArg; |
||
575 | |||
576 | rhd.UseAtomFlags = (RHD_ATOMBIOS_ON << RHD_ATOMBIOS_CRTC) | |
||
577 | (RHD_ATOMBIOS_ON << RHD_ATOMBIOS_OUTPUT) | |
||
578 | (RHD_ATOMBIOS_ON << RHD_ATOMBIOS_PLL); |
||
579 | |||
580 | // rhd.UseAtomFlags = 0; |
||
581 | |||
582 | if (RHDAtomBiosFunc(&rhd, NULL, ATOMBIOS_INIT, &atomBiosArg) == ATOM_SUCCESS) |
||
583 | { |
||
584 | rhd.atomBIOS = atomBiosArg.atomhandle; |
||
585 | } |
||
586 | } |
||
587 | |||
588 | rhd.videoRam = rhdGetVideoRamSize(&rhd); |
||
589 | if (!rhd.videoRam) |
||
590 | { |
||
591 | dbgprintf("No Video RAM detected.\n"); |
||
592 | goto error1; |
||
593 | } |
||
594 | dbgprintf("VideoRAM: %d kByte\n",rhd.videoRam); |
||
595 | |||
596 | if (rhd.atomBIOS) /* for testing functions */ |
||
597 | { |
||
598 | AtomBiosArgRec atomBiosArg; |
||
599 | |||
600 | atomBiosArg.fb.start = rhd.FbFreeStart; |
||
601 | atomBiosArg.fb.size = rhd.FbFreeSize; |
||
602 | if (RHDAtomBiosFunc(&rhd, rhd.atomBIOS, ATOMBIOS_ALLOCATE_FB_SCRATCH, |
||
603 | &atomBiosArg) == ATOM_SUCCESS) |
||
604 | { |
||
605 | rhd.FbFreeStart = atomBiosArg.fb.start; |
||
606 | rhd.FbFreeSize = atomBiosArg.fb.size; |
||
607 | }; |
||
608 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_DEFAULT_ENGINE_CLOCK, &atomBiosArg); |
||
609 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_DEFAULT_MEMORY_CLOCK, &atomBiosArg); |
||
610 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_MAX_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg); |
||
611 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_MIN_PIXEL_CLOCK_PLL_OUTPUT, &atomBiosArg); |
||
612 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_MAX_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg); |
||
613 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_MIN_PIXEL_CLOCK_PLL_INPUT, &atomBiosArg); |
||
614 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_MAX_PIXEL_CLK, &atomBiosArg); |
||
615 | RHDAtomBiosFunc(&rhd, rhd.atomBIOS, GET_REF_CLOCK, &atomBiosArg); |
||
616 | } |
||
617 | |||
618 | |||
619 | rhd.FbFreeStart = 0; |
||
620 | rhd.FbFreeSize = rhd.videoRam << 10; |
||
621 | |||
622 | |||
623 | if (RHDI2CFunc((int)&rhd, NULL, RHD_I2C_INIT, &i2cArg) == RHD_I2C_SUCCESS) |
||
624 | rhd.I2C = i2cArg.I2CBusList; |
||
625 | else |
||
626 | { |
||
627 | dbgprintf("I2C init failed\n"); |
||
628 | goto error1; |
||
629 | }; |
||
630 | |||
631 | if (!rhd.atomBIOS) |
||
632 | { |
||
633 | dbgprintf("No ATOMBIOS detected. Done.\n"); |
||
634 | return 0; |
||
635 | } |
||
636 | |||
637 | // rhdMapFB(&rhd); |
||
638 | |||
639 | Scrn.rhdPtr = &rhd; |
||
640 | Scrn.driverName = "Radeon HD driver"; |
||
641 | Scrn.bitsPerPixel = 32; |
||
642 | Scrn.depth = 32; |
||
643 | Scrn.virtualX = 1280; |
||
644 | Scrn.virtualY = 1024; |
||
645 | Scrn.displayWidth = 1280; |
||
646 | |||
647 | rhd.pScrn = &Scrn; |
||
648 | |||
649 | rhd.FbScanoutStart = 0; |
||
650 | rhd.FbScanoutSize = 8*1024*1024; |
||
651 | rhd.FbFreeStart = 8*1024*1024; |
||
652 | rhd.FbFreeSize = rhd.FbMapSize - 8*1024*1024; |
||
653 | |||
654 | rhdInitHeap(&rhd); |
||
655 | |||
656 | RHDVGAInit(&rhd); |
||
657 | RHDMCInit(&rhd); |
||
658 | |||
659 | if (!RHDCrtcsInit(&rhd)) |
||
660 | RHDAtomCrtcsInit(&rhd); |
||
661 | if (!RHDPLLsInit(&rhd)) |
||
662 | RHDAtomPLLsInit(&rhd); |
||
663 | |||
664 | RHDLUTsInit(&rhd); |
||
665 | |||
666 | if (!RHDConnectorsInit(&rhd, rhd.Card)) |
||
667 | { |
||
668 | dbgprintf("Card information has invalid connector information\n"); |
||
669 | goto error1; |
||
670 | } |
||
671 | |||
672 | { |
||
673 | struct rhdAtomOutputDeviceList *OutputDeviceList = NULL; |
||
674 | |||
675 | if (rhdPtr->Card |
||
676 | && rhdPtr->Card->ConnectorInfo[0].Type != RHD_CONNECTOR_NONE |
||
677 | && (rhdPtr->Card->DeviceInfo[0][0] != atomNone |
||
678 | || rhdPtr->Card->DeviceInfo[0][1] != atomNone)) |
||
679 | { |
||
680 | int i, k = 0; |
||
681 | |||
682 | for (i = 0; i < RHD_CONNECTORS_MAX; i++) |
||
683 | { |
||
684 | int j; |
||
685 | if (rhdPtr->Card->ConnectorInfo[i].Type == RHD_CONNECTOR_NONE) |
||
686 | break; |
||
687 | for (j = 0; j < MAX_OUTPUTS_PER_CONNECTOR; j++) |
||
688 | { |
||
689 | if (rhdPtr->Card->ConnectorInfo[i].Output[j] != RHD_OUTPUT_NONE) |
||
690 | { |
||
691 | if (!(OutputDeviceList = |
||
692 | (struct rhdAtomOutputDeviceList *) |
||
693 | xrealloc(OutputDeviceList, |
||
694 | sizeof (struct rhdAtomOutputDeviceList) * (k + 1)))) |
||
695 | break; |
||
696 | OutputDeviceList[k].ConnectorType = rhdPtr->Card->ConnectorInfo[i].Type; |
||
697 | OutputDeviceList[k].DeviceId = rhdPtr->Card->DeviceInfo[i][j]; |
||
698 | OutputDeviceList[k].OutputType = rhdPtr->Card->ConnectorInfo[i].Output[j]; |
||
699 | dbgprintf("OutputDevice: C: 0x%2.2x O: 0x%2.2x DevID: 0x%2.2x\n", |
||
700 | OutputDeviceList[k].ConnectorType, |
||
701 | OutputDeviceList[k].OutputType, |
||
702 | OutputDeviceList[k].DeviceId); |
||
703 | k++; |
||
704 | } |
||
705 | } |
||
706 | } |
||
707 | } |
||
708 | else |
||
709 | { |
||
710 | AtomBiosArgRec data; |
||
711 | |||
712 | data.chipset = rhdPtr->ChipSet; |
||
713 | if (RHDAtomBiosFunc(rhdPtr, rhdPtr->atomBIOS, |
||
714 | ATOMBIOS_GET_OUTPUT_DEVICE_LIST, &data) == ATOM_SUCCESS) |
||
715 | OutputDeviceList = data.OutputDeviceList; |
||
716 | } |
||
717 | |||
718 | if (OutputDeviceList) |
||
719 | { |
||
720 | struct rhdOutput *Output; |
||
721 | |||
722 | for (Output = rhdPtr->Outputs; Output; Output = Output->Next) |
||
723 | RHDAtomSetupOutputDriverPrivate(OutputDeviceList, Output); |
||
724 | xfree(OutputDeviceList); |
||
725 | } |
||
726 | } |
||
727 | |||
728 | |||
729 | if (!rhdModeLayoutSelect(&rhd)) |
||
730 | { |
||
731 | dbgprintf("Failed to detect a connected monitor\n"); |
||
732 | goto error1; |
||
733 | } |
||
734 | |||
735 | RHDConfigMonitorSet(&rhd, FALSE); |
||
736 | rhdModeLayoutPrint(&rhd); |
||
737 | |||
738 | { |
||
739 | DisplayModePtr Modes, tmp; |
||
740 | |||
741 | Modes = RHDModesPoolCreate(&Scrn, FALSE); |
||
742 | Scrn.modePool = Modes; |
||
743 | |||
744 | tmp = Modes; |
||
745 | SupportedModes=0; |
||
746 | while(tmp) |
||
747 | { |
||
748 | dbgprintf("%dx%d@%3.1fHz\n",tmp->CrtcHDisplay, |
||
749 | tmp->CrtcVDisplay,tmp->VRefresh); |
||
750 | tmp=tmp->next; |
||
751 | SupportedModes++; |
||
752 | }; |
||
753 | // rhdModeInit(&Scrn,Modes); |
||
754 | //RHDAdjustFrame(&rhd,0,0,0); |
||
755 | }; |
||
756 | dbgprintf("All done\n"); |
||
757 | return 1; |
||
758 | |||
759 | error1: |
||
760 | return 0; |
||
761 | }; |
||
762 | |||
763 | int __stdcall drvEntry(int action) |
||
764 | { |
||
765 | int i; |
||
766 | |||
767 | if(action != 1) |
||
768 | return 0; |
||
769 | |||
9583 | vitalkrilo | 770 | if(!dbg_open("/sys/drivers/ati.txt")) |
1029 | serge | 771 | { |
9583 | vitalkrilo | 772 | printf("Can't open /sys/drivers/ati.txt\nExit\n"); |
1029 | serge | 773 | return 0; |
774 | } |
||
775 | if(!FindPciDevice()) |
||
776 | return 0; |
||
777 | |||
778 | rhd.scrnIndex = (int)&rhd; |
||
779 | |||
780 | for(i=0;i<6;i++) |
||
781 | { |
||
782 | if(rhd.pci.memBase[i]) |
||
783 | dbgprintf("Memory base_%d 0x%x size 0x%x\n", |
||
784 | i,rhd.pci.memBase[i],(1< |
||
785 | }; |
||
786 | for(i=0;i<6;i++) |
||
787 | { |
||
788 | if(rhd.pci.ioBase[i]) |
||
789 | dbgprintf("Io base_%d 0x%x size 0x%x\n", |
||
790 | i,rhd.pci.ioBase[i],(1< |
||
791 | }; |
||
792 | if(RHDPreInit()==0) |
||
793 | return 0; |
||
794 | |||
795 | return RegService("RHD", srv_proc); |
||
796 | }; |
||
797 | |||
798 | |||
799 | void usleep(u32_t delay) |
||
800 | { |
||
801 | if(!delay) delay++; |
||
802 | delay*=1000; |
||
803 | |||
804 | asm( |
||
805 | "1:\n\t" |
||
806 | "xor eax, eax \n\t" |
||
807 | "cpuid \n\t" |
||
808 | "dec edi \n\t" |
||
809 | "jnz 1b" |
||
810 | : |
||
811 | :"D"(delay) |
||
812 | :"eax","ebx","ecx","edx" |
||
813 | ); |
||
814 | } |
||
815 | |||
816 | |||
817 | //git://anongit.freedesktop.org/git/xorg/xserver |
||
818 | //git://anongit.freedesktop.org/git/xorg/lib/libpciaccess |
||
819 | |||
820 | int KernelFree(void *p) |
||
821 | { |
||
822 | |||
823 | return 0; |
||
824 | } |
||
825 | |||
826 | static void |
||
827 | rhdPrepareMode(RHDPtr rhdPtr) |
||
828 | { |
||
829 | RHDFUNC(rhdPtr); |
||
830 | |||
831 | /* no active outputs == no mess */ |
||
832 | RHDOutputsPower(rhdPtr, RHD_POWER_RESET); |
||
833 | } |
||
834 | |||
835 | /* |
||
836 | * */static void |
||
837 | rhdModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) |
||
838 | { |
||
839 | RHDPtr rhdPtr = pScrn->rhdPtr; |
||
840 | |||
841 | RHDFUNC(rhdPtr); |
||
842 | |||
843 | rhdSetMode(pScrn, mode); |
||
844 | } |
||
845 | |||
846 | /* * */static void |
||
847 | rhdSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) |
||
848 | { |
||
849 | RHDPtr rhdPtr = RHDPTR(pScrn); |
||
850 | int i; |
||
851 | |||
852 | RHDFUNC(rhdPtr); |
||
853 | |||
854 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting up \"%s\" (%dx%d@%3.1fHz)\n", |
||
855 | mode->name, mode->CrtcHDisplay, mode->CrtcVDisplay, |
||
856 | mode->VRefresh); |
||
857 | |||
858 | /* Set up D1/D2 and appendages */ |
||
859 | for (i = 0; i < 2; i++) { |
||
860 | struct rhdCrtc *Crtc; |
||
861 | |||
862 | Crtc = rhdPtr->Crtc[i]; |
||
863 | if (Crtc->Active) { |
||
864 | Crtc->FBSet(Crtc, pScrn->displayWidth, pScrn->virtualX, pScrn->virtualY, |
||
865 | pScrn->depth, rhdPtr->FbScanoutStart); |
||
866 | if (Crtc->ScaledToMode) { |
||
867 | Crtc->ModeSet(Crtc, Crtc->ScaledToMode); |
||
868 | if (Crtc->ScaleSet) |
||
869 | Crtc->ScaleSet(Crtc, Crtc->ScaleType, mode, Crtc->ScaledToMode); |
||
870 | } else { |
||
871 | Crtc->ModeSet(Crtc, mode); |
||
872 | if (Crtc->ScaleSet) |
||
873 | Crtc->ScaleSet(Crtc, RHD_CRTC_SCALE_TYPE_NONE, mode, NULL); |
||
874 | } |
||
875 | RHDPLLSet(Crtc->PLL, mode->Clock); |
||
876 | Crtc->LUTSelect(Crtc, Crtc->LUT); |
||
877 | RHDOutputsMode(rhdPtr, Crtc, Crtc->ScaledToMode |
||
878 | ? Crtc->ScaledToMode : mode); |
||
879 | } |
||
880 | } |
||
881 | |||
882 | /* shut down that what we don't use */ |
||
883 | RHDPLLsShutdownInactive(rhdPtr); |
||
884 | RHDOutputsShutdownInactive(rhdPtr); |
||
885 | |||
886 | if (rhdPtr->Crtc[0]->Active) |
||
887 | rhdPtr->Crtc[0]->Power(rhdPtr->Crtc[0], RHD_POWER_ON); |
||
888 | else |
||
889 | rhdPtr->Crtc[0]->Power(rhdPtr->Crtc[0], RHD_POWER_SHUTDOWN); |
||
890 | |||
891 | if (rhdPtr->Crtc[1]->Active) |
||
892 | rhdPtr->Crtc[1]->Power(rhdPtr->Crtc[1], RHD_POWER_ON); |
||
893 | else |
||
894 | rhdPtr->Crtc[1]->Power(rhdPtr->Crtc[1], RHD_POWER_SHUTDOWN); |
||
895 | |||
896 | RHDOutputsPower(rhdPtr, RHD_POWER_ON); |
||
897 | } |
||
898 | |||
899 | |||
900 | |||
901 | static void |
||
902 | RHDAdjustFrame(RHDPtr rhdPtr, int x, int y, int flags) |
||
903 | { |
||
904 | // ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; |
||
905 | // RHDPtr rhdPtr = RHDPTR(pScrn); |
||
906 | struct rhdCrtc *Crtc; |
||
907 | |||
908 | Crtc = rhdPtr->Crtc[0]; |
||
909 | if (Crtc->Active) |
||
910 | Crtc->FrameSet(Crtc, x, y); |
||
911 | |||
912 | Crtc = rhdPtr->Crtc[1]; |
||
913 | if ( Crtc->Active) |
||
914 | Crtc->FrameSet(Crtc, x, y); |
||
915 | |||
916 | } |
||
917 | |||
918 | static Bool |
||
919 | rhdMapFB(RHDPtr rhdPtr) |
||
920 | { |
||
921 | CARD32 membase; |
||
922 | RHDFUNC(rhdPtr); |
||
923 | |||
924 | rhdPtr->FbMapSize = 1 << rhdPtr->pci.size[RHD_FB_BAR]; |
||
925 | membase = rhdPtr->pci.memBase[RHD_FB_BAR]; |
||
926 | |||
927 | rhdPtr->FbBase = MapIoMem(membase, rhdPtr->FbMapSize,PG_SW+PG_NOCACHE); |
||
928 | |||
929 | if (!rhdPtr->FbBase) |
||
930 | return FALSE; |
||
931 | |||
932 | /* These devices have an internal address reference, which some other |
||
933 | * address registers in there also use. This can be different from the |
||
934 | * address in the BAR */ |
||
935 | if (rhdPtr->ChipSet < RHD_R600) |
||
936 | rhdPtr->FbIntAddress = _RHDRegRead(rhdPtr, HDP_FB_LOCATION)<< 16; |
||
937 | else |
||
938 | rhdPtr->FbIntAddress = _RHDRegRead(rhdPtr, R6XX_CONFIG_FB_BASE); |
||
939 | |||
940 | if (rhdPtr->FbIntAddress != membase) |
||
941 | dbgprintf("PCI FB Address (BAR) is at " |
||
942 | "0x%08X while card Internal Address is 0x%08X\n", |
||
943 | (unsigned int) membase,rhdPtr->FbIntAddress); |
||
944 | dbgprintf("Mapped FB at %p (size 0x%08X)\n",rhdPtr->FbBase, rhdPtr->FbMapSize); |
||
945 | return TRUE; |
||
946 | } |
||
947 | |||
948 | |||
949 | #define ERR_PARAM -1 |
||
950 | |||
951 | #pragma pack (push,1) |
||
952 | typedef struct |
||
953 | { |
||
954 | short width; |
||
955 | short height; |
||
956 | short bpp; |
||
957 | short freq; |
||
958 | }mode_t; |
||
959 | #pragma pack (pop) |
||
960 | |||
961 | int get_modes(mode_t *mode, int count) |
||
962 | { |
||
963 | if(count==0) |
||
964 | count = SupportedModes; |
||
965 | else |
||
966 | { |
||
967 | DisplayModePtr tmp; |
||
968 | int i; |
||
969 | |||
970 | if(count>SupportedModes) |
||
971 | count = SupportedModes; |
||
972 | |||
973 | for(i=0,tmp = Scrn.modePool;i |
||
974 | { |
||
975 | mode->width = tmp->CrtcHDisplay; |
||
976 | mode->height = tmp->CrtcVDisplay; |
||
977 | mode->bpp = 32; |
||
978 | mode->freq = (short)__builtin_ceilf(tmp->VRefresh); |
||
979 | } |
||
980 | } |
||
981 | return count; |
||
982 | } |
||
983 | |||
984 | int set_mode(mode_t *mode) |
||
985 | { |
||
986 | DisplayModePtr tmp; |
||
987 | int i; |
||
988 | |||
989 | for(i=0,tmp = Scrn.modePool;i |
||
990 | { |
||
991 | if( (mode->width == tmp->CrtcHDisplay) && |
||
992 | (mode->height == tmp->CrtcVDisplay) && |
||
993 | (mode->freq == (short)__builtin_ceilf(tmp->VRefresh))) |
||
994 | { |
||
995 | Scrn.virtualX = mode->width ; |
||
996 | Scrn.virtualY = mode->height; |
||
997 | Scrn.displayWidth = mode->width; |
||
998 | rhdModeInit(&Scrn,tmp); |
||
999 | sysSetScreen(mode->width,mode->height); |
||
1000 | dbgprintf("set_mode OK\n"); |
||
1001 | return 1; |
||
1002 | }; |
||
1003 | } |
||
1004 | return 0; |
||
1005 | }; |
||
1006 | |||
1007 | #define API_VERSION 0x01000100 |
||
1008 | |||
1009 | #define SRV_GETVERSION 0 |
||
1010 | #define SRV_ENUM_MODES 1 |
||
1011 | #define SRV_SET_MODE 2 |
||
1012 | |||
1013 | int _stdcall srv_proc(ioctl_t *io) |
||
1014 | { |
||
1015 | u32_t *inp; |
||
1016 | u32_t *outp; |
||
1017 | |||
1018 | inp = io->input; |
||
1019 | outp = io->output; |
||
1020 | |||
1021 | switch(io->io_code) |
||
1022 | { |
||
1023 | case SRV_GETVERSION: |
||
1024 | if(io->out_size==4) |
||
1025 | { |
||
1026 | *(u32_t*)io->output = API_VERSION; |
||
1027 | return 0; |
||
1028 | } |
||
1029 | break; |
||
1030 | case SRV_ENUM_MODES: |
||
1031 | if(io->inp_size==8) |
||
1032 | { |
||
1033 | int count; |
||
1034 | count = get_modes((mode_t*)(*inp),(int)*(inp+1)); |
||
1035 | |||
1036 | if(io->out_size==4) |
||
1037 | { |
||
1038 | *outp = count; |
||
1039 | return 0; |
||
1040 | } |
||
1041 | }; |
||
1042 | break; |
||
1043 | case SRV_SET_MODE: |
||
1044 | if(io->inp_size==8) |
||
1045 | { |
||
1046 | int err; |
||
1047 | err = set_mode((mode_t*)inp); |
||
1048 | |||
1049 | if(io->out_size==4) |
||
1050 | { |
||
1051 | *outp = err; |
||
1052 | return 0; |
||
1053 | } |
||
1054 | }; |
||
1055 | break; |
||
1056 | |||
1057 | }; |
||
1058 | |||
1059 | return -1; |
||
1060 | } |
||
1061 | |||
1062 | |||
1063 | CARD32 |
||
1064 | _RHDReadMC(int scrnIndex, CARD32 addr) |
||
1065 | { |
||
1066 | RHDPtr rhdPtr = (RHDPtr)scrnIndex; |
||
1067 | CARD32 ret; |
||
1068 | |||
1069 | if (rhdPtr->ChipSet < RHD_RS600) { |
||
1070 | _RHDRegWrite(rhdPtr, MC_IND_INDEX, addr); |
||
1071 | ret = _RHDRegRead(rhdPtr, MC_IND_DATA); |
||
1072 | } else if (rhdPtr->ChipSet == RHD_RS600) { |
||
1073 | _RHDRegWrite(rhdPtr, RS60_MC_NB_MC_INDEX, addr); |
||
1074 | ret = _RHDRegRead(rhdPtr, RS60_MC_NB_MC_DATA); |
||
1075 | } else if (rhdPtr->ChipSet == RHD_RS690 || rhdPtr->ChipSet == RHD_RS740) { |
||
1076 | pciWriteLong(rhdPtr->NBPciTag, RS69_MC_INDEX, addr & ~RS69_MC_IND_WR_EN); |
||
1077 | ret = pciReadLong(rhdPtr->NBPciTag, RS69_MC_DATA); |
||
1078 | } else { |
||
1079 | pciWriteLong(rhdPtr->NBPciTag, RS78_NB_MC_IND_INDEX, (addr & ~RS78_MC_IND_WR_EN)); |
||
1080 | ret = pciReadLong(rhdPtr->NBPciTag, RS78_NB_MC_IND_DATA); |
||
1081 | } |
||
1082 | |||
1083 | RHDDebug(scrnIndex,"%s(0x%08X) = 0x%08X\n",__func__,(unsigned int)addr, |
||
1084 | (unsigned int)ret); |
||
1085 | return ret; |
||
1086 | } |
||
1087 | |||
1088 | void |
||
1089 | _RHDWriteMC(int scrnIndex, CARD32 addr, CARD32 data) |
||
1090 | { |
||
1091 | RHDPtr rhdPtr = (RHDPtr)scrnIndex; |
||
1092 | |||
1093 | RHDDebug(scrnIndex,"%s(0x%08X, 0x%08X)\n",__func__,(unsigned int)addr, |
||
1094 | (unsigned int)data); |
||
1095 | |||
1096 | if (rhdPtr->ChipSet < RHD_RS600) { |
||
1097 | _RHDRegWrite(rhdPtr, MC_IND_INDEX, addr | MC_IND_WR_EN); |
||
1098 | _RHDRegWrite(rhdPtr, MC_IND_DATA, data); |
||
1099 | } else if (rhdPtr->ChipSet == RHD_RS600) { |
||
1100 | _RHDRegWrite(rhdPtr, RS60_MC_NB_MC_INDEX, addr | RS60_NB_MC_IND_WR_EN); |
||
1101 | _RHDRegWrite(rhdPtr, RS60_MC_NB_MC_DATA, data); |
||
1102 | } else if (rhdPtr->ChipSet == RHD_RS690 || rhdPtr->ChipSet == RHD_RS740) { |
||
1103 | pciWriteLong(rhdPtr->NBPciTag, RS69_MC_INDEX, addr | RS69_MC_IND_WR_EN); |
||
1104 | pciWriteLong(rhdPtr->NBPciTag, RS69_MC_DATA, data); |
||
1105 | } else { |
||
1106 | pciWriteLong(rhdPtr->NBPciTag, RS78_NB_MC_IND_INDEX, addr | RS78_MC_IND_WR_EN); |
||
1107 | pciWriteLong(rhdPtr->NBPciTag, RS78_NB_MC_IND_DATA, data); |
||
1108 | } |
||
1109 | } |
||
1110 | |||
1111 | /* |
||
1112 | * |
||
1113 | */ |
||
1114 | static void |
||
1115 | rhdGetIGPNorthBridgeInfo(RHDPtr rhdPtr) |
||
1116 | { |
||
1117 | switch (rhdPtr->ChipSet) |
||
1118 | { |
||
1119 | case RHD_RS600: |
||
1120 | break; |
||
1121 | case RHD_RS690: |
||
1122 | case RHD_RS740: |
||
1123 | case RHD_RS780: |
||
1124 | rhdPtr->NBPciTag = pciTag(0,0,0); |
||
1125 | break; |
||
1126 | default: |
||
1127 | break; |
||
1128 | } |
||
1129 | } |
||
1130 | |||
1131 | static enum rhdCardType |
||
1132 | rhdGetCardType(RHDPtr rhdPtr) |
||
1133 | { |
||
1134 | CARD32 cmd_stat; |
||
1135 | |||
1136 | if (rhdPtr->ChipSet == RHD_RS780) |
||
1137 | return RHD_CARD_PCIE; |
||
1138 | |||
1139 | cmd_stat = pciReadLong(rhdPtr->PciTag, PCI_CMD_STAT_REG); |
||
1140 | |||
1141 | if (cmd_stat & 0x100000) { |
||
1142 | CARD32 cap_ptr, cap_id; |
||
1143 | |||
1144 | cap_ptr = pciReadLong(rhdPtr->PciTag, 0x34); |
||
1145 | cap_ptr &= 0xfc; |
||
1146 | |||
1147 | while (cap_ptr) |
||
1148 | { |
||
1149 | cap_id = pciReadLong(rhdPtr->PciTag, cap_ptr); |
||
1150 | switch (cap_id & 0xff) { |
||
1151 | case RHD_PCI_CAPID_AGP: |
||
1152 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "AGP Card Detected\n"); |
||
1153 | return RHD_CARD_AGP; |
||
1154 | case RHD_PCI_CAPID_PCIE: |
||
1155 | xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "PCIE Card Detected\n"); |
||
1156 | return RHD_CARD_PCIE; |
||
1157 | } |
||
1158 | cap_ptr = (cap_id >> 8) & 0xff; |
||
1159 | } |
||
1160 | } |
||
1161 | return RHD_CARD_NONE; |
||
1162 | }>>><>>><>> |
||
1163 | |||
1164 |