1 /******************************************************************************* 2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. 3 * 4 */ 5 /*=========================================================================*//** 6 @mainpage PolarFire MSS Frequency Meter Bare Metal Driver. 7 The MSS Clock Frequency Meter (CFM) block is used to support test of the 8 DLL's within the MSS. All functional clocks are connected to the CFM block. 9 10 The frequency meter can be configured to measure time or frequency, time 11 allowing items such as PLL lock times to be tested and frequency to test 12 oscillator frequencies. 13 14 Upto 8 circuit counters are implemented. 15 16 @section intro_sec Introduction 17 18 *//*=========================================================================*/ 19 #ifndef __COREPLEX_PLATFORM_CFM_H_ 20 #define __COREPLEX_PLATFORM_CFM_H_ 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 27 28 /* CFM Register base address. */ 29 #define CFM_REG_BASE 0x20006000 30 31 /***************************************************************************//** 32 The __cfm_count_id_t enumeration is used to identify the channel used. 33 */ 34 typedef enum __cfm_count_id 35 { 36 CFM_COUNT_0 = 0, 37 CFM_COUNT_1, 38 CFM_COUNT_2, 39 CFM_COUNT_3, 40 CFM_COUNT_4, 41 CFM_COUNT_5, 42 CFM_COUNT_6, 43 CFM_COUNT_7, 44 cfm_lastCH, 45 } cfm_count_id_t; 46 47 48 49 /***************************************************************************//** 50 The cfm_channel_mode enumeration is used to specify the channel mode. 51 */ 52 typedef enum __cfm_channel_mode 53 { 54 CFM_CH_DISABLED = 0, 55 CFM_CH_FREQUENCY_MODE, 56 CFM_CH_RESERVER, 57 CFM_CH_TIMER_MODE, 58 CFM_CH_lastmd 59 } cfm_channel_mode; 60 61 62 63 typedef enum __cfm_error_id_t 64 { 65 CFM_OK = 0, 66 ERROR_INVALID_CLK_SELECTION_GROUP, 67 ERROR_INVALID_REF_SEL0, 68 ERROR_INVALID_REF_SEL1, 69 ERROR_INVALID_CHANNEL_DRIVE_CLK_MONITOR, 70 ERROR_INVALID_CFM_BUSY, 71 72 ERROR_NULL_VALUE, 73 74 ERROR_CFMLAST_ID 75 } cfm_error_id_t; 76 77 78 typedef struct _cfmRegs 79 { 80 __IO uint32_t controlReg; /* CFM Control Register */ 81 __IO uint32_t clkselReg; /* Clock Selection Register */ 82 __IO uint32_t runtimeReg; /* Reference Count Value */ 83 __IO uint32_t modelReg; /* Sets the measurement mode */ 84 85 __I uint32_t count0; /* Count x value */ 86 __I uint32_t count1; 87 __I uint32_t count2; 88 __I uint32_t count3; 89 __I uint32_t count4; 90 __I uint32_t count5; 91 __I uint32_t count6; 92 __I uint32_t count7; 93 94 __I uint32_t reserved[4]; /*Reserved registers, padding structure */ 95 96 97 }CFM; 98 99 100 #define CFM_REG ((CFM *)CFM_REG_BASE) 101 102 typedef struct _cfmChannelMode 103 { 104 uint8_t channel0; /* Channel x mode */ 105 uint8_t channel1; /* Channel x mode */ 106 uint8_t channel2; /* Channel x mode */ 107 uint8_t channel3; /* Channel x mode */ 108 uint8_t channel4; /* Channel x mode */ 109 uint8_t channel5; /* Channel x mode */ 110 uint8_t channel6; /* Channel x mode */ 111 uint8_t channel7; /* Channel x mode */ 112 113 }cfmChannelMode; 114 115 #define CFM_CONTROL_REG_BUSY_MASK 0x01U 116 #define CFM_CONTROL_REG_START_MASK 0x01U 117 #define CFM_CONTROL_REG_STOP_BITS_SHIFT 0x01U 118 119 #define CFM_CLK_SEL_MASK 0x07U 120 121 122 #define CFM_CLK_REFSEL0_MASK 0x01U 123 #define CFM_CLK_REFSEL0SHIFT 0x04U 124 125 126 #define CFM_CLK_REFSEL1_MASK 0x01U 127 #define CFM_CLK_REFSEL1SHIFT 0x05U 128 129 130 #define CFM_CLK_MONSEL_MASK 0x07U 131 #define CFM_CLK_MONSEL_SHIFT 0x08U 132 133 134 135 #define CFM_CLK_MONEN_MASK 0x01 136 #define CFM_CLK_MONEN_SHIFT 11U 137 138 #define CFM_RUNTIME_REG_MASK 0xFFFFFFU 139 140 #define CFM_CHANNEL_MODE_MASK 0x3U 141 142 #define CFM_CH0_SHIFT_MASK 0x00U 143 #define CFM_CH1_SHIFT_MASK 0x02U 144 #define CFM_CH2_SHIFT_MASK 0x04U 145 #define CFM_CH3_SHIFT_MASK 0x06U 146 #define CFM_CH4_SHIFT_MASK 0x08U 147 #define CFM_CH5_SHIFT_MASK 0x0AU 148 #define CFM_CH6_SHIFT_MASK 0x0CU 149 #define CFM_CH7_SHIFT_MASK 0x0EU 150 151 152 153 /***************************************************************************** 154 * CFM Function Prototypes 155 ******************************************************************************* 156 */ 157 /*-------------------------------------------------------------------------*//** 158 The MSS_CFM_control_start() function causes the measurement circuitry 159 to start. This state of 'busy' will clear which measurement is complete. 160 161 162 @param None 163 164 @return 165 Busy state 166 167 Example: 168 The following call will start the CFM 169 @code 170 MSS_CFM_control_start( ); 171 @endcode 172 */ 173 uint8_t MSS_CFM_control_start(void); 174 175 176 177 /*-------------------------------------------------------------------------*//** 178 The MSS_CFM_control_stop() function causes the measurement circuitry 179 to stop. 180 181 182 @param None 183 184 185 @return uint8_t 186 Returns the busy flag. 187 188 189 Example: 190 The following call will stop the CFM 191 @code 192 MSS_CFM_control_stop( ); 193 @endcode 194 */ 195 uint8_t MSS_CFM_control_stop(void); 196 197 198 199 200 201 /*-------------------------------------------------------------------------*//** 202 The MSS_CLF_clk_configuration() function is used to configure the clock 203 selection register. 204 205 @param clkSel 206 Selects which group of clock inputs are selected by the channels, control 207 the input multiplexer. 208 209 @param refsel0 210 Selects the reference input, 0=clkref1 / 1=clkref2 211 212 @param refsel1 213 When in timer mode allows ATPG (corners) / clkref3 clock input to clock 214 the channel counters. This clock input is expected to be sourced from an 215 on-chip PLL to support at-speed testing. This allows the timer to clocked 216 off a much higher clock frequency that the reference counter that is limited 217 to 100Mhz. 218 219 @param monSEL 220 Selects which channel drives the clock monitor output 0-7. 221 222 223 @param monEN 224 Enables the clock monitor output. 225 226 227 @return 228 cfm_error_id_t 229 230 Example: 231 The following call will configure clk 0, using clkref1, channel zero drives 232 the clock monitor and enable the clock monitor output. 233 @code 234 MSS_GPIO_config( 0, 0, 0, 0, 1 ); 235 @endcode 236 */ 237 cfm_error_id_t MSS_CLF_clk_configuration( 238 uint8_t clkSel, 239 uint8_t refsel0, 240 uint8_t refsel1, 241 uint8_t monSEL, 242 uint8_t monEN 243 ); 244 245 246 247 248 /*-------------------------------------------------------------------------*//** 249 The MSS_CFM_runtime_register() function is used to set how many reference 250 clock cycles the frequency and time measurement should be made. 251 The register does NOT change during oepration 252 253 @param refcount 254 The reference count value. 255 256 */ 257 void MSS_CFM_runtime_register( 258 uint32_t referenceCount 259 ); 260 261 262 263 /*-------------------------------------------------------------------------*//** 264 The MSS_CFM_channel_mode() function is used to set the measurement mode for 265 the specified channel. 266 2'b00: Disabled 267 2'b01: Frequency Mode 268 2'b11: Timer Mode 269 2'b10: Reserved 270 271 @param cfmChannelMode 272 Configuration structure for each channel 273 274 @return 275 None 276 277 */ 278 void MSS_CFM_channel_mode(cfmChannelMode chMode); 279 280 281 /*-------------------------------------------------------------------------*//** 282 The MSS_CFM_get_count() function is used to get the count value. 283 Block must not be busy. 284 285 @param ch 286 The channel ID to return the count for. 287 288 @param count 289 The count for the channel register. 290 291 @return 292 cfm_error_id_t 293 294 Example: 295 The following call will return the value in count register. channel 0 296 297 @code 298 MSS_CFM_get_count(); 299 @endcode 300 */ 301 cfm_error_id_t MSS_CFM_get_count(cfm_count_id_t ch, uint32_t *count); 302 303 304 #ifdef __cplusplus 305 } 306 #endif 307 308 309 #endif /* __COREPLEX_PLATFORM_CFM_H_ */ 310