Commit 8373cd38 authored by Yufeng Mo's avatar Yufeng Mo Committed by David S. Miller
Browse files

net: hns3: change the method of obtaining default ptp cycle



The ptp cycle is related to the hardware, so it may cause compatibility
issues if a fixed value is used in driver. Therefore, the method of
obtaining this value is changed to read from the register rather than
use a fixed value in driver.

Fixes: 0bf5eb78 ("net: hns3: add support for PTP")
Signed-off-by: default avatarYufeng Mo <moyufeng@huawei.com>
Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 801e541c
Loading
Loading
Loading
Loading
+29 −7
Original line number Diff line number Diff line
@@ -5,9 +5,27 @@
#include "hclge_main.h"
#include "hnae3.h"

static int hclge_ptp_get_cycle(struct hclge_dev *hdev)
{
	struct hclge_ptp *ptp = hdev->ptp;

	ptp->cycle.quo = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG) &
			 HCLGE_PTP_CYCLE_QUO_MASK;
	ptp->cycle.numer = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
	ptp->cycle.den = readl(hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);

	if (ptp->cycle.den == 0) {
		dev_err(&hdev->pdev->dev, "invalid ptp cycle denominator!\n");
		return -EINVAL;
	}

	return 0;
}

static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
{
	struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
	struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle;
	u64 adj_val, adj_base, diff;
	unsigned long flags;
	bool is_neg = false;
@@ -18,7 +36,7 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
		is_neg = true;
	}

	adj_base = HCLGE_PTP_CYCLE_ADJ_BASE * HCLGE_PTP_CYCLE_ADJ_UNIT;
	adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer;
	adj_val = adj_base * ppb;
	diff = div_u64(adj_val, 1000000000ULL);

@@ -29,16 +47,16 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)

	/* This clock cycle is defined by three part: quotient, numerator
	 * and denominator. For example, 2.5ns, the quotient is 2,
	 * denominator is fixed to HCLGE_PTP_CYCLE_ADJ_UNIT, and numerator
	 * is 0.5 * HCLGE_PTP_CYCLE_ADJ_UNIT.
	 * denominator is fixed to ptp->cycle.den, and numerator
	 * is 0.5 * ptp->cycle.den.
	 */
	quo = div_u64_rem(adj_val, HCLGE_PTP_CYCLE_ADJ_UNIT, &numerator);
	quo = div_u64_rem(adj_val, cycle->den, &numerator);

	spin_lock_irqsave(&hdev->ptp->lock, flags);
	writel(quo, hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG);
	writel(quo & HCLGE_PTP_CYCLE_QUO_MASK,
	       hdev->ptp->io_base + HCLGE_PTP_CYCLE_QUO_REG);
	writel(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
	writel(HCLGE_PTP_CYCLE_ADJ_UNIT,
	       hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
	writel(cycle->den, hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
	writel(HCLGE_PTP_CYCLE_ADJ_EN,
	       hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG);
	spin_unlock_irqrestore(&hdev->ptp->lock, flags);
@@ -475,6 +493,10 @@ int hclge_ptp_init(struct hclge_dev *hdev)
		ret = hclge_ptp_create_clock(hdev);
		if (ret)
			return ret;

		ret = hclge_ptp_get_cycle(hdev);
		if (ret)
			return ret;
	}

	ret = hclge_ptp_int_en(hdev, true);
+8 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#define HCLGE_PTP_TIME_ADJ_REG		0x60
#define HCLGE_PTP_TIME_ADJ_EN		BIT(0)
#define HCLGE_PTP_CYCLE_QUO_REG		0x64
#define HCLGE_PTP_CYCLE_QUO_MASK	GENMASK(7, 0)
#define HCLGE_PTP_CYCLE_DEN_REG		0x68
#define HCLGE_PTP_CYCLE_NUM_REG		0x6C
#define HCLGE_PTP_CYCLE_CFG_REG		0x70
@@ -37,9 +38,7 @@
#define HCLGE_PTP_CUR_TIME_SEC_L_REG	0x78
#define HCLGE_PTP_CUR_TIME_NSEC_REG	0x7C

#define HCLGE_PTP_CYCLE_ADJ_BASE	2
#define HCLGE_PTP_CYCLE_ADJ_MAX		500000000
#define HCLGE_PTP_CYCLE_ADJ_UNIT	100000000
#define HCLGE_PTP_SEC_H_OFFSET		32u
#define HCLGE_PTP_SEC_L_MASK		GENMASK(31, 0)

@@ -47,6 +46,12 @@
#define HCLGE_PTP_FLAG_TX_EN		1
#define HCLGE_PTP_FLAG_RX_EN		2

struct hclge_ptp_cycle {
	u32 quo;
	u32 numer;
	u32 den;
};

struct hclge_ptp {
	struct hclge_dev *hdev;
	struct ptp_clock *clock;
@@ -58,6 +63,7 @@ struct hclge_ptp {
	spinlock_t lock;	/* protects ptp registers */
	u32 ptp_cfg;
	u32 last_tx_seqid;
	struct hclge_ptp_cycle cycle;
	unsigned long tx_start;
	unsigned long tx_cnt;
	unsigned long tx_skipped;