• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 /*---------------------------------------------------------------------
9  * Includes
10  *---------------------------------------------------------------------
11  */
12 #include "hpm_enet_drv.h"
13 #include "hpm_dp83867_regs.h"
14 #include "hpm_dp83867.h"
15 #include "board.h"
16 
17 /*---------------------------------------------------------------------
18  * Interal API
19  *---------------------------------------------------------------------
20  */
dp83867_id_check(ENET_Type * ptr)21 bool dp83867_id_check(ENET_Type *ptr)
22 {
23     uint16_t id1, id2;
24 
25     id1 = enet_read_phy(ptr, PHY_ADDR, DP83867_REG_PHYID1);
26     id2 = enet_read_phy(ptr, PHY_ADDR, DP83867_REG_PHYID2);
27 
28     if (DP83867_PHYID1_OUI_MSB_GET(id1) == PHY_ID1 && DP83867_PHYID2_OUI_MSB_GET(id2) == PHY_ID2) {
29         return true;
30     } else {
31         return false;
32     }
33 }
34 
dp83867_phy_write_ext(ENET_Type * ptr,uint32_t phy_addr,uint32_t addr,uint32_t data)35 static void dp83867_phy_write_ext(ENET_Type *ptr, uint32_t phy_addr, uint32_t addr, uint32_t data)
36 {
37     /* set the control register for register address */
38     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_REGCR, DP83867_REGCR_FUNCTION_ADDR | DP83867_REGCR_DEVAD);
39 
40     /* write the specified register address */
41     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_ADDAR, addr);
42 
43     /* set the control register for register data */
44     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_REGCR, DP83867_REGCR_FUNCTION_DATA | DP83867_REGCR_DEVAD);
45 
46     /* write the specified register data */
47     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_ADDAR, data);
48 }
49 
dp83867_phy_read_ext(ENET_Type * ptr,uint32_t phy_addr,uint32_t addr)50 static uint16_t dp83867_phy_read_ext(ENET_Type *ptr, uint32_t phy_addr, uint32_t addr)
51 {
52     /* set the control register for register address */
53     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_REGCR, DP83867_REGCR_FUNCTION_ADDR | DP83867_REGCR_DEVAD);
54 
55     /* write the specified register address */
56     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_ADDAR, addr);
57 
58     /* set the control register for register data */
59     enet_write_phy(ptr, phy_addr, DP83867_EXT_REG_REGCR, DP83867_REGCR_FUNCTION_DATA | DP83867_REGCR_DEVAD);
60 
61     /* read the specified register data */
62     return enet_read_phy(ptr, phy_addr, DP83867_EXT_REG_ADDAR);
63 }
64 /*---------------------------------------------------------------------
65  * API
66  *---------------------------------------------------------------------
67  */
DP83867_REGister_check(ENET_Type * ptr,uint32_t addr)68 uint16_t DP83867_REGister_check(ENET_Type *ptr, uint32_t addr)
69 {
70    return enet_read_phy(ptr, PHY_ADDR, addr);
71 }
72 
dp83867_reset(ENET_Type * ptr)73 void dp83867_reset(ENET_Type *ptr)
74 {
75     uint16_t data;
76 
77     /* PHY reset */
78     enet_write_phy(ptr, PHY_ADDR, DP83867_REG_BMCR, DP83867_BMCR_RESET_SET(1));
79 
80     /* wait until the reset is completed */
81     do {
82         data = enet_read_phy(ptr, PHY_ADDR, DP83867_REG_BMCR);
83     } while (DP83867_BMCR_RESET_GET(data));
84 }
85 
dp83867_basic_mode_default_config(ENET_Type * ptr,dp83867_config_t * config)86 void dp83867_basic_mode_default_config(ENET_Type *ptr, dp83867_config_t *config)
87 {
88     config->loopback         = 0; /* Enable PCS loopback mode */
89     config->speed            = 2; /* 3: reserved; 2: 1000mbps; 1: 100mbps; 0: 10mbps */
90     config->auto_negotiation = 1; /* Enable Auto-Negotiation */
91     config->duplex_mode      = 1; /* Full duplex mode */
92 }
93 
dp83867_basic_mode_init(ENET_Type * ptr,dp83867_config_t * config)94 bool dp83867_basic_mode_init(ENET_Type *ptr, dp83867_config_t *config)
95 {
96     uint16_t para = 0;
97 
98     para |= DP83867_BMCR_RESET_SET(0)                        /* Normal operation */
99          |  DP83867_BMCR_LOOPBACK_SET(config->loopback)      /* Configure PCS loopback mode */
100          |  DP83867_BMCR_ANE_SET(config->auto_negotiation)   /* Configure Auto-Negotiation */
101          |  DP83867_BMCR_PWD_SET(0)                          /* Normal operation */
102          |  DP83867_BMCR_ISOLATE_SET(0)                      /* Normal operation */
103          |  DP83867_BMCR_RESTART_AN_SET(0)                   /* Normal operation (ignored when Auto-Negotiation is disabled) */
104          |  DP83867_BMCR_DUPLEX_SET(config->duplex_mode)     /* Config duplex mode */
105          |  DP83867_BMCR_COLLISION_TEST_SET(0);              /* Normal operation */
106 
107     if (config->auto_negotiation == false) {
108         para |= DP83867_BMCR_SPEED0_SET(config->speed) | DP83867_BMCR_SPEED1_SET(config->speed >> 1);
109     }
110 
111     /* check the id of dp83867 */
112     if (dp83867_id_check(ptr) == false) {
113         return false;
114     }
115 
116     while (dp83867_get_phy_link_status(ptr) == 0) {
117 
118     }
119 
120     return true;
121 }
122 
dp83867_init_auto_negotiation(void)123 void dp83867_init_auto_negotiation(void)
124 {
125 
126 }
127 
dp83867_get_phy_link_status(ENET_Type * ptr)128 uint16_t dp83867_get_phy_link_status(ENET_Type *ptr)
129 {
130     return DP83867_BMSR_LINK_STATUS_GET(enet_read_phy(ptr, PHY_ADDR, DP83867_REG_BMSR));
131 }
132 
dp83867_set_rgmii_rx_delay(ENET_Type * ptr,uint32_t phy_addr,uint8_t delay)133 void dp83867_set_rgmii_rx_delay(ENET_Type *ptr, uint32_t phy_addr, uint8_t delay)
134 {
135     dp83867_phy_write_ext(ptr, phy_addr, DP83867_EXT_REG_RGMIIDCTL, delay);
136 }
137 
dp83867_get_rgmii_rx_delay(ENET_Type * ptr,uint32_t phy_addr)138 uint16_t dp83867_get_rgmii_rx_delay(ENET_Type *ptr, uint32_t phy_addr)
139 {
140     uint16_t temp = 0;
141 
142     temp = dp83867_phy_read_ext(ptr, phy_addr, DP83867_EXT_REG_RGMIIDCTL);
143 
144     return temp;
145 }
146 
dp83867_set_rx_clk_delay(ENET_Type * ptr)147 void dp83867_set_rx_clk_delay(ENET_Type *ptr)
148 {
149     uint16_t para = 0;
150 
151     para = dp83867_phy_read_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RGMIICTL);
152     dp83867_phy_write_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RGMIICTL, para | 1);
153 }
154 
dp83867_enable_crc_check(ENET_Type * ptr)155 void dp83867_enable_crc_check(ENET_Type *ptr)
156 {
157     uint16_t para = 0;
158 
159     para = dp83867_phy_read_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RXFCFG);
160     dp83867_phy_write_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RXFCFG, para | (1 << 7));
161 }
162 
dp83867_enable_rmii_inf(ENET_Type * ptr)163 void dp83867_enable_rmii_inf(ENET_Type *ptr)
164 {
165     uint16_t para = 0;
166 
167     para = dp83867_phy_read_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RGMIICTL);
168     dp83867_phy_write_ext(ptr, PHY_ADDR, DP83867_EXT_REG_RGMIICTL, para | (1 << 7));
169 }
170