xref: /linux/drivers/phy/freescale/phy-fsl-lynx-core.h (revision 62cf248de32f061d99cf7cd1675419d739031c5e)
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /* Copyright 2025-2026 NXP */
3 
4 #ifndef _PHY_FSL_LYNX_CORE_H
5 #define _PHY_FSL_LYNX_CORE_H
6 
7 #include <linux/phy/phy.h>
8 #include <linux/phy.h>
9 #include <soc/fsl/phy-fsl-lynx.h>
10 
11 #define LYNX_NUM_PLL				2
12 #define LYNX_QUIRK_HAS_HARDCODED_USXGMII	BIT(0)
13 
14 struct lynx_priv;
15 struct lynx_lane;
16 
17 struct lynx_pccr {
18 	int offset;
19 	int width;
20 	int shift;
21 };
22 
23 struct lynx_pll {
24 	struct lynx_priv *priv;
25 	int id;
26 	int refclk_sel;
27 	int frate_sel;
28 	bool enabled;
29 	bool locked;
30 	DECLARE_BITMAP(supported, LANE_MODE_MAX);
31 };
32 
33 struct lynx_lane {
34 	struct lynx_priv *priv;
35 	struct phy *phy;
36 	bool powered_up;
37 	bool init;
38 	unsigned int id;
39 	enum lynx_lane_mode mode;
40 	u32 default_pccr[LANE_MODE_MAX];
41 };
42 
43 struct lynx_info {
44 	int (*get_pccr)(enum lynx_lane_mode lane_mode, int lane,
45 			struct lynx_pccr *pccr);
46 	int (*get_pcvt_offset)(int lane, enum lynx_lane_mode mode);
47 	bool (*lane_supports_mode)(int lane, enum lynx_lane_mode mode);
48 	void (*pll_read_configuration)(struct lynx_pll *pll);
49 	void (*lane_read_configuration)(struct lynx_lane *lane);
50 	void (*cdr_lock_check)(struct lynx_lane *lane);
51 	int first_lane;
52 	int num_lanes;
53 	int index;
54 	unsigned long quirks;
55 };
56 
57 struct lynx_priv {
58 	void __iomem *base;
59 	struct device *dev;
60 	const struct lynx_info *info;
61 	/* Serialize concurrent access to registers shared between lanes,
62 	 * like PCCn
63 	 */
64 	spinlock_t pcc_lock;
65 	bool big_endian;
66 	struct lynx_pll pll[LYNX_NUM_PLL];
67 	struct lynx_lane *lane;
68 
69 	struct delayed_work cdr_check;
70 };
71 
72 static inline u32 lynx_read(struct lynx_priv *priv, unsigned long off)
73 {
74 	void __iomem *reg = priv->base + off;
75 
76 	if (priv->big_endian)
77 		return ioread32be(reg);
78 
79 	return ioread32(reg);
80 }
81 
82 static inline void lynx_write(struct lynx_priv *priv, unsigned long off, u32 val)
83 {
84 	void __iomem *reg = priv->base + off;
85 
86 	if (priv->big_endian)
87 		return iowrite32be(val, reg);
88 
89 	return iowrite32(val, reg);
90 }
91 
92 static inline void lynx_rmw(struct lynx_priv *priv, unsigned long off, u32 val,
93 			    u32 mask)
94 {
95 	u32 orig, tmp;
96 
97 	orig = lynx_read(priv, off);
98 	tmp = orig & ~mask;
99 	tmp |= val;
100 	if (orig != tmp)
101 		lynx_write(priv, off, tmp);
102 }
103 
104 #define lynx_lane_rmw(lane, reg, val, mask)	\
105 	lynx_rmw((lane)->priv, reg(lane->id), val, mask)
106 #define lynx_lane_read(lane, reg)			\
107 	lynx_read((lane)->priv, reg((lane)->id))
108 #define lynx_lane_write(lane, reg, val)		\
109 	lynx_write((lane)->priv, reg((lane)->id), val)
110 #define lynx_pll_read(pll, reg)			\
111 	lynx_read((pll)->priv, reg((pll)->id))
112 
113 int lynx_probe(struct platform_device *pdev, const struct lynx_info *info,
114 	       const struct phy_ops *phy_ops);
115 void lynx_remove(struct platform_device *pdev);
116 
117 const char *lynx_lane_mode_str(enum lynx_lane_mode lane_mode);
118 enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf);
119 bool lynx_lane_supports_mode(struct lynx_lane *lane, enum lynx_lane_mode mode);
120 int lynx_phy_mode_to_lane_mode(struct phy *phy, enum phy_mode mode,
121 			       int submode, enum lynx_lane_mode *lane_mode);
122 
123 struct lynx_pll *lynx_pll_get(struct lynx_priv *priv, enum lynx_lane_mode mode);
124 
125 int lynx_pccr_read(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 *val);
126 int lynx_pccr_write(struct lynx_lane *lane, enum lynx_lane_mode mode, u32 val);
127 int lynx_pcvt_read(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr,
128 		   u32 *val);
129 int lynx_pcvt_write(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr,
130 		    u32 val);
131 int lynx_pcvt_rmw(struct lynx_lane *lane, enum lynx_lane_mode mode, int cr,
132 		  u32 val, u32 mask);
133 
134 #endif
135