Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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