mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-22 00:40:03 +00:00
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: 0bf5eb7885
("net: hns3: add support for PTP")
Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
801e541c79
commit
8373cd38a8
2 changed files with 37 additions and 9 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue