LCOV - code coverage report
Current view: top level - src - device.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 33 119 27.7 %
Date: 2025-09-09 12:09:29 Functions: 9 19 47.4 %

          Line data    Source code
       1             : #include <algorithm>
       2             : 
       3             : #include "device.hpp"
       4             : #include "log.hpp"
       5             : 
       6             : #define BROADCAST_NONE    0
       7             : #define BROADCAST_ALL     1
       8             : #define BROADCAST_CHANNEL 2
       9             : #define BROADCAST_ELINK   3
      10             : 
      11             : #define MAX_BROADCAST_CHANNELS (32)
      12             : #define MAX_BROADCAST_ELINKS (1 + 32 + 64)
      13             : 
      14          32 : Device::Device(unsigned dev_no, uint8_t vid, uint16_t did, uint16_t cid)
      15          32 :     : m_device_number(dev_no), m_vid(vid), m_did(did), m_cid(cid) {}
      16             : 
      17             : 
      18          37 : bool Device::has_wrong_rm() {
      19          37 :     unsigned int regmap = get_regmap_version();
      20             : #if REGMAP_VERSION < 0x0500
      21             :     return ((regmap < 0x0400) || (regmap >= 0x0500));
      22             : #else
      23          37 :     return ((regmap < 0x0500) || (regmap >= 0x0600));
      24             : #endif
      25             : }
      26             : 
      27             : 
      28           0 : bool Device::is_full_mode() {
      29           0 :     return (m_firmware_type == FIRMW_FULL or m_firmware_type == FIRMW_MROD or m_firmware_type == FIRMW_INTERLAKEN);
      30             : }
      31             : 
      32             : 
      33          82 : bool Device::is_lpgbt_mode() {
      34          82 :     u_int mode = m_firmware_type;
      35          82 :     return (mode == FIRMW_PIXEL or mode == FIRMW_STRIP or mode == FIRMW_LPGBT or mode == FIRMW_HGTD_LUMI or mode == FIRMW_BCM_PRIME);
      36             : }
      37             : 
      38             : 
      39           0 : uint64_t Device::get_elink(u_int channel, u_int egroup, u_int epath) {
      40           0 :     bool lpgbt = this->is_lpgbt_mode();
      41           0 :     int egroup_shift = (lpgbt) ? 2 : 3;
      42           0 :     return (channel << 6) + (egroup << egroup_shift) + epath;
      43             : }
      44             : 
      45             : 
      46          41 : uint32_t Device::get_channel(uint32_t elink) {
      47          41 :     return (elink >> 6);
      48             : }
      49             : 
      50             : 
      51          41 : uint32_t Device::get_egroup(uint32_t elink) {
      52          41 :     bool lpgbt = this->is_lpgbt_mode();
      53          41 :     int egroup_shift = (lpgbt) ? 2 : 3;
      54          41 :     return (elink & 0x3f) >> egroup_shift;
      55             : }
      56             : 
      57             : 
      58          41 : uint32_t Device::get_epath(uint32_t elink) {
      59          41 :     bool lpgbt = this->is_lpgbt_mode();
      60          41 :     int egroup_shift = (lpgbt) ? 2 : 3;
      61          41 :     return egroup_shift == 2 ? elink & 0x03 : elink & 0x07;
      62             : }
      63             : 
      64             : 
      65           0 : u_int Device::get_egroups_per_channel(u_int is_to_flx) {
      66           0 :     u_int egroups_per_chan;
      67           0 :     if( is_to_flx == 0 ) {
      68             :         // tohost
      69           0 :         if( this->is_full_mode() )
      70             :             egroups_per_chan = 1;
      71           0 :         else if( this->is_lpgbt_mode() )
      72             :             egroups_per_chan = 7;
      73           0 :         else if( this->get_wide_mode() )
      74             :             egroups_per_chan = 7;
      75             :         else 
      76           0 :             egroups_per_chan = 5;
      77             :     } else {
      78             :         // toflx
      79           0 :         if( this->is_full_mode() )
      80             :             egroups_per_chan = 5;
      81           0 :         else if( this->is_lpgbt_mode() )
      82             :             egroups_per_chan = 4;
      83           0 :         else if( this->get_wide_mode() )
      84             :             egroups_per_chan = 3;
      85             :         else
      86           0 :             egroups_per_chan = 5;
      87             :     }
      88           0 :   return egroups_per_chan;
      89             : }
      90             : 
      91             : 
      92           0 : u_int Device::get_epaths_per_egroup(u_int is_to_flx) {
      93           0 :     int epaths_per_egroup;
      94           0 :     if( is_to_flx == 0 ) {
      95             :     // tohost
      96           0 :         if( this->is_full_mode() )
      97             :             epaths_per_egroup = 1;
      98           0 :         else if( this->is_lpgbt_mode() )
      99             :             epaths_per_egroup = 4;
     100           0 :         else if( this->get_wide_mode()) 
     101             :             epaths_per_egroup = 8;
     102             :         else 
     103           0 :             epaths_per_egroup = 8;
     104             :     } else {
     105             :         // toflx
     106           0 :         if( this->is_full_mode() )
     107             :             epaths_per_egroup = 8;
     108           0 :         else if( this->is_lpgbt_mode() and this->get_firmware_type() != FIRMW_STRIP )
     109             :             epaths_per_egroup = 4;
     110           0 :         else if( this->is_lpgbt_mode() and this->get_firmware_type() == FIRMW_STRIP )
     111             :             epaths_per_egroup = 5;
     112           0 :         else if( this->get_wide_mode() )
     113             :             epaths_per_egroup = 8;
     114             :         else
     115           0 :             epaths_per_egroup = 8;
     116             :     }
     117           0 :     return epaths_per_egroup;
     118             : }
     119             : 
     120             : 
     121           0 : u_int Device::get_ctrl_elinks_per_channel() {
     122           0 :     if( m_firmware_type == FIRMW_LTDB )
     123             :         return 3; // IC, EC, AUX
     124             :     else
     125           0 :         return  2; // IC, EC
     126             : }
     127             : 
     128             : 
     129          41 : const std::string Device::get_elink_type_str(elink_type_t encoding) {
     130          41 :     switch(encoding) {
     131           0 :         case NONE_ELINK_TYPE: return "NONE_ELINK_TYPE";
     132          37 :         case DAQ: return "DAQ";
     133           4 :         case TTC: return "TTC";
     134           0 :         case DCS: return "DCS";
     135           0 :         case IC: return "IC";
     136           0 :         default: return "UNKNOWN";
     137             :     }
     138             : }
     139             : 
     140             : 
     141         110 : std::vector<Elink> Device::get_enabled_elinks_of_type(int dmaid, elink_type_t t)
     142             : {
     143         110 :     auto all_elinks = read_enabled_elinks(dmaid);
     144         110 :     std::vector<Elink> ret;
     145         290 :     std::copy_if(all_elinks.begin(), all_elinks.end(),  std::back_inserter(ret), [t](Elink e) { return e.type == t; });
     146             : 
     147             : //    for (auto& e : all_elinks){
     148             : //        if ( e.type == t ){
     149             : //            ret.emplace_back(e);
     150             : //        }
     151             : //    }
     152         110 :     return ret;
     153         110 : }
     154             : 
     155          27 : unsigned int Device::make_dma_lock_mask(const std::vector<int>& dmaids)
     156             : {
     157          27 :     unsigned int lock_mask(LOCK_NONE);
     158          54 :     for(int id : dmaids){
     159          27 :         lock_mask |= LOCK_DMA(id);
     160             :     } 
     161          27 :     return lock_mask;
     162             : }
     163             : 
     164             : 
     165           0 : int64_t Device::broadcast_for(uint64_t elink) {
     166           0 :     if ((elink & 0x7ff) == 0x7ff) return -1;
     167           0 :     if ((elink & 0x3f) == 0x3f) return (elink >> 6) & 0x1f;
     168           0 :     if ((elink & (0x1f << 6)) == (0x1f << 6)) return elink & 0x3f;
     169           0 :     return elink;
     170             : }
     171             : 
     172             : 
     173           0 : int Device::broadcast_type(uint64_t elink) {
     174           0 :     if ((elink & 0x7ff) == 0x7ff) return BROADCAST_ALL;
     175           0 :     if ((elink & 0x3f) == 0x3f) return BROADCAST_CHANNEL;
     176           0 :     if ((elink & (0x1f << 6)) == (0x1f << 6)) return BROADCAST_ELINK;
     177             :     return BROADCAST_NONE;
     178             : }
     179             : 
     180             : 
     181           0 : const std::string Device::broadcast_type_str(uint64_t elink) {
     182           0 :     switch(Device::broadcast_type(elink)) {
     183           0 :         case BROADCAST_NONE:
     184           0 :             return "None";
     185           0 :         case BROADCAST_ALL:
     186           0 :             return "All";
     187           0 :         case BROADCAST_CHANNEL:
     188           0 :             return "Channel";
     189           0 :         case BROADCAST_ELINK:
     190           0 :             return "E-Link";
     191           0 :         default:
     192           0 :             return "Unknown";
     193             :     }
     194             : }
     195             : 
     196             : 
     197             : // Note allow an array of MAX_BROADCAST_ELINKS for bc_elinks.
     198           0 : unsigned Device::broadcast_elinks(uint64_t broadcast_elinks[], const uint64_t broadcast_enable_registers[], uint32_t num_of_channels) {
     199           0 :     unsigned no_of_broadcast_elinks = 0;
     200             : 
     201           0 :     int broadcast_to_all = 0;
     202           0 :     int broadcast_to_elink[64] = {0};
     203           0 :     for (uint32_t channel = 0; channel < num_of_channels; channel++) {
     204           0 :         if (broadcast_enable_registers[channel] > 0) {
     205             :             // Save Broadcast to All
     206           0 :             broadcast_to_all = 1;
     207             : 
     208             :             // Add Broadcast to all e-links of one link
     209           0 :             broadcast_elinks[no_of_broadcast_elinks] = ((channel << 6) | 0x03F);
     210             :             // LOG_INFO("Broadcast for link %d to 0x%x", link, broadcast_elinks[no_of_broadcast_elinks]);
     211           0 :             no_of_broadcast_elinks++;
     212             : 
     213             :             // Save Broadcast to 1 e-link of all links
     214           0 :             for (uint32_t elink = 0; elink < 64; elink++) {
     215           0 :                 if (broadcast_enable_registers[channel] & (1UL << elink)) {
     216             :                     // LOG_INFO("Adding for link %d, elink %d, based on 0x%x and mask 0x%x", link, elink, broadcast_enable_registers[link], (1 << elink));
     217           0 :                     broadcast_to_elink[elink] = 1;
     218             :                 }
     219             :             }
     220             :         }
     221             :     }
     222             : 
     223             :     // Add Broadcast to 1 e-link of all links
     224           0 :     for (uint32_t elink = 0; elink < 64; elink++) {
     225           0 :         if (broadcast_to_elink[elink]) {
     226           0 :             broadcast_elinks[no_of_broadcast_elinks] = ((0x1F << 6) | elink);
     227             :             //LOG_INFO("Broadcast for elink 0x%x to 0x%x", elink, broadcast_elinks[no_of_broadcast_elinks]);
     228           0 :             no_of_broadcast_elinks++;
     229             :         }
     230             :     }
     231             : 
     232             :     // Add Broadcast to All if needed
     233           0 :     if (broadcast_to_all) {
     234           0 :         broadcast_elinks[no_of_broadcast_elinks] = 0x7ff;
     235             :         //LOG_INFO("Broadcast all for links to 0x%x", broadcast_elinks[no_of_broadcast_elinks]);
     236           0 :         no_of_broadcast_elinks++;
     237             :     }
     238             : 
     239           0 :     return no_of_broadcast_elinks;
     240             : }
     241             : 
     242             : 
     243           0 : u_int Device::get_broadcast_elinks(uint64_t broadcast_elinks[], uint32_t num_of_channels) {
     244           0 :     uint64_t broadcast_enable_registers[MAX_BROADCAST_CHANNELS];
     245             : 
     246           0 :     for( unsigned channel=0; channel < num_of_channels; ++channel ) {
     247           0 :         broadcast_enable_registers[channel] = get_broadcast_enable_gen(channel);
     248             :     }
     249             : 
     250           0 :     unsigned no_of_broadcast_elinks = Device::broadcast_elinks(broadcast_elinks, broadcast_enable_registers, num_of_channels);
     251             : 
     252           0 :     LOG_INFO("Deduced %d broadcast elinks", no_of_broadcast_elinks);
     253           0 :     return no_of_broadcast_elinks;
     254             : }

Generated by: LCOV version 1.0