1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright 2009-2012 Freescale Semiconductor, Inc.
4 * Copyright 2019 NXP
5 */
6
7#ifndef __FM_ETH_H__
8#define __FM_ETH_H__
9
10#include <phy.h>
11#include <asm/types.h>
12
13enum fm_port {
14	FM1_DTSEC1,
15	FM1_DTSEC2,
16	FM1_DTSEC3,
17	FM1_DTSEC4,
18	FM1_DTSEC5,
19	FM1_DTSEC6,
20	FM1_DTSEC9,
21	FM1_DTSEC10,
22	FM1_10GEC1,
23	FM1_10GEC2,
24	FM1_10GEC3,
25	FM1_10GEC4,
26	FM2_DTSEC1,
27	FM2_DTSEC2,
28	FM2_DTSEC3,
29	FM2_DTSEC4,
30	FM2_DTSEC5,
31	FM2_DTSEC6,
32	FM2_DTSEC9,
33	FM2_DTSEC10,
34	FM2_10GEC1,
35	FM2_10GEC2,
36	NUM_FM_PORTS,
37};
38
39enum fm_eth_type {
40	FM_ETH_1G_E,
41	FM_ETH_10G_E,
42};
43
44/* Historically, on FMan v3 platforms, the first MDIO bus has been used for
45 * Clause 22 PHYs and the second MDIO bus for 10G Clause 45 PHYs (thus the
46 * TGEC name).
47 *
48 * On LS1046A-FRWY, the QSGMII PHY is connected to the second MDIO bus,
49 * and no TGEC ports are present on-board.
50 */
51#ifdef CONFIG_SYS_FMAN_V3
52#ifdef CONFIG_TARGET_LS1046AFRWY
53#define CFG_SYS_FM1_DTSEC_MDIO_ADDR	(CFG_SYS_FSL_FM1_ADDR + 0xfd000)
54#else
55#define CFG_SYS_FM1_DTSEC_MDIO_ADDR	(CFG_SYS_FSL_FM1_ADDR + 0xfc000)
56#endif
57#define CFG_SYS_FM1_TGEC_MDIO_ADDR	(CFG_SYS_FSL_FM1_ADDR + 0xfd000)
58#if (CFG_SYS_NUM_FMAN == 2)
59#define CFG_SYS_FM2_DTSEC_MDIO_ADDR	(CFG_SYS_FSL_FM2_ADDR + 0xfc000)
60#define CFG_SYS_FM2_TGEC_MDIO_ADDR	(CFG_SYS_FSL_FM2_ADDR + 0xfd000)
61#endif
62#else
63#define CFG_SYS_FM1_DTSEC1_MDIO_ADDR	(CFG_SYS_FSL_FM1_ADDR + 0xe1120)
64#define CFG_SYS_FM1_TGEC_MDIO_ADDR	(CFG_SYS_FSL_FM1_ADDR + 0xf1000)
65#endif
66
67#define DEFAULT_FM_MDIO_NAME "FSL_MDIO0"
68#define DEFAULT_FM_TGEC_MDIO_NAME "FM_TGEC_MDIO"
69
70/* Fman ethernet info struct */
71#define FM_ETH_INFO_INITIALIZER(idx, pregs) \
72	.fm		= idx,						\
73	.phy_regs	= (void *)pregs,				\
74	.enet_if	= PHY_INTERFACE_MODE_NA,			\
75
76#ifdef CONFIG_SYS_FMAN_V3
77#define FM_DTSEC_INFO_INITIALIZER(idx, n) \
78{									\
79	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_DTSEC_MDIO_ADDR)	\
80	.index		= idx,						\
81	.num		= n - 1,					\
82	.type		= FM_ETH_1G_E,					\
83	.port		= FM##idx##_DTSEC##n,				\
84	.rx_port_id	= RX_PORT_1G_BASE + n - 1,			\
85	.tx_port_id	= TX_PORT_1G_BASE + n - 1,			\
86	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
87				offsetof(struct ccsr_fman, memac[n-1]),\
88}
89
90#ifdef CONFIG_FSL_FM_10GEC_REGULAR_NOTATION
91#define FM_TGEC_INFO_INITIALIZER(idx, n) \
92{									\
93	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_TGEC_MDIO_ADDR)	\
94	.index		= idx,						\
95	.num		= n - 1,					\
96	.type		= FM_ETH_10G_E,					\
97	.port		= FM##idx##_10GEC##n,				\
98	.rx_port_id	= RX_PORT_10G_BASE2 + n - 1,			\
99	.tx_port_id	= TX_PORT_10G_BASE2 + n - 1,			\
100	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
101				 offsetof(struct ccsr_fman, memac[n-1]),\
102}
103#else
104#if (CFG_SYS_NUM_FMAN == 2)
105#define FM_TGEC_INFO_INITIALIZER(idx, n) \
106{									\
107	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM2_TGEC_MDIO_ADDR)	\
108	.index		= idx,						\
109	.num		= n - 1,					\
110	.type		= FM_ETH_10G_E,					\
111	.port		= FM##idx##_10GEC##n,				\
112	.rx_port_id	= RX_PORT_10G_BASE + n - 1,			\
113	.tx_port_id	= TX_PORT_10G_BASE + n - 1,			\
114	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
115				offsetof(struct ccsr_fman, memac[n-1+8]),\
116}
117#else
118#define FM_TGEC_INFO_INITIALIZER(idx, n) \
119{									\
120	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_TGEC_MDIO_ADDR)	\
121	.index		= idx,						\
122	.num		= n - 1,					\
123	.type		= FM_ETH_10G_E,					\
124	.port		= FM##idx##_10GEC##n,				\
125	.rx_port_id	= RX_PORT_10G_BASE + n - 1,			\
126	.tx_port_id	= TX_PORT_10G_BASE + n - 1,			\
127	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
128				offsetof(struct ccsr_fman, memac[n-1+8]),\
129}
130#endif
131#endif
132
133#if (CFG_SYS_NUM_FM1_10GEC >= 3)
134#define FM_TGEC_INFO_INITIALIZER2(idx, n) \
135{									\
136	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_TGEC_MDIO_ADDR)	\
137	.index		= idx,						\
138	.num		= n - 1,					\
139	.type		= FM_ETH_10G_E,					\
140	.port		= FM##idx##_10GEC##n,				\
141	.rx_port_id	= RX_PORT_10G_BASE2 + n - 3,			\
142	.tx_port_id	= TX_PORT_10G_BASE2 + n - 3,			\
143	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
144				offsetof(struct ccsr_fman, memac[n-1-2]),\
145}
146#endif
147
148#else
149#define FM_DTSEC_INFO_INITIALIZER(idx, n) \
150{									\
151	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_DTSEC1_MDIO_ADDR)	\
152	.index		= idx,						\
153	.num		= n - 1,					\
154	.type		= FM_ETH_1G_E,					\
155	.port		= FM##idx##_DTSEC##n,				\
156	.rx_port_id	= RX_PORT_1G_BASE + n - 1,			\
157	.tx_port_id	= TX_PORT_1G_BASE + n - 1,			\
158	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
159				offsetof(struct ccsr_fman, mac_1g[n-1]),\
160}
161
162#define FM_TGEC_INFO_INITIALIZER(idx, n) \
163{									\
164	FM_ETH_INFO_INITIALIZER(idx, CFG_SYS_FM1_TGEC_MDIO_ADDR)	\
165	.index		= idx,						\
166	.num		= n - 1,					\
167	.type		= FM_ETH_10G_E,					\
168	.port		= FM##idx##_10GEC##n,				\
169	.rx_port_id	= RX_PORT_10G_BASE + n - 1,			\
170	.tx_port_id	= TX_PORT_10G_BASE + n - 1,			\
171	.compat_offset	= CFG_SYS_FSL_FM##idx##_OFFSET +		\
172				offsetof(struct ccsr_fman, mac_10g[n-1]),\
173}
174#endif
175struct fm_eth_info {
176	u8 enabled;
177	u8 fm;
178	u8 num;
179	u8 phy_addr;
180	int index;
181	u16 rx_port_id;
182	u16 tx_port_id;
183	enum fm_port port;
184	enum fm_eth_type type;
185	void *phy_regs;
186	phy_interface_t enet_if;
187	u32 compat_offset;
188	struct mii_dev *bus;
189};
190
191struct tgec_mdio_info {
192	struct tgec_mdio_controller *regs;
193	char *name;
194};
195
196struct memac_mdio_info {
197	struct memac_mdio_controller *regs;
198	char *name;
199};
200
201int fm_tgec_mdio_init(struct bd_info *bis, struct tgec_mdio_info *info);
202int fm_memac_mdio_init(struct bd_info *bis, struct memac_mdio_info *info);
203
204void fman_enet_init(void);
205void fdt_fixup_fman_ethernet(void *fdt);
206phy_interface_t fm_info_get_enet_if(enum fm_port port);
207void fm_info_set_phy_address(enum fm_port port, int address);
208int fm_info_get_phy_address(enum fm_port port);
209void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus);
210void fm_disable_port(enum fm_port port);
211void fm_enable_port(enum fm_port port);
212void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port,
213		unsigned int port_num, int phy_base_addr);
214int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr,
215		unsigned int port_num, unsigned regnum);
216
217#endif
218