Subversion Repositories Kolibri OS

Rev

Rev 1407 | 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;inext,mode++)
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;inext)
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