xref: /linux/drivers/dpll/zl3073x/ref.h (revision 84318277d6334c6981ab326d4acc87c6a6ddc9b8)
1607f2c00SIvan Vecera /* SPDX-License-Identifier: GPL-2.0-only */
2607f2c00SIvan Vecera 
3607f2c00SIvan Vecera #ifndef _ZL3073X_REF_H
4607f2c00SIvan Vecera #define _ZL3073X_REF_H
5607f2c00SIvan Vecera 
6607f2c00SIvan Vecera #include <linux/bitfield.h>
7*5bc02b19SIvan Vecera #include <linux/math64.h>
8607f2c00SIvan Vecera #include <linux/types.h>
9607f2c00SIvan Vecera 
10607f2c00SIvan Vecera #include "regs.h"
11607f2c00SIvan Vecera 
12607f2c00SIvan Vecera struct zl3073x_dev;
13607f2c00SIvan Vecera 
14607f2c00SIvan Vecera /**
15607f2c00SIvan Vecera  * struct zl3073x_ref - input reference state
16607f2c00SIvan Vecera  * @ffo: current fractional frequency offset
17*5bc02b19SIvan Vecera  * @phase_comp: phase compensation
18*5bc02b19SIvan Vecera  * @esync_n_div: divisor for embedded sync or n-divided signal formats
19*5bc02b19SIvan Vecera  * @freq_base: frequency base
20*5bc02b19SIvan Vecera  * @freq_mult: frequnecy multiplier
21*5bc02b19SIvan Vecera  * @freq_ratio_m: FEC mode multiplier
22*5bc02b19SIvan Vecera  * @freq_ratio_n: FEC mode divisor
23607f2c00SIvan Vecera  * @config: reference config
24*5bc02b19SIvan Vecera  * @sync_ctrl: reference sync control
255534a820SIvan Vecera  * @mon_status: reference monitor status
26607f2c00SIvan Vecera  */
27607f2c00SIvan Vecera struct zl3073x_ref {
28607f2c00SIvan Vecera 	s64	ffo;
29*5bc02b19SIvan Vecera 	u64	phase_comp;
30*5bc02b19SIvan Vecera 	u32	esync_n_div;
31*5bc02b19SIvan Vecera 	u16	freq_base;
32*5bc02b19SIvan Vecera 	u16	freq_mult;
33*5bc02b19SIvan Vecera 	u16	freq_ratio_m;
34*5bc02b19SIvan Vecera 	u16	freq_ratio_n;
35607f2c00SIvan Vecera 	u8	config;
36*5bc02b19SIvan Vecera 	u8	sync_ctrl;
375534a820SIvan Vecera 	u8	mon_status;
38607f2c00SIvan Vecera };
39607f2c00SIvan Vecera 
40607f2c00SIvan Vecera int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index);
41607f2c00SIvan Vecera 
42607f2c00SIvan Vecera const struct zl3073x_ref *zl3073x_ref_state_get(struct zl3073x_dev *zldev,
43607f2c00SIvan Vecera 						u8 index);
44607f2c00SIvan Vecera 
45*5bc02b19SIvan Vecera int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index,
46*5bc02b19SIvan Vecera 			  const struct zl3073x_ref *ref);
47*5bc02b19SIvan Vecera 
48607f2c00SIvan Vecera int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult);
49607f2c00SIvan Vecera 
50607f2c00SIvan Vecera /**
51607f2c00SIvan Vecera  * zl3073x_ref_ffo_get - get current fractional frequency offset
52607f2c00SIvan Vecera  * @ref: pointer to ref state
53607f2c00SIvan Vecera  *
54607f2c00SIvan Vecera  * Return: the latest measured fractional frequency offset
55607f2c00SIvan Vecera  */
56607f2c00SIvan Vecera static inline s64
57607f2c00SIvan Vecera zl3073x_ref_ffo_get(const struct zl3073x_ref *ref)
58607f2c00SIvan Vecera {
59607f2c00SIvan Vecera 	return ref->ffo;
60607f2c00SIvan Vecera }
61607f2c00SIvan Vecera 
62607f2c00SIvan Vecera /**
63*5bc02b19SIvan Vecera  * zl3073x_ref_freq_get - get given input reference frequency
64*5bc02b19SIvan Vecera  * @ref: pointer to ref state
65*5bc02b19SIvan Vecera  *
66*5bc02b19SIvan Vecera  * Return: frequency of the given input reference
67*5bc02b19SIvan Vecera  */
68*5bc02b19SIvan Vecera static inline u32
69*5bc02b19SIvan Vecera zl3073x_ref_freq_get(const struct zl3073x_ref *ref)
70*5bc02b19SIvan Vecera {
71*5bc02b19SIvan Vecera 	return mul_u64_u32_div(ref->freq_base * ref->freq_mult,
72*5bc02b19SIvan Vecera 			       ref->freq_ratio_m, ref->freq_ratio_n);
73*5bc02b19SIvan Vecera }
74*5bc02b19SIvan Vecera 
75*5bc02b19SIvan Vecera /**
76*5bc02b19SIvan Vecera  * zl3073x_ref_freq_set - set given input reference frequency
77*5bc02b19SIvan Vecera  * @ref: pointer to ref state
78*5bc02b19SIvan Vecera  * @freq: frequency to be set
79*5bc02b19SIvan Vecera  *
80*5bc02b19SIvan Vecera  * Return: 0 on success, <0 when frequency cannot be factorized
81*5bc02b19SIvan Vecera  */
82*5bc02b19SIvan Vecera static inline int
83*5bc02b19SIvan Vecera zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq)
84*5bc02b19SIvan Vecera {
85*5bc02b19SIvan Vecera 	u16 base, mult;
86*5bc02b19SIvan Vecera 	int rc;
87*5bc02b19SIvan Vecera 
88*5bc02b19SIvan Vecera 	rc = zl3073x_ref_freq_factorize(freq, &base, &mult);
89*5bc02b19SIvan Vecera 	if (rc)
90*5bc02b19SIvan Vecera 		return rc;
91*5bc02b19SIvan Vecera 
92*5bc02b19SIvan Vecera 	ref->freq_base = base;
93*5bc02b19SIvan Vecera 	ref->freq_mult = mult;
94*5bc02b19SIvan Vecera 
95*5bc02b19SIvan Vecera 	return 0;
96*5bc02b19SIvan Vecera }
97*5bc02b19SIvan Vecera 
98*5bc02b19SIvan Vecera /**
99607f2c00SIvan Vecera  * zl3073x_ref_is_diff - check if the given input reference is differential
100607f2c00SIvan Vecera  * @ref: pointer to ref state
101607f2c00SIvan Vecera  *
102607f2c00SIvan Vecera  * Return: true if reference is differential, false if reference is single-ended
103607f2c00SIvan Vecera  */
104607f2c00SIvan Vecera static inline bool
105607f2c00SIvan Vecera zl3073x_ref_is_diff(const struct zl3073x_ref *ref)
106607f2c00SIvan Vecera {
107607f2c00SIvan Vecera 	return !!FIELD_GET(ZL_REF_CONFIG_DIFF_EN, ref->config);
108607f2c00SIvan Vecera }
109607f2c00SIvan Vecera 
110607f2c00SIvan Vecera /**
111607f2c00SIvan Vecera  * zl3073x_ref_is_enabled - check if the given input reference is enabled
112607f2c00SIvan Vecera  * @ref: pointer to ref state
113607f2c00SIvan Vecera  *
114607f2c00SIvan Vecera  * Return: true if input refernce is enabled, false otherwise
115607f2c00SIvan Vecera  */
116607f2c00SIvan Vecera static inline bool
117607f2c00SIvan Vecera zl3073x_ref_is_enabled(const struct zl3073x_ref *ref)
118607f2c00SIvan Vecera {
119607f2c00SIvan Vecera 	return !!FIELD_GET(ZL_REF_CONFIG_ENABLE, ref->config);
120607f2c00SIvan Vecera }
121607f2c00SIvan Vecera 
1225534a820SIvan Vecera /**
1235534a820SIvan Vecera  * zl3073x_ref_is_status_ok - check the given input reference status
1245534a820SIvan Vecera  * @ref: pointer to ref state
1255534a820SIvan Vecera  *
1265534a820SIvan Vecera  * Return: true if the status is ok, false otherwise
1275534a820SIvan Vecera  */
1285534a820SIvan Vecera static inline bool
1295534a820SIvan Vecera zl3073x_ref_is_status_ok(const struct zl3073x_ref *ref)
1305534a820SIvan Vecera {
1315534a820SIvan Vecera 	return ref->mon_status == ZL_REF_MON_STATUS_OK;
1325534a820SIvan Vecera }
1335534a820SIvan Vecera 
134607f2c00SIvan Vecera #endif /* _ZL3073X_REF_H */
135