|
16 | 16 | #include <esp_mac.h>
|
17 | 17 | #include <hal/emac_hal.h>
|
18 | 18 | #include <hal/emac_ll.h>
|
| 19 | +#include <soc/rtc.h> |
| 20 | +#include <clk_ctrl_os.h> |
19 | 21 |
|
20 | 22 | LOG_MODULE_REGISTER(mdio_esp32, CONFIG_MDIO_LOG_LEVEL);
|
21 | 23 |
|
@@ -86,6 +88,35 @@ static int mdio_esp32_write(const struct device *dev, uint8_t prtad,
|
86 | 88 | return mdio_transfer(dev, prtad, regad, true, data, NULL);
|
87 | 89 | }
|
88 | 90 |
|
| 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 | + |
89 | 120 | static int mdio_esp32_initialize(const struct device *dev)
|
90 | 121 | {
|
91 | 122 | const struct mdio_esp32_dev_config *const cfg = dev->config;
|
@@ -113,6 +144,24 @@ static int mdio_esp32_initialize(const struct device *dev)
|
113 | 144 | /* Only the mac registers are required for MDIO */
|
114 | 145 | dev_data->hal.mac_regs = &EMAC_MAC;
|
115 | 146 |
|
| 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 | + |
116 | 165 | /* Init MDIO clock */
|
117 | 166 | emac_hal_set_csr_clock_range(&dev_data->hal, esp_clk_apb_freq());
|
118 | 167 |
|
|
0 commit comments