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

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
...@@ -5,9 +5,27 @@ ...@@ -5,9 +5,27 @@
#include "hclge_main.h" #include "hclge_main.h"
#include "hnae3.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) static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
{ {
struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp); struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle;
u64 adj_val, adj_base, diff; u64 adj_val, adj_base, diff;
unsigned long flags; unsigned long flags;
bool is_neg = false; bool is_neg = false;
...@@ -18,7 +36,7 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) ...@@ -18,7 +36,7 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
is_neg = true; 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; adj_val = adj_base * ppb;
diff = div_u64(adj_val, 1000000000ULL); diff = div_u64(adj_val, 1000000000ULL);
...@@ -29,16 +47,16 @@ static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) ...@@ -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 /* This clock cycle is defined by three part: quotient, numerator
* and denominator. For example, 2.5ns, the quotient is 2, * and denominator. For example, 2.5ns, the quotient is 2,
* denominator is fixed to HCLGE_PTP_CYCLE_ADJ_UNIT, and numerator * denominator is fixed to ptp->cycle.den, and numerator
* is 0.5 * HCLGE_PTP_CYCLE_ADJ_UNIT. * 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); 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(numerator, hdev->ptp->io_base + HCLGE_PTP_CYCLE_NUM_REG);
writel(HCLGE_PTP_CYCLE_ADJ_UNIT, writel(cycle->den, hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
hdev->ptp->io_base + HCLGE_PTP_CYCLE_DEN_REG);
writel(HCLGE_PTP_CYCLE_ADJ_EN, writel(HCLGE_PTP_CYCLE_ADJ_EN,
hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG); hdev->ptp->io_base + HCLGE_PTP_CYCLE_CFG_REG);
spin_unlock_irqrestore(&hdev->ptp->lock, flags); spin_unlock_irqrestore(&hdev->ptp->lock, flags);
...@@ -475,6 +493,10 @@ int hclge_ptp_init(struct hclge_dev *hdev) ...@@ -475,6 +493,10 @@ int hclge_ptp_init(struct hclge_dev *hdev)
ret = hclge_ptp_create_clock(hdev); ret = hclge_ptp_create_clock(hdev);
if (ret) if (ret)
return ret; return ret;
ret = hclge_ptp_get_cycle(hdev);
if (ret)
return ret;
} }
ret = hclge_ptp_int_en(hdev, true); ret = hclge_ptp_int_en(hdev, true);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define HCLGE_PTP_TIME_ADJ_REG 0x60 #define HCLGE_PTP_TIME_ADJ_REG 0x60
#define HCLGE_PTP_TIME_ADJ_EN BIT(0) #define HCLGE_PTP_TIME_ADJ_EN BIT(0)
#define HCLGE_PTP_CYCLE_QUO_REG 0x64 #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_DEN_REG 0x68
#define HCLGE_PTP_CYCLE_NUM_REG 0x6C #define HCLGE_PTP_CYCLE_NUM_REG 0x6C
#define HCLGE_PTP_CYCLE_CFG_REG 0x70 #define HCLGE_PTP_CYCLE_CFG_REG 0x70
...@@ -37,9 +38,7 @@ ...@@ -37,9 +38,7 @@
#define HCLGE_PTP_CUR_TIME_SEC_L_REG 0x78 #define HCLGE_PTP_CUR_TIME_SEC_L_REG 0x78
#define HCLGE_PTP_CUR_TIME_NSEC_REG 0x7C #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_MAX 500000000
#define HCLGE_PTP_CYCLE_ADJ_UNIT 100000000
#define HCLGE_PTP_SEC_H_OFFSET 32u #define HCLGE_PTP_SEC_H_OFFSET 32u
#define HCLGE_PTP_SEC_L_MASK GENMASK(31, 0) #define HCLGE_PTP_SEC_L_MASK GENMASK(31, 0)
...@@ -47,6 +46,12 @@ ...@@ -47,6 +46,12 @@
#define HCLGE_PTP_FLAG_TX_EN 1 #define HCLGE_PTP_FLAG_TX_EN 1
#define HCLGE_PTP_FLAG_RX_EN 2 #define HCLGE_PTP_FLAG_RX_EN 2
struct hclge_ptp_cycle {
u32 quo;
u32 numer;
u32 den;
};
struct hclge_ptp { struct hclge_ptp {
struct hclge_dev *hdev; struct hclge_dev *hdev;
struct ptp_clock *clock; struct ptp_clock *clock;
...@@ -58,6 +63,7 @@ struct hclge_ptp { ...@@ -58,6 +63,7 @@ struct hclge_ptp {
spinlock_t lock; /* protects ptp registers */ spinlock_t lock; /* protects ptp registers */
u32 ptp_cfg; u32 ptp_cfg;
u32 last_tx_seqid; u32 last_tx_seqid;
struct hclge_ptp_cycle cycle;
unsigned long tx_start; unsigned long tx_start;
unsigned long tx_cnt; unsigned long tx_cnt;
unsigned long tx_skipped; unsigned long tx_skipped;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment