Skip to content

Commit 68bbf22

Browse files
author
CKI KWF Bot
committed
Merge: zl3073x: Allow to configure phase offset averaging factor
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1785 JIRA: https://issues.redhat.com/browse/RHEL-123203 Depends: !1726 Commits: ``` 9363b48 ("dpll: zl3073x: Allow to configure phase offset averaging factor") ``` Signed-off-by: Ivan Vecera <ivecera@redhat.com> Approved-by: Michal Schmidt <mschmidt@redhat.com> Approved-by: Petr Oros <poros@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 31c2a78 + 23cd962 commit 68bbf22

File tree

4 files changed

+107
-6
lines changed

4 files changed

+107
-6
lines changed

drivers/dpll/zl3073x/core.c

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,32 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
956956
msecs_to_jiffies(500));
957957
}
958958

959+
int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor)
960+
{
961+
u8 dpll_meas_ctrl, value;
962+
int rc;
963+
964+
/* Read DPLL phase measurement control register */
965+
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, &dpll_meas_ctrl);
966+
if (rc)
967+
return rc;
968+
969+
/* Convert requested factor to register value */
970+
value = (factor + 1) & 0x0f;
971+
972+
/* Update phase measurement control register */
973+
dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR;
974+
dpll_meas_ctrl |= FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, value);
975+
rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, dpll_meas_ctrl);
976+
if (rc)
977+
return rc;
978+
979+
/* Save the new factor */
980+
zldev->phase_avg_factor = factor;
981+
982+
return 0;
983+
}
984+
959985
/**
960986
* zl3073x_dev_phase_meas_setup - setup phase offset measurement
961987
* @zldev: pointer to zl3073x_dev structure
@@ -972,15 +998,16 @@ zl3073x_dev_phase_meas_setup(struct zl3073x_dev *zldev)
972998
u8 dpll_meas_ctrl, mask = 0;
973999
int rc;
9741000

1001+
/* Setup phase measurement averaging factor */
1002+
rc = zl3073x_dev_phase_avg_factor_set(zldev, zldev->phase_avg_factor);
1003+
if (rc)
1004+
return rc;
1005+
9751006
/* Read DPLL phase measurement control register */
9761007
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, &dpll_meas_ctrl);
9771008
if (rc)
9781009
return rc;
9791010

980-
/* Setup phase measurement averaging factor */
981-
dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR;
982-
dpll_meas_ctrl |= FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, 3);
983-
9841011
/* Enable DPLL measurement block */
9851012
dpll_meas_ctrl |= ZL_DPLL_MEAS_CTRL_EN;
9861013

@@ -1208,6 +1235,9 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
12081235
*/
12091236
zldev->clock_id = get_random_u64();
12101237

1238+
/* Default phase offset averaging factor */
1239+
zldev->phase_avg_factor = 2;
1240+
12111241
/* Initialize mutex for operations where multiple reads, writes
12121242
* and/or polls are required to be done atomically.
12131243
*/

drivers/dpll/zl3073x/core.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,19 @@ struct zl3073x_synth {
6868
* @dev: pointer to device
6969
* @regmap: regmap to access device registers
7070
* @multiop_lock: to serialize multiple register operations
71-
* @clock_id: clock id of the device
7271
* @ref: array of input references' invariants
7372
* @out: array of outs' invariants
7473
* @synth: array of synths' invariants
7574
* @dplls: list of DPLLs
7675
* @kworker: thread for periodic work
7776
* @work: periodic work
77+
* @clock_id: clock id of the device
78+
* @phase_avg_factor: phase offset measurement averaging factor
7879
*/
7980
struct zl3073x_dev {
8081
struct device *dev;
8182
struct regmap *regmap;
8283
struct mutex multiop_lock;
83-
u64 clock_id;
8484

8585
/* Invariants */
8686
struct zl3073x_ref ref[ZL3073X_NUM_REFS];
@@ -93,6 +93,10 @@ struct zl3073x_dev {
9393
/* Monitor */
9494
struct kthread_worker *kworker;
9595
struct kthread_delayed_work work;
96+
97+
/* Devlink parameters */
98+
u64 clock_id;
99+
u8 phase_avg_factor;
96100
};
97101

98102
struct zl3073x_chip_info {
@@ -115,6 +119,13 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev,
115119
int zl3073x_dev_start(struct zl3073x_dev *zldev, bool full);
116120
void zl3073x_dev_stop(struct zl3073x_dev *zldev);
117121

122+
static inline u8 zl3073x_dev_phase_avg_factor_get(struct zl3073x_dev *zldev)
123+
{
124+
return zldev->phase_avg_factor;
125+
}
126+
127+
int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor);
128+
118129
/**********************
119130
* Registers operations
120131
**********************/

drivers/dpll/zl3073x/dpll.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,6 +1576,59 @@ zl3073x_dpll_mode_get(const struct dpll_device *dpll, void *dpll_priv,
15761576
return 0;
15771577
}
15781578

1579+
static int
1580+
zl3073x_dpll_phase_offset_avg_factor_get(const struct dpll_device *dpll,
1581+
void *dpll_priv, u32 *factor,
1582+
struct netlink_ext_ack *extack)
1583+
{
1584+
struct zl3073x_dpll *zldpll = dpll_priv;
1585+
1586+
*factor = zl3073x_dev_phase_avg_factor_get(zldpll->dev);
1587+
1588+
return 0;
1589+
}
1590+
1591+
static void
1592+
zl3073x_dpll_change_work(struct work_struct *work)
1593+
{
1594+
struct zl3073x_dpll *zldpll;
1595+
1596+
zldpll = container_of(work, struct zl3073x_dpll, change_work);
1597+
dpll_device_change_ntf(zldpll->dpll_dev);
1598+
}
1599+
1600+
static int
1601+
zl3073x_dpll_phase_offset_avg_factor_set(const struct dpll_device *dpll,
1602+
void *dpll_priv, u32 factor,
1603+
struct netlink_ext_ack *extack)
1604+
{
1605+
struct zl3073x_dpll *item, *zldpll = dpll_priv;
1606+
int rc;
1607+
1608+
if (factor > 15) {
1609+
NL_SET_ERR_MSG_FMT(extack,
1610+
"Phase offset average factor has to be from range <0,15>");
1611+
return -EINVAL;
1612+
}
1613+
1614+
rc = zl3073x_dev_phase_avg_factor_set(zldpll->dev, factor);
1615+
if (rc) {
1616+
NL_SET_ERR_MSG_FMT(extack,
1617+
"Failed to set phase offset averaging factor");
1618+
return rc;
1619+
}
1620+
1621+
/* The averaging factor is common for all DPLL channels so after change
1622+
* we have to send a notification for other DPLL devices.
1623+
*/
1624+
list_for_each_entry(item, &zldpll->dev->dplls, list) {
1625+
if (item != zldpll)
1626+
schedule_work(&item->change_work);
1627+
}
1628+
1629+
return 0;
1630+
}
1631+
15791632
static int
15801633
zl3073x_dpll_phase_offset_monitor_get(const struct dpll_device *dpll,
15811634
void *dpll_priv,
@@ -1635,6 +1688,8 @@ static const struct dpll_pin_ops zl3073x_dpll_output_pin_ops = {
16351688
static const struct dpll_device_ops zl3073x_dpll_device_ops = {
16361689
.lock_status_get = zl3073x_dpll_lock_status_get,
16371690
.mode_get = zl3073x_dpll_mode_get,
1691+
.phase_offset_avg_factor_get = zl3073x_dpll_phase_offset_avg_factor_get,
1692+
.phase_offset_avg_factor_set = zl3073x_dpll_phase_offset_avg_factor_set,
16381693
.phase_offset_monitor_get = zl3073x_dpll_phase_offset_monitor_get,
16391694
.phase_offset_monitor_set = zl3073x_dpll_phase_offset_monitor_set,
16401695
};
@@ -1983,6 +2038,8 @@ zl3073x_dpll_device_unregister(struct zl3073x_dpll *zldpll)
19832038
{
19842039
WARN(!zldpll->dpll_dev, "DPLL device is not registered\n");
19852040

2041+
cancel_work_sync(&zldpll->change_work);
2042+
19862043
dpll_device_unregister(zldpll->dpll_dev, &zl3073x_dpll_device_ops,
19872044
zldpll);
19882045
dpll_device_put(zldpll->dpll_dev);
@@ -2258,6 +2315,7 @@ zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch)
22582315
zldpll->dev = zldev;
22592316
zldpll->id = ch;
22602317
INIT_LIST_HEAD(&zldpll->pins);
2318+
INIT_WORK(&zldpll->change_work, zl3073x_dpll_change_work);
22612319

22622320
return zldpll;
22632321
}

drivers/dpll/zl3073x/dpll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* @dpll_dev: pointer to registered DPLL device
2121
* @lock_status: last saved DPLL lock status
2222
* @pins: list of pins
23+
* @change_work: device change notification work
2324
*/
2425
struct zl3073x_dpll {
2526
struct list_head list;
@@ -32,6 +33,7 @@ struct zl3073x_dpll {
3233
struct dpll_device *dpll_dev;
3334
enum dpll_lock_status lock_status;
3435
struct list_head pins;
36+
struct work_struct change_work;
3537
};
3638

3739
struct zl3073x_dpll *zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch);

0 commit comments

Comments
 (0)