The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qat/qat_common/adf_clock.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* SPDX-License-Identifier: BSD-3-Clause */
    2 /* Copyright(c) 2007-2022 Intel Corporation */
    3 /* $FreeBSD$ */
    4 #include "adf_accel_devices.h"
    5 #include "adf_common_drv.h"
    6 
    7 #include <linux/delay.h>
    8 
    9 #define MEASURE_CLOCK_RETRIES 10
   10 #define MEASURE_CLOCK_DELTA_THRESHOLD 100
   11 #define MEASURE_CLOCK_DELAY 10000
   12 #define ME_CLK_DIVIDER 16
   13 
   14 #define CLK_DBGFS_FILE "frequency"
   15 #define HB_SYSCTL_ERR(RC)                                                      \
   16         do {                                                                   \
   17                 if (!RC) {                                                     \
   18                         device_printf(GET_DEV(accel_dev),                      \
   19                                       "Memory allocation failed in \
   20                                 adf_heartbeat_dbg_add\n");                     \
   21                         return ENOMEM;                                         \
   22                 }                                                              \
   23         } while (0)
   24 
   25 int
   26 adf_clock_debugfs_add(struct adf_accel_dev *accel_dev)
   27 {
   28         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
   29 
   30         struct sysctl_ctx_list *qat_sysctl_ctx;
   31         struct sysctl_oid *qat_sysctl_tree;
   32         struct sysctl_oid *rc = 0;
   33 
   34         qat_sysctl_ctx =
   35             device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
   36         qat_sysctl_tree =
   37             device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev);
   38 
   39         rc = SYSCTL_ADD_UINT(qat_sysctl_ctx,
   40                              SYSCTL_CHILDREN(qat_sysctl_tree),
   41                              OID_AUTO,
   42                              CLK_DBGFS_FILE,
   43                              CTLFLAG_RD,
   44                              &hw_data->clock_frequency,
   45                              0,
   46                              "clock frequency");
   47         HB_SYSCTL_ERR(rc);
   48         return 0;
   49 }
   50 
   51 /**
   52  * adf_dev_measure_clock() -- Measure the CPM clock frequency
   53  * @accel_dev: Pointer to acceleration device.
   54  * @frequency: Pointer to returned frequency in Hz.
   55  *
   56  * Return: 0 on success, error code otherwise.
   57  */
   58 static int
   59 measure_clock(struct adf_accel_dev *accel_dev, u32 *frequency)
   60 {
   61         struct timespec ts1;
   62         struct timespec ts2;
   63         struct timespec ts3;
   64         struct timespec ts4;
   65         struct timespec delta;
   66         u64 delta_us = 0;
   67         u64 timestamp1 = 0;
   68         u64 timestamp2 = 0;
   69         u64 temp = 0;
   70         int tries = 0;
   71 
   72         if (!accel_dev || !frequency)
   73                 return EIO;
   74         do {
   75                 nanotime(&ts1);
   76                 if (adf_get_fw_timestamp(accel_dev, &timestamp1)) {
   77                         device_printf(GET_DEV(accel_dev),
   78                                       "Failed to get fw timestamp\n");
   79                         return EIO;
   80                 }
   81                 nanotime(&ts2);
   82 
   83                 delta = timespec_sub(ts2, ts1);
   84                 temp = delta.tv_nsec;
   85                 do_div(temp, NSEC_PER_USEC);
   86 
   87                 delta_us = delta.tv_sec * USEC_PER_SEC + temp;
   88         } while (delta_us > MEASURE_CLOCK_DELTA_THRESHOLD &&
   89                  ++tries < MEASURE_CLOCK_RETRIES);
   90 
   91         if (tries >= MEASURE_CLOCK_RETRIES) {
   92                 device_printf(GET_DEV(accel_dev),
   93                               "Excessive clock measure delay\n");
   94                 return EIO;
   95         }
   96 
   97         usleep_range(MEASURE_CLOCK_DELAY, MEASURE_CLOCK_DELAY * 2);
   98         tries = 0;
   99         do {
  100                 nanotime(&ts3);
  101                 if (adf_get_fw_timestamp(accel_dev, &timestamp2)) {
  102                         device_printf(GET_DEV(accel_dev),
  103                                       "Failed to get fw timestamp\n");
  104                         return EIO;
  105                 }
  106                 nanotime(&ts4);
  107 
  108                 delta = timespec_sub(ts4, ts3);
  109                 temp = delta.tv_nsec;
  110                 do_div(temp, NSEC_PER_USEC);
  111 
  112                 delta_us = delta.tv_sec * USEC_PER_SEC + temp;
  113         } while (delta_us > MEASURE_CLOCK_DELTA_THRESHOLD &&
  114                  ++tries < MEASURE_CLOCK_RETRIES);
  115 
  116         if (tries >= MEASURE_CLOCK_RETRIES) {
  117                 device_printf(GET_DEV(accel_dev),
  118                               "Excessive clock measure delay\n");
  119                 return EIO;
  120         }
  121 
  122         delta = timespec_sub(ts3, ts1);
  123         temp =
  124             delta.tv_sec * NSEC_PER_SEC + delta.tv_nsec + (NSEC_PER_USEC / 2);
  125         do_div(temp, NSEC_PER_USEC);
  126         delta_us = temp;
  127         /* Don't pretend that this gives better than 100KHz resolution */
  128         temp = (timestamp2 - timestamp1) * ME_CLK_DIVIDER * 10 + (delta_us / 2);
  129         do_div(temp, delta_us);
  130         *frequency = temp * 100000;
  131 
  132         return 0;
  133 }
  134 
  135 /**
  136  * adf_dev_measure_clock() -- Measure the CPM clock frequency
  137  * @accel_dev: Pointer to acceleration device.
  138  * @frequency: Pointer to returned frequency in Hz.
  139  * @min: Minimum expected frequency
  140  * @max: Maximum expected frequency
  141  *
  142  * Return: 0 on success, error code otherwise.
  143  */
  144 int
  145 adf_dev_measure_clock(struct adf_accel_dev *accel_dev,
  146                       u32 *frequency,
  147                       u32 min,
  148                       u32 max)
  149 {
  150         int ret;
  151         u32 freq;
  152 
  153         ret = measure_clock(accel_dev, &freq);
  154         if (ret)
  155                 return ret;
  156 
  157         if (freq < min) {
  158                 device_printf(GET_DEV(accel_dev),
  159                               "Slow clock %d MHz measured, assuming %d\n",
  160                               freq,
  161                               min);
  162                 freq = min;
  163         } else if (freq > max) {
  164                 device_printf(GET_DEV(accel_dev),
  165                               "Fast clock %d MHz measured, assuming %d\n",
  166                               freq,
  167                               max);
  168                 freq = max;
  169         }
  170         *frequency = freq;
  171         return 0;
  172 }
  173 
  174 static inline u64
  175 timespec_to_ms(const struct timespec *ts)
  176 {
  177         return (uint64_t)(ts->tv_sec * (1000)) + (ts->tv_nsec / NSEC_PER_MSEC);
  178 }
  179 
  180 u64
  181 adf_clock_get_current_time(void)
  182 {
  183         struct timespec ts;
  184 
  185         getnanotime(&ts);
  186         return timespec_to_ms(&ts);
  187 }

Cache object: 4dd5c2c5b4620fc8109368e53879472f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.