예제 #1
0
static int kfd_ioctl_get_clock_counters(struct file *filep,
				struct kfd_process *p, void *data)
{
	struct kfd_ioctl_get_clock_counters_args *args = data;
	struct kfd_dev *dev;
	struct timespec64 time;

	dev = kfd_device_by_id(args->gpu_id);
	if (dev == NULL)
		return -EINVAL;

	/* Reading GPU clock counter from KGD */
	args->gpu_clock_counter =
		dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);

	/* No access to rdtsc. Using raw monotonic time */
	getrawmonotonic64(&time);
	args->cpu_clock_counter = (uint64_t)timespec64_to_ns(&time);

	get_monotonic_boottime64(&time);
	args->system_clock_counter = (uint64_t)timespec64_to_ns(&time);

	/* Since the counter is in nano-seconds we use 1GHz frequency */
	args->system_clock_freq = 1000000000;

	return 0;
}
예제 #2
0
unsigned long long dm_get_timestamp(struct dc_context *ctx)
{
	struct timespec64 time;

	getrawmonotonic64(&time);
	return timespec64_to_ns(&time);
}
예제 #3
0
/**
 * fec_ptp_settime
 * @ptp: the ptp clock structure
 * @ts: the timespec containing the new time for the cycle counter
 *
 * reset the timecounter to use a new base value instead of the kernel
 * wall timer value.
 */
static int fec_ptp_settime(struct ptp_clock_info *ptp,
			   const struct timespec64 *ts)
{
	struct fec_enet_private *fep =
	    container_of(ptp, struct fec_enet_private, ptp_caps);

	u64 ns;
	unsigned long flags;
	u32 counter;

	mutex_lock(&fep->ptp_clk_mutex);
	/* Check the ptp clock */
	if (!fep->ptp_clk_on) {
		mutex_unlock(&fep->ptp_clk_mutex);
		return -EINVAL;
	}

	ns = timespec64_to_ns(ts);
	/* Get the timer value based on timestamp.
	 * Update the counter with the masked value.
	 */
	counter = ns & fep->cc.mask;

	spin_lock_irqsave(&fep->tmreg_lock, flags);
	writel(counter, fep->hwp + FEC_ATIME);
	timecounter_init(&fep->tc, &fep->cc, ns);
	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
	mutex_unlock(&fep->ptp_clk_mutex);
	return 0;
}
예제 #4
0
파일: i40e_ptp.c 프로젝트: Lyude/linux
/**
 * i40e_ptp_write - Write the PHC time to the device
 * @pf: Board private structure
 * @ts: timespec structure that holds the new time value
 *
 * This function writes the PRTTSYN_TIME registers with the user value. Since
 * we receive a timespec from the stack, we must convert that timespec into
 * nanoseconds before programming the registers.
 **/
static void i40e_ptp_write(struct i40e_pf *pf, const struct timespec64 *ts)
{
	struct i40e_hw *hw = &pf->hw;
	u64 ns = timespec64_to_ns(ts);

	/* The timer will not update until the high register is written, so
	 * write the low register first.
	 */
	wr32(hw, I40E_PRTTSYN_TIME_L, ns & 0xFFFFFFFF);
	wr32(hw, I40E_PRTTSYN_TIME_H, ns >> 32);
}
예제 #5
0
static int mlx5e_ptp_settime(struct ptp_clock_info *ptp,
			     const struct timespec64 *ts)
{
	struct mlx5e_tstamp *tstamp = container_of(ptp, struct mlx5e_tstamp,
						   ptp_info);
	u64 ns = timespec64_to_ns(ts);
	unsigned long flags;

	write_lock_irqsave(&tstamp->lock, flags);
	timecounter_init(&tstamp->clock, &tstamp->cycles, ns);
	write_unlock_irqrestore(&tstamp->lock, flags);

	return 0;
}
예제 #6
0
파일: en_clock.c 프로젝트: 19Dan01/linux
/**
 * mlx4_en_phc_settime - Set the current time on the hardware clock
 * @ptp: ptp clock structure
 * @ts: timespec containing the new time for the cycle counter
 *
 * Reset the timecounter to use a new base value instead of the kernel
 * wall timer value.
 **/
