Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. #include "ati_pciids_gen.h"
  3. #include "radeon_chipset_gen.h"
  4. #include "radeon_chipinfo_gen.h"
  5.  
  6.  
  7.  
  8. const char *
  9. xf86TokenToString(SymTabPtr table, int token)
  10. {
  11.     int i;
  12.  
  13.     for (i = 0; table[i].token >= 0 && table[i].token != token; i++){};
  14.  
  15.     if (table[i].token < 0)
  16.       return NULL;
  17.     else
  18.       return(table[i].name);
  19. }
  20.  
  21.  
  22.  
  23. const RADEONCardInfo *RadeonDevMatch(u16_t dev,const RADEONCardInfo *list)
  24. {
  25.   while(list->pci_device_id)
  26.   {
  27.     if(dev == list->pci_device_id)
  28.       return list;
  29.     list++;
  30.   }
  31.   return 0;
  32. }
  33.  
  34.  
  35. RHDPtr FindPciDevice()
  36. {
  37.     const RADEONCardInfo *dev;
  38.     u32_t bus, last_bus;
  39.  
  40.     if( (last_bus = PciApi(1))==-1)
  41.         return 0;
  42.  
  43.     for(bus=0;bus<=last_bus;bus++)
  44.     {
  45.         u32_t devfn;
  46.  
  47.         for(devfn=0;devfn<256;devfn++)
  48.         {
  49.             u32_t id;
  50.             id = PciRead32(bus,devfn, 0);
  51.  
  52.             if( (u16_t)id != VENDOR_ATI)
  53.                 continue;
  54.  
  55.             rhd.PciDeviceID = (id>>16);
  56.  
  57.             if( (dev = RadeonDevMatch(rhd.PciDeviceID, RADEONCards))!=NULL)
  58.             {
  59.                 u32_t reg2C;
  60.                 int i;
  61.  
  62.                 rhd.chipset = (char*)xf86TokenToString(RADEONChipsets, rhd.PciDeviceID);
  63.                 if (!rhd.chipset){
  64.                     dbgprintf("ChipID 0x%04x is not recognized\n", rhd.PciDeviceID);
  65.                     return FALSE;
  66.                 }
  67.                 dbgprintf("Chipset: \"%s\" (ChipID = 0x%04x)\n",
  68.                            rhd.chipset,rhd.PciDeviceID);
  69.  
  70.                 rhd.bus = bus;
  71.                 rhd.devfn = devfn;
  72.                 rhd.PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
  73.  
  74.                 rhd.ChipFamily  = dev->chip_family;
  75.                 rhd.IsMobility  = dev->mobility;
  76.                 rhd.IsIGP       = dev->igp;
  77.                 rhd.HasCRTC2    = !dev->nocrtc2;
  78.  
  79.                 reg2C = PciRead32(bus,devfn, 0x2C);
  80.  
  81.                 rhd.subvendor_id = reg2C & 0xFFFF;;
  82.                 rhd.subdevice_id = reg2C >> 16;
  83.  
  84.                 if (rhd.ChipFamily >= CHIP_FAMILY_R600)
  85.                     dbgprintf("R600 unsupported yet.\nExit\n");
  86.  
  87.                 if( rhd.ChipFamily >= CHIP_FAMILY_R420)
  88.                     rhd.gart_type = RADEON_IS_PCIE;
  89.                 else
  90.                     rhd.gart_type = RADEON_IS_PCI;
  91.  
  92.                 for (i = 0; i < 6; i++)
  93.                 {
  94.                     u32_t base;
  95.                     Bool validSize;
  96.  
  97.                     base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2));
  98.                     if(base)
  99.                     {
  100.                         if (base & PCI_MAP_IO){
  101.                             rhd.ioBase[i] = (u32_t)PCIGETIO(base);
  102.                             rhd.memtype[i]   = base & PCI_MAP_IO_ATTR_MASK;
  103.                         }
  104.                         else{
  105.                             rhd.memBase[i] = (u32_t)PCIGETMEMORY(base);
  106.                             rhd.memtype[i] = base & PCI_MAP_MEMORY_ATTR_MASK;
  107.                         }
  108.                     }
  109.                     rhd.memsize[i] = pciGetBaseSize(bus,devfn, i, TRUE, &validSize);
  110.                 }
  111.                 return &rhd;
  112.             }
  113.         }
  114.     };
  115.     return NULL;
  116. }
  117.  
  118.  
  119.  
  120. u32_t pciGetBaseSize(int bus, int devfn, int index, Bool destructive, Bool *min)
  121. {
  122.   int offset;
  123.   u32_t addr1;
  124.   u32_t addr2;
  125.   u32_t mask1;
  126.   u32_t mask2;
  127.   int bits = 0;
  128.  
  129.   /*
  130.    * silently ignore bogus index values.  Valid values are 0-6.  0-5 are
  131.    * the 6 base address registers, and 6 is the ROM base address register.
  132.    */
  133.   if (index < 0 || index > 6)
  134.     return 0;
  135.  
  136.   if (min)
  137.     *min = destructive;
  138.  
  139.   /* Get the PCI offset */
  140.   if (index == 6)
  141.     offset = PCI_MAP_ROM_REG;
  142.   else
  143.     offset = PCI_MAP_REG_START + (index << 2);
  144.  
  145.   addr1 = PciRead32(bus, devfn, offset);
  146.   /*
  147.    * Check if this is the second part of a 64 bit address.
  148.    * XXX need to check how endianness affects 64 bit addresses.
  149.    */
  150.   if (index > 0 && index < 6) {
  151.     addr2 = PciRead32(bus, devfn, offset - 4);
  152.     if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
  153.       return 0;
  154.   }
  155.  
  156.   if (destructive) {
  157.      PciWrite32(bus, devfn, offset, 0xffffffff);
  158.      mask1 = PciRead32(bus, devfn, offset);
  159.      PciWrite32(bus, devfn, offset, addr1);
  160.   } else {
  161.     mask1 = addr1;
  162.   }
  163.  
  164.   /* Check if this is the first part of a 64 bit address. */
  165.   if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1))
  166.   {
  167.     if (PCIGETMEMORY(mask1) == 0)
  168.     {
  169.       addr2 = PciRead32(bus, devfn, offset + 4);
  170.       if (destructive)
  171.       {
  172.         PciWrite32(bus, devfn, offset + 4, 0xffffffff);
  173.         mask2 = PciRead32(bus, devfn, offset + 4);
  174.         PciWrite32(bus, devfn, offset + 4, addr2);
  175.       }
  176.       else
  177.      {
  178.        mask2 = addr2;
  179.      }
  180.      if (mask2 == 0)
  181.        return 0;
  182.      bits = 32;
  183.      while ((mask2 & 1) == 0)
  184.      {
  185.        bits++;
  186.        mask2 >>= 1;
  187.      }
  188.      if (bits > 32)
  189.           return bits;
  190.     }
  191.   }
  192.   if (index < 6)
  193.     if (PCI_MAP_IS_MEM(mask1))
  194.       mask1 = PCIGETMEMORY(mask1);
  195.     else
  196.       mask1 = PCIGETIO(mask1);
  197.   else
  198.     mask1 = PCIGETROM(mask1);
  199.   if (mask1 == 0)
  200.     return 0;
  201.   bits = 0;
  202.   while ((mask1 & 1) == 0) {
  203.     bits++;
  204.     mask1 >>= 1;
  205.   }
  206.   /* I/O maps can be no larger than 8 bits */
  207.  
  208.   if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8)
  209.     bits = 8;
  210.   /* ROM maps can be no larger than 24 bits */
  211.   if (index == 6 && bits > 24)
  212.     bits = 24;
  213.   return bits;
  214. }
  215.  
  216.  
  217.  
  218. #define PCI_FIND_CAP_TTL    48
  219.  
  220. static int __pci_find_next_cap_ttl(PCITAG pciTag, u8_t pos,
  221.                                    int cap, int *ttl)
  222. {
  223.     u8_t id;
  224.  
  225.     while ((*ttl)--)
  226.     {
  227.         pos = pciReadByte(pciTag, pos);
  228.                 if (pos < 0x40)
  229.                         break;
  230.                 pos &= ~3;
  231.         id = pciReadByte(pciTag, pos + PCI_CAP_LIST_ID);
  232.                 if (id == 0xff)
  233.                         break;
  234.                 if (id == cap)
  235.                         return pos;
  236.                 pos += PCI_CAP_LIST_NEXT;
  237.         }
  238.         return 0;
  239. }
  240.  
  241. static int __pci_find_next_cap(PCITAG pciTag, u8_t pos, int cap)
  242. {
  243.         int ttl = PCI_FIND_CAP_TTL;
  244.  
  245.     return __pci_find_next_cap_ttl(pciTag, pos, cap, &ttl);
  246. }
  247.  
  248. static int __pci_bus_find_cap_start(PCITAG pciTag)
  249. {
  250.     u16_t status;
  251.     u8_t  hdr_type;
  252.  
  253.     status = pciReadWord(pciTag, PCI_STATUS);
  254.         if (!(status & PCI_STATUS_CAP_LIST))
  255.                 return 0;
  256.  
  257.     hdr_type = pciReadByte(pciTag, 0x0E);
  258.     switch (hdr_type)
  259.     {
  260.         case PCI_HEADER_TYPE_NORMAL:
  261.         case PCI_HEADER_TYPE_BRIDGE:
  262.             return PCI_CAPABILITY_LIST;
  263.         case PCI_HEADER_TYPE_CARDBUS:
  264.             return PCI_CB_CAPABILITY_LIST;
  265.         default:
  266.             return 0;
  267.         }
  268.         return 0;
  269. }
  270.  
  271.  
  272. int pci_find_capability(PCITAG pciTag, int cap)
  273. {
  274.         int pos;
  275.  
  276.     pos = __pci_bus_find_cap_start(pciTag);
  277.         if (pos)
  278.         pos = __pci_find_next_cap(pciTag, pos, cap);
  279.  
  280.         return pos;
  281. }
  282.  
  283.  
  284. static __inline__ int drm_device_is_pcie(PCITAG pciTag)
  285. {
  286.     return pci_find_capability(pciTag, PCI_CAP_ID_EXP);
  287. }
  288.  
  289.