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 : }