static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
			       const struct timespec64 *ts)
{
	struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
						ptp_clock_info);
	u64 ns = timespec64_to_ns(ts);
	unsigned long flags;

	/* reset the timecounter */
	write_lock_irqsave(&mdev->clock_lock, flags);
	timecounter_init(&mdev->clock, &mdev->cycles, ns);
	write_unlock_irqrestore(&mdev->clock_lock, flags);

	return 0;
}
예제 #7
0
/**
 * e1000e_phc_settime - Set the current time on the hardware clock
 * @ptp: ptp clock structure
 * @ts: timespec containing the new time for the cycle counter
 *
 * Reset the timecounter to use a new base value instead of the kernel
 * wall timer value.
 **/
static int e1000e_phc_settime(struct ptp_clock_info *ptp,
			      const struct timespec64 *ts)
{
	struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
						     ptp_clock_info);
	unsigned long flags;
	u64 ns;

	ns = timespec64_to_ns(ts);

	/* reset the timecounter */
	spin_lock_irqsave(&adapter->systim_lock, flags);
	timecounter_init(&adapter->tc, &adapter->cc, ns);
	spin_unlock_irqrestore(&adapter->systim_lock, flags);

	return 0;
}
예제 #8
0
파일: igb_ptp.c 프로젝트: AK101111/linux
static int igb_ptp_settime_82576(struct ptp_clock_info *ptp,
				 const struct timespec64 *ts)
{
	struct igb_adapter *igb = container_of(ptp, struct igb_adapter,
					       ptp_caps);
	unsigned long flags;
	u64 ns;

	ns = timespec64_to_ns(ts);

	spin_lock_irqsave(&igb->tmreg_lock, flags);

	timecounter_init(&igb->tc, &igb->cc, ns);

	spin_unlock_irqrestore(&igb->tmreg_lock, flags);

	return 0;
}
예제 #9
0
파일: bfin_mac.c 프로젝트: 513855417/linux
static int bfin_ptp_settime(struct ptp_clock_info *ptp,
			   const struct timespec64 *ts)
{
	u64 ns;
	unsigned long flags;
	struct bfin_mac_local *lp =
		container_of(ptp, struct bfin_mac_local, caps);

	ns = timespec64_to_ns(ts);

	spin_lock_irqsave(&lp->phc_lock, flags);

	bfin_ptp_time_write(lp, ns);

	spin_unlock_irqrestore(&lp->phc_lock, flags);

	return 0;
}
예제 #10
0
static int ptp_ixp_settime(struct ptp_clock_info *ptp,
			   const struct timespec64 *ts)
{
	u64 ns;
	unsigned long flags;
	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
	struct ixp46x_ts_regs *regs = ixp_clock->regs;

	ns = timespec64_to_ns(ts);

	spin_lock_irqsave(&register_lock, flags);

	ixp_systime_write(regs, ns);

	spin_unlock_irqrestore(&register_lock, flags);

	return 0;
}
예제 #11
0
파일: igb_ptp.c 프로젝트: AK101111/linux
static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,
				       struct ptp_clock_request *rq, int on)
{
	struct igb_adapter *igb =
		container_of(ptp, struct igb_adapter, ptp_caps);
	struct e1000_hw *hw = &igb->hw;
	u32 tsauxc, tsim, tsauxc_mask, tsim_mask, trgttiml, trgttimh, freqout;
	unsigned long flags;
	struct timespec64 ts;
	int use_freq = 0, pin = -1;
	s64 ns;

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		if (on) {
			pin = ptp_find_pin(igb->ptp_clock, PTP_PF_EXTTS,
					   rq->extts.index);
			if (pin < 0)
				return -EBUSY;
		}
		if (rq->extts.index == 1) {
			tsauxc_mask = TSAUXC_EN_TS1;
			tsim_mask = TSINTR_AUTT1;
		} else {
			tsauxc_mask = TSAUXC_EN_TS0;
			tsim_mask = TSINTR_AUTT0;
		}
		spin_lock_irqsave(&igb->tmreg_lock, flags);
		tsauxc = rd32(E1000_TSAUXC);
		tsim = rd32(E1000_TSIM);
		if (on) {
			igb_pin_extts(igb, rq->extts.index, pin);
			tsauxc |= tsauxc_mask;
			tsim |= tsim_mask;
		} else {
			tsauxc &= ~tsauxc_mask;
			tsim &= ~tsim_mask;
		}
		wr32(E1000_TSAUXC, tsauxc);
		wr32(E1000_TSIM, tsim);
		spin_unlock_irqrestore(&igb->tmreg_lock, flags);
		return 0;

