1 /*
2  * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /******************************************************************************
17  * @file     phy.h
18  * @brief    header file for generic PHY Driver
19  * @version  V1.0
20  * @date     21 March 2019
21  ******************************************************************************/
22 #ifndef _ETH_PHY_H_
23 #define _ETH_PHY_H_
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #include <stdint.h>
30 #include "mmio.h"
31 #include "drv_ioremap.h"
32 
33 /**
34 \brief Ethernet link speed
35 */
36 #define CSI_ETH_SPEED_10M               (0)     ///< 10 Mbps link speed
37 #define CSI_ETH_SPEED_100M              (1)     ///< 100 Mbps link speed
38 #define CSI_ETH_SPEED_1G                (2)     ///< 1 Gpbs link speed
39 
40 /**
41 \brief Ethernet duplex mode
42 */
43 #define CSI_ETH_DUPLEX_HALF             (0)     ///< Half duplex link
44 #define CSI_ETH_DUPLEX_FULL             (1)     ///< Full duplex link
45 
46 typedef void *eth_phy_handle_t;
47 
48 typedef enum eth_power_state
49 {
50     CSI_ETH_POWER_OFF,                        ///< Power off: no operation possible
51     CSI_ETH_POWER_LOW,                        ///< Low Power mode: retain state, detect and signal wake-up events
52     CSI_ETH_POWER_FULL                        ///< Power on: full operation at maximum performance
53 } eth_power_state_t;
54 
55 typedef int32_t (*csi_eth_phy_read_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);   ///< Read Ethernet PHY Register.
56 typedef int32_t (*csi_eth_phy_write_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t  data);  ///< Write Ethernet PHY Register.
57 
58 typedef volatile struct eth_link_info
59 {
60     uint32_t speed              : 2;                ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit
61     uint32_t duplex             : 1;                ///< Duplex mode: 0= Half, 1= Full
62     uint32_t autoneg            : 1;                ///< Set the interface to Auto Negotiation mode of transmission parameters
63     uint32_t loopback           : 1;                ///< Set the interface into a Loop-back test mode
64     uint32_t isolation          : 1;                ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface
65     uint32_t reserved           : 26;
66 } eth_link_info_t;
67 
68 typedef struct
69 {
70     csi_eth_phy_read_t  phy_read;
71     csi_eth_phy_write_t phy_write;
72     eth_link_info_t     link_info;
73 } eth_phy_priv_t;
74 
75 typedef enum eth_link_state
76 {
77     ETH_LINK_DOWN,                    ///< Link is down
78     ETH_LINK_UP                       ///< Link is up
79 } eth_link_state_t;
80 
81 /* Basic mode control register */
82 #define CVI_BMCR_RESV           (0x003f)
83 #define CVI_BMCR_SPEED1000      (0x0040)
84 #define CVI_BMCR_CTST           (0x0080)
85 #define CVI_BMCR_FULLDPLX       (0x0100)
86 #define CVI_BMCR_ANRESTART      (0x0200)
87 #define CVI_BMCR_ISOLATE        (0x0400)
88 #define CVI_BMCR_PDOWN          (0x0800)
89 #define CVI_BMCR_ANENABLE       (0x1000)
90 #define CVI_BMCR_SPEED100       (0x2000)
91 #define CVI_BMCR_LOOPBACK       (0x4000)
92 #define CVI_BMCR_RESET          (0x8000)
93 #define BMCR_SPEED10            (0x0000)
94 
95 
96 /* Generic MII registers */
97 #define CVI_MII_BMCR            (0x00)
98 #define CVI_MII_BMSR            (0x01)
99 #define CVI_MII_PHYSID1         (0x02)
100 #define CVI_MII_PHYSID2         (0x03)
101 #define CVI_MII_ADVERTISE       (0x04)
102 #define CVI_MII_LPA             (0x05)
103 #define CVI_MII_EXPANSION       (0x06)
104 #define CVI_MII_CTRL1000        (0x09)
105 #define CVI_MII_STAT1000        (0x0a)
106 #define MII_MMD_CTRL            (0x0d)
107 #define MII_MMD_DATA            (0x0e)
108 #define CVI_MII_ESTATUS         (0x0f)
109 #define CVI_MII_DCOUNTER        (0x12)
110 #define CVI_MII_FCSCOUNTER      (0x13)
111 #define CVI_MII_NWAYTEST        (0x14)
112 #define CVI_MII_RERRCOUNTER     (0x15)
113 #define CVI_MII_SREVISION       (0x16)
114 #define CVI_MII_RESV1           (0x17)
115 #define CVI_MII_LBRERROR        (0x18)
116 #define CVI_MII_PHYADDR         (0x19)
117 #define CVI_MII_RESV2           (0x1a)
118 #define CVI_MII_TPISTATUS       (0x1b)
119 #define CVI_MII_NCONFIG         (0x1c)
120 
121 /* Advertisement control register. */
122 #define CVI_ADVERTISE_CSMA          (0x0001)
123 #define CVI_ADVERTISE_SLCT          (0x001f)
124 #define CVI_ADVERTISE_10HALF        (0x0020)
125 #define CVI_ADVERTISE_1000XFULL     (0x0020)
126 #define CVI_ADVERTISE_10FULL        (0x0040)
127 #define CVI_ADVERTISE_1000XHALF     (0x0040)
128 #define CVI_ADVERTISE_100HALF       (0x0080)
129 #define CVI_ADVERTISE_1000XPAUSE    (0x0080)
130 #define CVI_ADVERTISE_100FULL       (0x0100)
131 #define CVI_ADVERTISE_1000XPSE_ASYM (0x0100)
132 #define CVI_ADVERTISE_100BASE4      (0x0200)
133 #define CVI_ADVERTISE_PAUSE_CAP     (0x0400)
134 #define CVI_ADVERTISE_PAUSE_ASYM    (0x0800)
135 #define CVI_ADVERTISE_RESV          (0x1000)
136 #define CVI_ADVERTISE_RFAULT        (0x2000)
137 #define CVI_ADVERTISE_LPACK         (0x4000)
138 #define CVI_ADVERTISE_NPAGE         (0x8000)
139 
140 /* Basic mode status register. */
141 #define CVI_BMSR_ERCAP          (0x0001)
142 #define CVI_BMSR_JCD            (0x0002)
143 #define CVI_BMSR_LSTATUS        (0x0004)
144 #define CVI_BMSR_ANEGCAPABLE    (0x0008)
145 #define CVI_BMSR_RFAULT         (0x0010)
146 #define CVI_BMSR_ANEGCOMPLETE   (0x0020)
147 #define CVI_BMSR_RESV           (0x00c0)
148 #define CVI_BMSR_ESTATEN        (0x0100)
149 #define CVI_BMSR_100HALF2       (0x0200)
150 #define CVI_BMSR_100FULL2       (0x0400)
151 #define CVI_BMSR_10HALF         (0x0800)
152 #define CVI_BMSR_10FULL         (0x1000)
153 #define CVI_BMSR_100HALF        (0x2000)
154 #define CVI_BMSR_100FULL        (0x4000)
155 #define CVI_BMSR_100BASE4       (0x8000)
156 
157 #define CVI_ADVERTISE_FULL  (CVI_ADVERTISE_100FULL | CVI_ADVERTISE_10FULL | \
158                          CVI_ADVERTISE_CSMA)
159 #define CVI_ADVERTISE_ALL   (CVI_ADVERTISE_10HALF | CVI_ADVERTISE_10FULL | \
160                          CVI_ADVERTISE_100HALF | CVI_ADVERTISE_100FULL)
161 
162 /* Link partner ability register. */
163 #define CVI_LPA_SLCT            (0x001f)  /* Same as advertise selector */
164 #define CVI_LPA_10HALF          (0x0020)  /* Can do 10mbps half-duplex */
165 #define CVI_LPA_1000XFULL       (0x0020)  /* Can do 1000BASE-X full-duplex */
166 #define CVI_LPA_10FULL          (0x0040)  /* Can do 10mbps full-duplex */
167 #define CVI_LPA_1000XHALF       (0x0040)  /* Can do 1000BASE-X half-duplex */
168 #define CVI_LPA_100HALF         (0x0080)  /* Can do 100mbps half-duplex */
169 #define CVI_LPA_1000XPAUSE      (0x0080)  /* Can do 1000BASE-X pause */
170 #define CVI_LPA_100FULL         (0x0100)  /* Can do 100mbps full-duplex */
171 #define CVI_LPA_1000XPAUSE_ASYM (0x0100)  /* Can do 1000BASE-X pause asym */
172 #define CVI_LPA_100BASE4        (0x0200)  /* Can do 100mbps 4k packets */
173 #define CVI_LPA_PAUSE_CAP       (0x0400)  /* Can pause */
174 #define CVI_LPA_PAUSE_ASYM      (0x0800)  /* Can pause asymetrically */
175 #define CVI_LPA_RESV            (0x1000)  /* Unused */
176 #define CVI_LPA_RFAULT          (0x2000)  /* Link partner faulted */
177 #define CVI_LPA_LPACK           (0x4000)  /* Link partner acked us */
178 #define CVI_LPA_NPAGE           (0x8000)  /* Next page bit */
179 
180 #define CVI_LPA_DUPLEX  (CVI_LPA_10FULL | CVI_LPA_100FULL)
181 #define CVI_LPA_100     (CVI_LPA_100FULL | CVI_LPA_100HALF | CVI_LPA_100BASE4)
182 
183 /* Expansion register for auto-negotiation. */
184 #define CVI_EXPANSION_NWAY          (0x0001)  /* Can do N-way auto-nego */
185 #define CVI_EXPANSION_LCWP          (0x0002)  /* Got new RX page code word */
186 #define CVI_EXPANSION_ENABLENPAGE   (0x0004)  /* This enables npage words */
187 #define CVI_EXPANSION_NPCAPABLE     (0x0008)  /* Link partner supports npage */
188 #define CVI_EXPANSION_MFAULTS       (0x0010)  /* Multiple faults detected */
189 #define CVI_EXPANSION_RESV          (0xffe0)  /* Unused */
190 
191 #define CVI_ESTATUS_1000_XFULL  (0x8000)  /* Can do 1000BX Full */
192 #define CVI_ESTATUS_1000_XHALF  (0x4000)  /* Can do 1000BX Half */
193 #define CVI_ESTATUS_1000_TFULL  (0x2000)  /* Can do 1000BT Full */
194 #define CVI_ESTATUS_1000_THALF  (0x1000)  /* Can do 1000BT Half */
195 
196 /* N-way test register. */
197 #define CVI_NWAYTEST_RESV1      (0x00ff)  /* Unused */
198 #define CVI_NWAYTEST_LOOPBACK   (0x0100)  /* Enable loopback for N-way */
199 #define CVI_NWAYTEST_RESV2      (0xfe00)  /* Unused */
200 
201 /* 1000BASE-T Control register */
202 #define CVI_ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex */
203 #define CVI_ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex */
204 #define CTL1000_AS_MASTER           0x0800
205 #define CTL1000_ENABLE_MASTER       0x1000
206 
207 /* 1000BASE-T Status register */
208 #define CVI_LPA_1000LOCALRXOK   0x2000  /* Link partner local receiver status */
209 #define CVI_LPA_1000REMRXOK     0x1000  /* Link partner remote receiver status */
210 #define CVI_LPA_1000FULL        0x0800  /* Link partner 1000BASE-T full duplex */
211 #define CVI_LPA_1000HALF        0x0400  /* Link partner 1000BASE-T half duplex */
212 
213 /* Flow control flags */
214 #define CVI_FLOW_CTRL_TX        0x01
215 #define CVI_FLOW_CTRL_RX        0x02
216 
217 /* MMD Access Control register fields */
218 #define CVI_MII_MMD_CTRL_DEVAD_MASK 0x1f    /* Mask MMD DEVAD*/
219 #define CVI_MII_MMD_CTRL_ADDR       0x0000  /* Address */
220 #define CVI_MII_MMD_CTRL_NOINCR     0x4000  /* no post increment */
221 #define CVI_MII_MMD_CTRL_INCR_RDWT  0x8000  /* post increment on reads & writes */
222 #define CVI_MII_MMD_CTRL_INCR_ON_WT 0xC000  /* post increment on writes only */
223 
224 
225 /* Indicates what features are advertised by the interface. */
226 #define CVI_ADVERTISED_10baseT_Half         (1 << 0)
227 #define CVI_ADVERTISED_10baseT_Full         (1 << 1)
228 #define CVI_ADVERTISED_100baseT_Half        (1 << 2)
229 #define CVI_ADVERTISED_100baseT_Full        (1 << 3)
230 #define CVI_ADVERTISED_1000baseT_Half       (1 << 4)
231 #define CVI_ADVERTISED_1000baseT_Full       (1 << 5)
232 #define CVI_ADVERTISED_Autoneg              (1 << 6)
233 #define CVI_ADVERTISED_TP                   (1 << 7)
234 #define CVI_ADVERTISED_AUI                  (1 << 8)
235 #define CVI_ADVERTISED_MII                  (1 << 9)
236 #define CVI_ADVERTISED_FIBRE                (1 << 10)
237 #define CVI_ADVERTISED_BNC                  (1 << 11)
238 #define CVI_ADVERTISED_10000baseT_Full      (1 << 12)
239 #define CVI_ADVERTISED_Pause                (1 << 13)
240 #define CVI_ADVERTISED_Asym_Pause           (1 << 14)
241 #define CVI_ADVERTISED_2500baseX_Full       (1 << 15)
242 #define CVI_ADVERTISED_Backplane            (1 << 16)
243 #define CVI_ADVERTISED_1000baseKX_Full      (1 << 17)
244 #define CVI_ADVERTISED_10000baseKX4_Full    (1 << 18)
245 #define CVI_ADVERTISED_10000baseKR_Full     (1 << 19)
246 #define CVI_ADVERTISED_10000baseR_FEC       (1 << 20)
247 #define CVI_ADVERTISED_1000baseX_Half       (1 << 21)
248 #define CVI_ADVERTISED_1000baseX_Full       (1 << 22)
249 
250 
251 /* Indicates what features are supported by the interface. */
252 #define CVI_SUPPORTED_10baseT_Half      (1 << 0)
253 #define CVI_SUPPORTED_10baseT_Full      (1 << 1)
254 #define CVI_SUPPORTED_100baseT_Half     (1 << 2)
255 #define CVI_SUPPORTED_100baseT_Full     (1 << 3)
256 #define CVI_SUPPORTED_1000baseT_Half    (1 << 4)
257 #define CVI_SUPPORTED_1000baseT_Full    (1 << 5)
258 #define CVI_SUPPORTED_Autoneg           (1 << 6)
259 #define CVI_SUPPORTED_TP                (1 << 7)
260 #define CVI_SUPPORTED_AUI               (1 << 8)
261 #define CVI_SUPPORTED_MII               (1 << 9)
262 #define CVI_SUPPORTED_FIBRE             (1 << 10)
263 #define CVI_SUPPORTED_BNC               (1 << 11)
264 #define CVI_SUPPORTED_10000baseT_Full   (1 << 12)
265 #define CVI_SUPPORTED_Pause             (1 << 13)
266 #define CVI_SUPPORTED_Asym_Pause        (1 << 14)
267 #define CVI_SUPPORTED_2500baseX_Full    (1 << 15)
268 #define CVI_SUPPORTED_Backplane         (1 << 16)
269 #define CVI_SUPPORTED_1000baseKX_Full   (1 << 17)
270 #define CVI_SUPPORTED_10000baseKX4_Full (1 << 18)
271 #define CVI_SUPPORTED_10000baseKR_Full  (1 << 19)
272 #define CVI_SUPPORTED_10000baseR_FEC    (1 << 20)
273 #define CVI_SUPPORTED_1000baseX_Half    (1 << 21)
274 #define CVI_SUPPORTED_1000baseX_Full    (1 << 22)
275 
276 /* PHY features */
277 #define CVI_PHY_DEFAULT_FEATURES    (CVI_SUPPORTED_Autoneg | \
278                                  CVI_SUPPORTED_TP | \
279                                  CVI_SUPPORTED_MII)
280 
281 #define CVI_PHY_10BT_FEATURES   (CVI_SUPPORTED_10baseT_Half | \
282                              CVI_SUPPORTED_10baseT_Full)
283 
284 #define CVI_PHY_100BT_FEATURES  (CVI_SUPPORTED_100baseT_Half | \
285                              CVI_SUPPORTED_100baseT_Full)
286 
287 #define CVI_PHY_1000BT_FEATURES (CVI_SUPPORTED_1000baseT_Half | \
288                              CVI_SUPPORTED_1000baseT_Full)
289 
290 #define CVI_PHY_BASIC_FEATURES  (CVI_PHY_10BT_FEATURES | \
291                              CVI_PHY_100BT_FEATURES | \
292                              CVI_PHY_DEFAULT_FEATURES)
293 
294 #define CVI_PHY_GBIT_FEATURES   (CVI_PHY_BASIC_FEATURES | \
295                              CVI_PHY_1000BT_FEATURES)
296 
297 #define CVI_PHY_ANEG_TIMEOUT    5000    /* in ms */
298 
299 typedef enum {
300     LOOPBACK_XMII2MAC,
301     LOOPBACK_PCS2MAC,
302     LOOPBACK_PMA2MAC,
303     LOOPBACK_RMII2PHY,
304 } phy_loopback_mode_t;
305 
306 /* phy interface mode */
307 typedef enum {
308     PHY_IF_MODE_MII,
309     PHY_IF_MODE_GMII,
310     PHY_IF_MODE_SGMII,
311     PHY_IF_MODE_TBI,
312     PHY_IF_MODE_RMII,
313     PHY_IF_MODE_RGMII,
314     PHY_IF_MODE_RGMII_ID,
315     PHY_IF_MODE_RGMII_RXID,
316     PHY_IF_MODE_RGMII_TXID,
317     PHY_IF_MODE_RTBI,
318 
319     PHY_IF_MODE_NONE,   /* Last One */
320     PHY_IF_MODE_COUNT,
321 } phy_if_mode_t;
322 
323 typedef struct {
324     eth_phy_priv_t *priv;
325     eth_link_state_t link_state;
326 
327     uint32_t supported;
328     uint32_t advertising;
329 
330     /*
331      * platform specific
332      */
333     uint32_t phy_addr;
334     phy_if_mode_t interface;
335 
336     /*
337      * driver specific
338      */
339     uint32_t phy_id;
340     uint32_t mask;
341     uint32_t features;
342     int8_t name[20];
343     /* config() should be called before calling start() */
344     int32_t (*config)(eth_phy_handle_t phy_dev);
345     int32_t (*start)(eth_phy_handle_t phy_dev);
346     int32_t (*stop)(eth_phy_handle_t phy_dev);
347     int32_t (*loopback)(eth_phy_handle_t phy_dev);
348     int32_t (*update_link)(eth_phy_handle_t phy_dev);
349 } eth_phy_dev_t;
350 
351 /* ethernet phy config */
352 #define ETH_PHY_BASE            (uintptr_t)DRV_IOREMAP((void *)0x03009000, 0x1000)
353 #define ETH_PHY_INIT_MASK       0xFFFFFFF9
354 #define ETH_PHY_SHUTDOWN        (1 << 1)
355 #define ETH_PHY_POWERUP         0xFFFFFFFD
356 #define ETH_PHY_RESET           0xFFFFFFFB
357 #define ETH_PHY_RESET_N         (1 << 2)
358 #define ETH_PHY_LED_LOW_ACTIVE  (1 << 3)
359 
360 int generic_phy_config_aneg(eth_phy_dev_t *dev);
361 int generic_phy_restart_aneg(eth_phy_dev_t *dev);
362 int generic_phy_update_link(eth_phy_dev_t *dev);
363 
364 int32_t eth_phy_read(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
365 int32_t eth_phy_write(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
366 
367 int32_t eth_phy_reset(eth_phy_handle_t handle);
368 int32_t eth_phy_config(eth_phy_handle_t handle);
369 int32_t eth_phy_start(eth_phy_handle_t handle);
370 int32_t eth_phy_update_link(eth_phy_handle_t handle);
371 
372 int32_t genphy_config(eth_phy_dev_t *phy_dev);
373 int32_t genphy_update_link(eth_phy_dev_t *phy_dev);
374 
375 int32_t cvi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state);
376 
377 eth_phy_handle_t cvi_eth_phy_init(csi_eth_phy_read_t  fn_read, csi_eth_phy_write_t fn_write);
378 
379 
380 #ifdef __cplusplus
381 }
382 #endif
383 
384 #endif /* _ETH_PHY_H_ */
385