Merge branch 'ptp-adjfreq-copnvert'
Jacob Keller says: ==================== ptp: convert remaining users of .adjfreq A handful of drivers remain which still use the .adjfreq interface instead of the newer .adjfine interface. The new interface is preferred as it has a more precise adjustment using scaled parts per million. A handful of the remaining drivers are implemented with a common pattern that can be refactored to use the adjust_by_scaled_ppm and diff_by_scaled_ppm helper functions. These include the ptp_phc, ptp_ixp64x, tg3, hclge, stmac, cpts and bnxt drivers. These are each refactored in a separate change. The remaining drivers, bnx2x, liquidio, cxgb4, fec, and qede implement .adjfreq in a way different from the normal pattern expected by adjust_by_scaled_ppm. Fixing these drivers to properly use .adjfine requires specific knowledge of the hardware implementation. Instead I simply refactor them to use .adjfine and convert scaled_ppm into ppb using the scaled_ppm_to_ppb function. Finally, the .adjfreq implementation interface is removed entirely. This simplifies the interface and ensures that new drivers must implement the new interface as they no longer have an alternative. This still leaves parts per billion used as part of the max_adj interface, and the core PTP stack still converts scaled_ppm to ppb to check this. I plan to investigate fixing this in the future. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
2cf7e87fc4
|
@ -13671,19 +13671,20 @@ static int bnx2x_send_update_drift_ramrod(struct bnx2x *bp, int drift_dir,
|
|||
return bnx2x_func_state_change(bp, &func_params);
|
||||
}
|
||||
|
||||
static int bnx2x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int bnx2x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
|
||||
int rc;
|
||||
int drift_dir = 1;
|
||||
int val, period, period1, period2, dif, dif1, dif2;
|
||||
int best_dif = BNX2X_MAX_PHC_DRIFT, best_period = 0, best_val = 0;
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
|
||||
DP(BNX2X_MSG_PTP, "PTP adjfreq called, ppb = %d\n", ppb);
|
||||
DP(BNX2X_MSG_PTP, "PTP adjfine called, ppb = %d\n", ppb);
|
||||
|
||||
if (!netif_running(bp->dev)) {
|
||||
DP(BNX2X_MSG_PTP,
|
||||
"PTP adjfreq called while the interface is down\n");
|
||||
"PTP adjfine called while the interface is down\n");
|
||||
return -ENETDOWN;
|
||||
}
|
||||
|
||||
|
@ -13818,7 +13819,7 @@ void bnx2x_register_phc(struct bnx2x *bp)
|
|||
bp->ptp_clock_info.n_ext_ts = 0;
|
||||
bp->ptp_clock_info.n_per_out = 0;
|
||||
bp->ptp_clock_info.pps = 0;
|
||||
bp->ptp_clock_info.adjfreq = bnx2x_ptp_adjfreq;
|
||||
bp->ptp_clock_info.adjfine = bnx2x_ptp_adjfine;
|
||||
bp->ptp_clock_info.adjtime = bnx2x_ptp_adjtime;
|
||||
bp->ptp_clock_info.gettime64 = bnx2x_ptp_gettime;
|
||||
bp->ptp_clock_info.settime64 = bnx2x_ptp_settime;
|
||||
|
|
|
@ -205,7 +205,7 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
|
||||
static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
|
||||
{
|
||||
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
|
||||
ptp_info);
|
||||
|
@ -214,23 +214,13 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
|
|||
int rc = 0;
|
||||
|
||||
if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
|
||||
int neg_adj = 0;
|
||||
u32 diff;
|
||||
u64 adj;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = 1;
|
||||
ppb = -ppb;
|
||||
}
|
||||
adj = ptp->cmult;
|
||||
adj *= ppb;
|
||||
diff = div_u64(adj, 1000000000ULL);
|
||||
|
||||
spin_lock_bh(&ptp->ptp_lock);
|
||||
timecounter_read(&ptp->tc);
|
||||
ptp->cc.mult = neg_adj ? ptp->cmult - diff : ptp->cmult + diff;
|
||||
ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
|
||||
spin_unlock_bh(&ptp->ptp_lock);
|
||||
} else {
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
|
||||
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
@ -240,7 +230,7 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
|
|||
rc = hwrm_req_send(ptp->bp, req);
|
||||
if (rc)
|
||||
netdev_err(ptp->bp->dev,
|
||||
"ptp adjfreq failed. rc = %d\n", rc);
|
||||
"ptp adjfine failed. rc = %d\n", rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -769,7 +759,7 @@ static const struct ptp_clock_info bnxt_ptp_caps = {
|
|||
.n_per_out = 0,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = bnxt_ptp_adjfreq,
|
||||
.adjfine = bnxt_ptp_adjfine,
|
||||
.adjtime = bnxt_ptp_adjtime,
|
||||
.do_aux_work = bnxt_ptp_ts_aux_work,
|
||||
.gettimex64 = bnxt_ptp_gettimex,
|
||||
|
|
|
@ -6179,34 +6179,26 @@ static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int tg3_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
|
||||
bool neg_adj = false;
|
||||
u32 correction = 0;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = true;
|
||||
ppb = -ppb;
|
||||
}
|
||||
u64 correction;
|
||||
bool neg_adj;
|
||||
|
||||
/* Frequency adjustment is performed using hardware with a 24 bit
|
||||
* accumulator and a programmable correction value. On each clk, the
|
||||
* correction value gets added to the accumulator and when it
|
||||
* overflows, the time counter is incremented/decremented.
|
||||
*
|
||||
* So conversion from ppb to correction value is
|
||||
* ppb * (1 << 24) / 1000000000
|
||||
*/
|
||||
correction = div_u64((u64)ppb * (1 << 24), 1000000000ULL) &
|
||||
TG3_EAV_REF_CLK_CORRECT_MASK;
|
||||
neg_adj = diff_by_scaled_ppm(1 << 24, scaled_ppm, &correction);
|
||||
|
||||
tg3_full_lock(tp, 0);
|
||||
|
||||
if (correction)
|
||||
tw32(TG3_EAV_REF_CLK_CORRECT_CTL,
|
||||
TG3_EAV_REF_CLK_CORRECT_EN |
|
||||
(neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) | correction);
|
||||
(neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) |
|
||||
((u32)correction & TG3_EAV_REF_CLK_CORRECT_MASK));
|
||||
else
|
||||
tw32(TG3_EAV_REF_CLK_CORRECT_CTL, 0);
|
||||
|
||||
|
@ -6330,7 +6322,7 @@ static const struct ptp_clock_info tg3_ptp_caps = {
|
|||
.n_per_out = 1,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = tg3_ptp_adjfreq,
|
||||
.adjfine = tg3_ptp_adjfine,
|
||||
.adjtime = tg3_ptp_adjtime,
|
||||
.gettimex64 = tg3_ptp_gettimex,
|
||||
.settime64 = tg3_ptp_settime,
|
||||
|
|
|
@ -1512,14 +1512,17 @@ static void free_netsgbuf_with_resp(void *buf)
|
|||
}
|
||||
|
||||
/**
|
||||
* liquidio_ptp_adjfreq - Adjust ptp frequency
|
||||
* liquidio_ptp_adjfine - Adjust ptp frequency
|
||||
* @ptp: PTP clock info
|
||||
* @ppb: how much to adjust by, in parts-per-billion
|
||||
* @scaled_ppm: how much to adjust by, in scaled parts-per-million
|
||||
*
|
||||
* Scaled parts per million is ppm with a 16-bit binary fractional field.
|
||||
*/
|
||||
static int liquidio_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int liquidio_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct lio *lio = container_of(ptp, struct lio, ptp_info);
|
||||
struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
u64 comp, delta;
|
||||
unsigned long flags;
|
||||
bool neg_adj = false;
|
||||
|
@ -1643,7 +1646,7 @@ static void oct_ptp_open(struct net_device *netdev)
|
|||
lio->ptp_info.n_ext_ts = 0;
|
||||
lio->ptp_info.n_per_out = 0;
|
||||
lio->ptp_info.pps = 0;
|
||||
lio->ptp_info.adjfreq = liquidio_ptp_adjfreq;
|
||||
lio->ptp_info.adjfine = liquidio_ptp_adjfine;
|
||||
lio->ptp_info.adjtime = liquidio_ptp_adjtime;
|
||||
lio->ptp_info.gettime64 = liquidio_ptp_gettime;
|
||||
lio->ptp_info.settime64 = liquidio_ptp_settime;
|
||||
|
|
|
@ -194,17 +194,20 @@ int cxgb4_ptp_redirect_rx_packet(struct adapter *adapter, struct port_info *pi)
|
|||
}
|
||||
|
||||
/**
|
||||
* cxgb4_ptp_adjfreq - Adjust frequency of PHC cycle counter
|
||||
* cxgb4_ptp_adjfine - Adjust frequency of PHC cycle counter
|
||||
* @ptp: ptp clock structure
|
||||
* @ppb: Desired frequency change in parts per billion
|
||||
* @scaled_ppm: Desired frequency in scaled parts per billion
|
||||
*
|
||||
* Adjust the frequency of the PHC cycle counter by the indicated ppb from
|
||||
* Adjust the frequency of the PHC cycle counter by the indicated amount from
|
||||
* the base frequency.
|
||||
*
|
||||
* Scaled parts per million is ppm with a 16-bit binary fractional field.
|
||||
*/
|
||||
static int cxgb4_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int cxgb4_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct adapter *adapter = (struct adapter *)container_of(ptp,
|
||||
struct adapter, ptp_clock_info);
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
struct fw_ptp_cmd c;
|
||||
int err;
|
||||
|
||||
|
@ -404,7 +407,7 @@ static const struct ptp_clock_info cxgb4_ptp_clock_info = {
|
|||
.n_ext_ts = 0,
|
||||
.n_per_out = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = cxgb4_ptp_adjfreq,
|
||||
.adjfine = cxgb4_ptp_adjfine,
|
||||
.adjtime = cxgb4_ptp_adjtime,
|
||||
.gettime64 = cxgb4_ptp_gettime,
|
||||
.settime64 = cxgb4_ptp_settime,
|
||||
|
|
|
@ -338,18 +338,21 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
|
|||
}
|
||||
|
||||
/**
|
||||
* fec_ptp_adjfreq - adjust ptp cycle frequency
|
||||
* fec_ptp_adjfine - adjust ptp cycle frequency
|
||||
* @ptp: the ptp clock structure
|
||||
* @ppb: parts per billion adjustment from base
|
||||
* @scaled_ppm: scaled parts per million adjustment from base
|
||||
*
|
||||
* Adjust the frequency of the ptp cycle counter by the
|
||||
* indicated ppb from the base frequency.
|
||||
* indicated amount from the base frequency.
|
||||
*
|
||||
* Scaled parts per million is ppm with a 16-bit binary fractional field.
|
||||
*
|
||||
* Because ENET hardware frequency adjust is complex,
|
||||
* using software method to do that.
|
||||
*/
|
||||
static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int fec_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
unsigned long flags;
|
||||
int neg_adj = 0;
|
||||
u32 i, tmp;
|
||||
|
@ -742,7 +745,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
|
|||
fep->ptp_caps.n_per_out = 1;
|
||||
fep->ptp_caps.n_pins = 0;
|
||||
fep->ptp_caps.pps = 1;
|
||||
fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
|
||||
fep->ptp_caps.adjfine = fec_ptp_adjfine;
|
||||
fep->ptp_caps.adjtime = fec_ptp_adjtime;
|
||||
fep->ptp_caps.gettime64 = fec_ptp_gettime;
|
||||
fep->ptp_caps.settime64 = fec_ptp_settime;
|
||||
|
|
|
@ -22,28 +22,16 @@ static int hclge_ptp_get_cycle(struct hclge_dev *hdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int hclge_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
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;
|
||||
unsigned long flags;
|
||||
bool is_neg = false;
|
||||
u32 quo, numerator;
|
||||
|
||||
if (ppb < 0) {
|
||||
ppb = -ppb;
|
||||
is_neg = true;
|
||||
}
|
||||
|
||||
adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer;
|
||||
adj_val = adj_base * ppb;
|
||||
diff = div_u64(adj_val, 1000000000ULL);
|
||||
|
||||
if (is_neg)
|
||||
adj_val = adj_base - diff;
|
||||
else
|
||||
adj_val = adj_base + diff;
|
||||
adj_val = adjust_by_scaled_ppm(adj_base, scaled_ppm);
|
||||
|
||||
/* This clock cycle is defined by three part: quotient, numerator
|
||||
* and denominator. For example, 2.5ns, the quotient is 2,
|
||||
|
@ -446,7 +434,7 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
|
|||
ptp->info.max_adj = HCLGE_PTP_CYCLE_ADJ_MAX;
|
||||
ptp->info.n_ext_ts = 0;
|
||||
ptp->info.pps = 0;
|
||||
ptp->info.adjfreq = hclge_ptp_adjfreq;
|
||||
ptp->info.adjfine = hclge_ptp_adjfine;
|
||||
ptp->info.adjtime = hclge_ptp_adjtime;
|
||||
ptp->info.gettimex64 = hclge_ptp_gettimex;
|
||||
ptp->info.settime64 = hclge_ptp_settime;
|
||||
|
@ -504,7 +492,7 @@ int hclge_ptp_init(struct hclge_dev *hdev)
|
|||
goto out;
|
||||
|
||||
set_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags);
|
||||
ret = hclge_ptp_adjfreq(&hdev->ptp->info, 0);
|
||||
ret = hclge_ptp_adjfine(&hdev->ptp->info, 0);
|
||||
if (ret) {
|
||||
dev_err(&hdev->pdev->dev,
|
||||
"failed to init freq, ret = %d\n", ret);
|
||||
|
|
|
@ -28,16 +28,19 @@ struct qede_ptp {
|
|||
};
|
||||
|
||||
/**
|
||||
* qede_ptp_adjfreq() - Adjust the frequency of the PTP cycle counter.
|
||||
* qede_ptp_adjfine() - Adjust the frequency of the PTP cycle counter.
|
||||
*
|
||||
* @info: The PTP clock info structure.
|
||||
* @ppb: Parts per billion adjustment from base.
|
||||
* @scaled_ppm: Scaled parts per million adjustment from base.
|
||||
*
|
||||
* Scaled parts per million is ppm with a 16-bit binary fractional field.
|
||||
*
|
||||
* Return: Zero on success, negative errno otherwise.
|
||||
*/
|
||||
static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
|
||||
static int qede_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
|
||||
{
|
||||
struct qede_ptp *ptp = container_of(info, struct qede_ptp, clock_info);
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
struct qede_dev *edev = ptp->edev;
|
||||
int rc;
|
||||
|
||||
|
@ -47,7 +50,7 @@ static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
|
|||
rc = ptp->ops->adjfreq(edev->cdev, ppb);
|
||||
spin_unlock_bh(&ptp->lock);
|
||||
} else {
|
||||
DP_ERR(edev, "PTP adjfreq called while interface is down\n");
|
||||
DP_ERR(edev, "PTP adjfine called while interface is down\n");
|
||||
rc = -EFAULT;
|
||||
}
|
||||
__qede_unlock(edev);
|
||||
|
@ -462,7 +465,7 @@ int qede_ptp_enable(struct qede_dev *edev)
|
|||
ptp->clock_info.n_ext_ts = 0;
|
||||
ptp->clock_info.n_per_out = 0;
|
||||
ptp->clock_info.pps = 0;
|
||||
ptp->clock_info.adjfreq = qede_ptp_adjfreq;
|
||||
ptp->clock_info.adjfine = qede_ptp_adjfine;
|
||||
ptp->clock_info.adjtime = qede_ptp_adjtime;
|
||||
ptp->clock_info.gettime64 = qede_ptp_gettime;
|
||||
ptp->clock_info.settime64 = qede_ptp_settime;
|
||||
|
|
|
@ -351,7 +351,7 @@ struct efx_ptp_data {
|
|||
void (*xmit_skb)(struct efx_nic *efx, struct sk_buff *skb);
|
||||
};
|
||||
|
||||
static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta);
|
||||
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
|
||||
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta);
|
||||
static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||
static int efx_phc_settime(struct ptp_clock_info *ptp,
|
||||
|
@ -1508,7 +1508,7 @@ static const struct ptp_clock_info efx_phc_clock_info = {
|
|||
.n_per_out = 0,
|
||||
.n_pins = 0,
|
||||
.pps = 1,
|
||||
.adjfreq = efx_phc_adjfreq,
|
||||
.adjfine = efx_phc_adjfine,
|
||||
.adjtime = efx_phc_adjtime,
|
||||
.gettime64 = efx_phc_gettime,
|
||||
.settime64 = efx_phc_settime,
|
||||
|
@ -2137,11 +2137,12 @@ void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
|
|||
ptp->ts_corrections.general_rx);
|
||||
}
|
||||
|
||||
static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
|
||||
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct efx_ptp_data *ptp_data = container_of(ptp,
|
||||
struct efx_ptp_data,
|
||||
phc_clock_info);
|
||||
s32 delta = scaled_ppm_to_ppb(scaled_ppm);
|
||||
struct efx_nic *efx = ptp_data->efx;
|
||||
MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
|
||||
s64 adjustment_ns;
|
||||
|
|
|
@ -347,7 +347,7 @@ struct efx_ptp_data {
|
|||
void (*xmit_skb)(struct efx_nic *efx, struct sk_buff *skb);
|
||||
};
|
||||
|
||||
static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta);
|
||||
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
|
||||
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta);
|
||||
static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||
static int efx_phc_settime(struct ptp_clock_info *ptp,
|
||||
|
@ -1429,7 +1429,7 @@ static const struct ptp_clock_info efx_phc_clock_info = {
|
|||
.n_per_out = 0,
|
||||
.n_pins = 0,
|
||||
.pps = 1,
|
||||
.adjfreq = efx_phc_adjfreq,
|
||||
.adjfine = efx_phc_adjfine,
|
||||
.adjtime = efx_phc_adjtime,
|
||||
.gettime64 = efx_phc_gettime,
|
||||
.settime64 = efx_phc_settime,
|
||||
|
@ -2044,11 +2044,12 @@ void __efx_siena_rx_skb_attach_timestamp(struct efx_channel *channel,
|
|||
ptp->ts_corrections.general_rx);
|
||||
}
|
||||
|
||||
static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
|
||||
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct efx_ptp_data *ptp_data = container_of(ptp,
|
||||
struct efx_ptp_data,
|
||||
phc_clock_info);
|
||||
s32 delta = scaled_ppm_to_ppb(scaled_ppm);
|
||||
struct efx_nic *efx = ptp_data->efx;
|
||||
MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
|
||||
s64 adjustment_ns;
|
||||
|
|
|
@ -15,29 +15,20 @@
|
|||
* stmmac_adjust_freq
|
||||
*
|
||||
* @ptp: pointer to ptp_clock_info structure
|
||||
* @ppb: desired period change in parts ber billion
|
||||
* @scaled_ppm: desired period change in scaled parts per million
|
||||
*
|
||||
* Description: this function will adjust the frequency of hardware clock.
|
||||
*
|
||||
* Scaled parts per million is ppm with a 16-bit binary fractional field.
|
||||
*/
|
||||
static int stmmac_adjust_freq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int stmmac_adjust_freq(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct stmmac_priv *priv =
|
||||
container_of(ptp, struct stmmac_priv, ptp_clock_ops);
|
||||
unsigned long flags;
|
||||
u32 diff, addend;
|
||||
int neg_adj = 0;
|
||||
u64 adj;
|
||||
u32 addend;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = 1;
|
||||
ppb = -ppb;
|
||||
}
|
||||
|
||||
addend = priv->default_addend;
|
||||
adj = addend;
|
||||
adj *= ppb;
|
||||
diff = div_u64(adj, 1000000000ULL);
|
||||
addend = neg_adj ? (addend - diff) : (addend + diff);
|
||||
addend = adjust_by_scaled_ppm(priv->default_addend, scaled_ppm);
|
||||
|
||||
write_lock_irqsave(&priv->ptp_lock, flags);
|
||||
stmmac_config_addend(priv, priv->ptpaddr, addend);
|
||||
|
@ -269,7 +260,7 @@ static struct ptp_clock_info stmmac_ptp_clock_ops = {
|
|||
.n_per_out = 0, /* will be overwritten in stmmac_ptp_register */
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = stmmac_adjust_freq,
|
||||
.adjfine = stmmac_adjust_freq,
|
||||
.adjtime = stmmac_adjust_time,
|
||||
.gettime64 = stmmac_get_time,
|
||||
.settime64 = stmmac_set_time,
|
||||
|
|
|
@ -391,9 +391,10 @@ static irqreturn_t am65_cpts_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
/* PTP clock operations */
|
||||
static int am65_cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
int neg_adj = 0;
|
||||
u64 adj_period;
|
||||
u32 val;
|
||||
|
@ -625,7 +626,7 @@ static long am65_cpts_ts_work(struct ptp_clock_info *ptp);
|
|||
static struct ptp_clock_info am65_ptp_info = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "CTPS timer",
|
||||
.adjfreq = am65_cpts_ptp_adjfreq,
|
||||
.adjfine = am65_cpts_ptp_adjfine,
|
||||
.adjtime = am65_cpts_ptp_adjtime,
|
||||
.gettimex64 = am65_cpts_ptp_gettimex,
|
||||
.settime64 = am65_cpts_ptp_settime,
|
||||
|
|
|
@ -213,25 +213,13 @@ static void cpts_update_cur_time(struct cpts *cpts, int match,
|
|||
|
||||
/* PTP clock operations */
|
||||
|
||||
static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct cpts *cpts = container_of(ptp, struct cpts, info);
|
||||
int neg_adj = 0;
|
||||
u32 diff, mult;
|
||||
u64 adj;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = 1;
|
||||
ppb = -ppb;
|
||||
}
|
||||
mult = cpts->cc_mult;
|
||||
adj = mult;
|
||||
adj *= ppb;
|
||||
diff = div_u64(adj, 1000000000ULL);
|
||||
|
||||
mutex_lock(&cpts->ptp_clk_mutex);
|
||||
|
||||
cpts->mult_new = neg_adj ? mult - diff : mult + diff;
|
||||
cpts->mult_new = adjust_by_scaled_ppm(cpts->cc_mult, scaled_ppm);
|
||||
|
||||
cpts_update_cur_time(cpts, CPTS_EV_PUSH, NULL);
|
||||
|
||||
|
@ -435,7 +423,7 @@ static const struct ptp_clock_info cpts_info = {
|
|||
.n_ext_ts = 0,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = cpts_ptp_adjfreq,
|
||||
.adjfine = cpts_ptp_adjfine,
|
||||
.adjtime = cpts_ptp_adjtime,
|
||||
.gettimex64 = cpts_ptp_gettimeex,
|
||||
.settime64 = cpts_ptp_settime,
|
||||
|
@ -794,7 +782,7 @@ struct cpts *cpts_create(struct device *dev, void __iomem *regs,
|
|||
|
||||
cpts_calc_mult_shift(cpts);
|
||||
/* save cc.mult original value as it can be modified
|
||||
* by cpts_ptp_adjfreq().
|
||||
* by cpts_ptp_adjfine().
|
||||
*/
|
||||
cpts->cc_mult = cpts->cc.mult;
|
||||
|
||||
|
|
|
@ -120,24 +120,13 @@ static irqreturn_t isr(int irq, void *priv)
|
|||
* PTP clock operations
|
||||
*/
|
||||
|
||||
static int ptp_ixp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int ptp_ixp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
u64 adj;
|
||||
u32 diff, addend;
|
||||
int neg_adj = 0;
|
||||
u32 addend;
|
||||
struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
|
||||
struct ixp46x_ts_regs *regs = ixp_clock->regs;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = 1;
|
||||
ppb = -ppb;
|
||||
}
|
||||
addend = DEFAULT_ADDEND;
|
||||
adj = addend;
|
||||
adj *= ppb;
|
||||
diff = div_u64(adj, 1000000000ULL);
|
||||
|
||||
addend = neg_adj ? addend - diff : addend + diff;
|
||||
addend = adjust_by_scaled_ppm(DEFAULT_ADDEND, scaled_ppm);
|
||||
|
||||
__raw_writel(addend, ®s->addend);
|
||||
|
||||
|
@ -230,7 +219,7 @@ static const struct ptp_clock_info ptp_ixp_caps = {
|
|||
.n_ext_ts = N_EXT_TS,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = ptp_ixp_adjfreq,
|
||||
.adjfine = ptp_ixp_adjfine,
|
||||
.adjtime = ptp_ixp_adjtime,
|
||||
.gettime64 = ptp_ixp_gettime,
|
||||
.settime64 = ptp_ixp_settime,
|
||||
|
|
|
@ -131,10 +131,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx)
|
|||
long ppb = scaled_ppm_to_ppb(tx->freq);
|
||||
if (ppb > ops->max_adj || ppb < -ops->max_adj)
|
||||
return -ERANGE;
|
||||
if (ops->adjfine)
|
||||
err = ops->adjfine(ops, tx->freq);
|
||||
else
|
||||
err = ops->adjfreq(ops, ppb);
|
||||
err = ops->adjfine(ops, tx->freq);
|
||||
ptp->dialed_frequency = tx->freq;
|
||||
} else if (tx->modes & ADJ_OFFSET) {
|
||||
if (ops->adjphase) {
|
||||
|
|
|
@ -134,8 +134,9 @@ static s64 dte_read_nco_with_ovf(struct ptp_dte *ptp_dte)
|
|||
return ns;
|
||||
}
|
||||
|
||||
static int ptp_dte_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int ptp_dte_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
|
||||
u32 nco_incr;
|
||||
unsigned long flags;
|
||||
struct ptp_dte *ptp_dte = container_of(ptp, struct ptp_dte, caps);
|
||||
|
@ -219,7 +220,7 @@ static const struct ptp_clock_info ptp_dte_caps = {
|
|||
.n_ext_ts = 0,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = ptp_dte_adjfreq,
|
||||
.adjfine = ptp_dte_adjfine,
|
||||
.adjtime = ptp_dte_adjtime,
|
||||
.gettime64 = ptp_dte_gettime,
|
||||
.settime64 = ptp_dte_settime,
|
||||
|
|
|
@ -336,24 +336,13 @@ static irqreturn_t isr(int irq, void *priv)
|
|||
* PTP clock operations
|
||||
*/
|
||||
|
||||
static int ptp_pch_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
|
||||
static int ptp_pch_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
u64 adj;
|
||||
u32 diff, addend;
|
||||
int neg_adj = 0;
|
||||
u32 addend;
|
||||
struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
|
||||
struct pch_ts_regs __iomem *regs = pch_dev->regs;
|
||||
|
||||
if (ppb < 0) {
|
||||
neg_adj = 1;
|
||||
ppb = -ppb;
|
||||
}
|
||||
addend = DEFAULT_ADDEND;
|
||||
adj = addend;
|
||||
adj *= ppb;
|
||||
diff = div_u64(adj, 1000000000ULL);
|
||||
|
||||
addend = neg_adj ? addend - diff : addend + diff;
|
||||
addend = adjust_by_scaled_ppm(DEFAULT_ADDEND, scaled_ppm);
|
||||
|
||||
iowrite32(addend, ®s->addend);
|
||||
|
||||
|
@ -440,7 +429,7 @@ static const struct ptp_clock_info ptp_pch_caps = {
|
|||
.n_ext_ts = N_EXT_TS,
|
||||
.n_pins = 0,
|
||||
.pps = 0,
|
||||
.adjfreq = ptp_pch_adjfreq,
|
||||
.adjfine = ptp_pch_adjfine,
|
||||
.adjtime = ptp_pch_adjtime,
|
||||
.gettime64 = ptp_pch_gettime,
|
||||
.settime64 = ptp_pch_settime,
|
||||
|
|
|
@ -77,12 +77,6 @@ struct ptp_system_timestamp {
|
|||
* nominal frequency in parts per million, but with a
|
||||
* 16 bit binary fractional field.
|
||||
*
|
||||
* @adjfreq: Adjusts the frequency of the hardware clock.
|
||||
* This method is deprecated. New drivers should implement
|
||||
* the @adjfine method instead.
|
||||
* parameter delta: Desired frequency offset from nominal frequency
|
||||
* in parts per billion
|
||||
*
|
||||
* @adjphase: Adjusts the phase offset of the hardware clock.
|
||||
* parameter delta: Desired change in nanoseconds.
|
||||
*
|
||||
|
@ -174,7 +168,6 @@ struct ptp_clock_info {
|
|||
int pps;
|
||||
struct ptp_pin_desc *pin_config;
|
||||
int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm);
|
||||
int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta);
|
||||
int (*adjphase)(struct ptp_clock_info *ptp, s32 phase);
|
||||
int (*adjtime)(struct ptp_clock_info *ptp, s64 delta);
|
||||
int (*gettime64)(struct ptp_clock_info *ptp, struct timespec64 *ts);
|
||||
|
|
Загрузка…
Ссылка в новой задаче