	case PTP_CLK_REQ_PEROUT:
		if (on) {
			pin = ptp_find_pin(igb->ptp_clock, PTP_PF_PEROUT,
					   rq->perout.index);
			if (pin < 0)
				return -EBUSY;
		}
		ts.tv_sec = rq->perout.period.sec;
		ts.tv_nsec = rq->perout.period.nsec;
		ns = timespec64_to_ns(&ts);
		ns = ns >> 1;
		if (on && ((ns <= 70000000LL) || (ns == 125000000LL) ||
			   (ns == 250000000LL) || (ns == 500000000LL))) {
			if (ns < 8LL)
				return -EINVAL;
			use_freq = 1;
		}
		ts = ns_to_timespec64(ns);
		if (rq->perout.index == 1) {
			if (use_freq) {
				tsauxc_mask = TSAUXC_EN_CLK1 | TSAUXC_ST1;
				tsim_mask = 0;
			} else {
				tsauxc_mask = TSAUXC_EN_TT1;
				tsim_mask = TSINTR_TT1;
			}
			trgttiml = E1000_TRGTTIML1;
			trgttimh = E1000_TRGTTIMH1;
			freqout = E1000_FREQOUT1;
		} else {
			if (use_freq) {
				tsauxc_mask = TSAUXC_EN_CLK0 | TSAUXC_ST0;
				tsim_mask = 0;
			} else {
				tsauxc_mask = TSAUXC_EN_TT0;
				tsim_mask = TSINTR_TT0;
			}
			trgttiml = E1000_TRGTTIML0;
			trgttimh = E1000_TRGTTIMH0;
			freqout = E1000_FREQOUT0;
		}
		spin_lock_irqsave(&igb->tmreg_lock, flags);
		tsauxc = rd32(E1000_TSAUXC);
		tsim = rd32(E1000_TSIM);
		if (rq->perout.index == 1) {
			tsauxc &= ~(TSAUXC_EN_TT1 | TSAUXC_EN_CLK1 | TSAUXC_ST1);
			tsim &= ~TSINTR_TT1;
		} else {
			tsauxc &= ~(TSAUXC_EN_TT0 | TSAUXC_EN_CLK0 | TSAUXC_ST0);
			tsim &= ~TSINTR_TT0;
		}
		if (on) {
			int i = rq->perout.index;
			igb_pin_perout(igb, i, pin, use_freq);
			igb->perout[i].start.tv_sec = rq->perout.start.sec;
			igb->perout[i].start.tv_nsec = rq->perout.start.nsec;
			igb->perout[i].period.tv_sec = ts.tv_sec;
			igb->perout[i].period.tv_nsec = ts.tv_nsec;
			wr32(trgttimh, rq->perout.start.sec);
			wr32(trgttiml, rq->perout.start.nsec);
			if (use_freq)
				wr32(freqout, ns);
			tsauxc |= tsauxc_mask;
			tsim |= tsim_mask;
		}
		wr32(E1000_TSAUXC, tsauxc);
		wr32(E1000_TSIM, tsim);
		spin_unlock_irqrestore(&igb->tmreg_lock, flags);
		return 0;

	case PTP_CLK_REQ_PPS:
		spin_lock_irqsave(&igb->tmreg_lock, flags);
		tsim = rd32(E1000_TSIM);
		if (on)
			tsim |= TSINTR_SYS_WRAP;
		else
			tsim &= ~TSINTR_SYS_WRAP;
		wr32(E1000_TSIM, tsim);
		spin_unlock_irqrestore(&igb->tmreg_lock, flags);
		return 0;
	}

	return -EOPNOTSUPP;
}
예제 #12
0
 * Reset the timecounter to use a new base value instead of the kernel
 * wall timer value.
 **/
static int mlx4_en_phc_settime(struct ptp_clock_info *ptp,
#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
			       const struct timespec *ts)
#else
			       const struct timespec64 *ts)
#endif
{
	struct mlx4_en_dev *mdev = container_of(ptp, struct mlx4_en_dev,
						ptp_clock_info);
#ifdef HAVE_PTP_CLOCK_INFO_GETTIME_32BIT
	u64 ns = timespec_to_ns(ts);
#else
	u64 ns = timespec64_to_ns(ts);
#endif
	unsigned long flags;

	/* reset the timecounter */
	write_lock_irqsave(&mdev->clock_lock, flags);
	timecounter_init(&mdev->clock, &mdev->cycles, ns);
	write_unlock_irqrestore(&mdev->clock_lock, flags);

	return 0;
}

/**
 * mlx4_en_phc_enable - enable or disable an ancillary feature
 * @ptp: ptp clock structure
 * @request: Desired resource to enable or disable