Skip to content

Commit 0207c62

Browse files
committed
drivers: mdio_esp32: let the REF_CLK be initialized before the PHY.
When GPIO17 or 16 is used as an external REF_CLK signal, the output is enabled in eth_esp32.c This was added in PR number zephyrproject-rtos#65759 and then refined in PR zephyrproject-rtos#74442. However this does not work for PHYs which need the REF_CLK for MDIO communication, such as LAN8720A. In such cases phy_mii driver tries to get the ID of such a PHY before REF_CLK is present. Therefore in this PR I propose to move REF_CLK initialization from eth_esp32.c to mdio_esp32.c which gets initialized before PHY and ETH. Signed-off-by: Łukasz Iwaszkiewicz <[email protected]>
1 parent de69ebd commit 0207c62

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

drivers/mdio/mdio_esp32.c

+49
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <esp_mac.h>
1717
#include <hal/emac_hal.h>
1818
#include <hal/emac_ll.h>
19+
#include <soc/rtc.h>
20+
#include <clk_ctrl_os.h>
1921

2022
LOG_MODULE_REGISTER(mdio_esp32, CONFIG_MDIO_LOG_LEVEL);
2123

@@ -86,6 +88,35 @@ static int mdio_esp32_write(const struct device *dev, uint8_t prtad,
8688
return mdio_transfer(dev, prtad, regad, true, data, NULL);
8789
}
8890

91+
#if DT_INST_NODE_HAS_PROP(0, ref_clk_output_gpios)
92+
static int emac_config_apll_clock(void)
93+
{
94+
uint32_t expt_freq = MHZ(50);
95+
uint32_t real_freq = 0;
96+
esp_err_t ret = periph_rtc_apll_freq_set(expt_freq, &real_freq);
97+
98+
if (ret == ESP_ERR_INVALID_ARG) {
99+
LOG_ERR("Set APLL clock coefficients failed");
100+
return -EIO;
101+
}
102+
103+
if (ret == ESP_ERR_INVALID_STATE) {
104+
LOG_INF("APLL is occupied already, it is working at %d Hz", real_freq);
105+
}
106+
107+
/* If the difference of real APLL frequency
108+
* is not within 50 ppm, i.e. 2500 Hz,
109+
* the APLL is unavailable
110+
*/
111+
if (abs((int)real_freq - (int)expt_freq) > 2500) {
112+
LOG_ERR("The APLL is working at an unusable frequency");
113+
return -EIO;
114+
}
115+
116+
return 0;
117+
}
118+
#endif
119+
89120
static int mdio_esp32_initialize(const struct device *dev)
90121
{
91122
const struct mdio_esp32_dev_config *const cfg = dev->config;
@@ -113,6 +144,24 @@ static int mdio_esp32_initialize(const struct device *dev)
113144
/* Only the mac registers are required for MDIO */
114145
dev_data->hal.mac_regs = &EMAC_MAC;
115146

147+
#if DT_INST_NODE_HAS_PROP(0, ref_clk_output_gpios)
148+
emac_hal_init(&dev_data->hal, NULL, NULL, NULL);
149+
emac_hal_iomux_init_rmii();
150+
BUILD_ASSERT(DT_INST_GPIO_PIN(0, ref_clk_output_gpios) == 16 ||
151+
DT_INST_GPIO_PIN(0, ref_clk_output_gpios) == 17,
152+
"Only GPIO16/17 are allowed as a GPIO REF_CLK source!");
153+
int ref_clk_gpio = DT_INST_GPIO_PIN(0, ref_clk_output_gpios);
154+
155+
emac_hal_iomux_rmii_clk_output(ref_clk_gpio);
156+
emac_ll_clock_enable_rmii_output(dev_data->hal.ext_regs);
157+
periph_rtc_apll_acquire();
158+
res = emac_config_apll_clock();
159+
if (res != 0) {
160+
goto err;
161+
}
162+
rtc_clk_apll_enable(true);
163+
#endif
164+
116165
/* Init MDIO clock */
117166
emac_hal_set_csr_clock_range(&dev_data->hal, esp_clk_apb_freq());
118167

dts/bindings/mdio/espressif,esp32-mdio.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,9 @@ compatible: "espressif,esp32-mdio"
88
include:
99
- name: mdio-controller.yaml
1010
- name: pinctrl-device.yaml
11+
12+
properties:
13+
ref-clk-output-gpios:
14+
type: phandle-array
15+
description: |
16+
GPIO to output RMII Clock.

0 commit comments

Comments
 (0)