Merge "net: stmmac: SDx55 EMAC HW configuration changes"

This commit is contained in:
qctecmdr 2021-03-03 22:36:25 -08:00 • committed by Gerrit - the friendly Code Review server
commit 9bef368bcd
4 changed files with 288 additions and 79 deletions

View file

@ -18,6 +18,7 @@ obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o
obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-gpio.o
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o
obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o
obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o

View file

@ -6,16 +6,12 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/regulator/consumer.h>
#include "stmmac.h"
#include "stmmac_platform.h"
#include "dwmac-qcom-ethqos.h"
#define RGMII_IO_MACRO_CONFIG 0x0
#define SDCC_HC_REG_DLL_CONFIG 0x4
#define SDCC_HC_REG_DDR_CONFIG 0xC
#define SDCC_HC_REG_DLL_CONFIG2 0x10
#define SDC4_STATUS 0x14
#define SDCC_USR_CTL 0x18
#define RGMII_IO_MACRO_CONFIG2 0x1C
#define RGMII_IO_MACRO_DEBUG1 0x20
#define EMAC_SYSTEM_LOW_POWER_DEBUG 0x28
@ -70,27 +66,8 @@
#define RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL BIT(6)
#define RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN BIT(5)
struct ethqos_emac_por {
unsigned int offset;
unsigned int value;
};
struct ethqos_emac_driver_data {
const struct ethqos_emac_por *por;
unsigned int num_por;
};
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
unsigned int rgmii_clk_rate;
struct clk *rgmii_clk;
unsigned int speed;
const struct ethqos_emac_por *por;
unsigned int num_por;
};
#define EMAC_I0_EMAC_CORE_HW_VERSION_RGOFFADDR 0x00000070
#define EMAC_HW_v2_3_2_RG 0x20030002
static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
{
@ -167,28 +144,18 @@ static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos)
RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG);
}
static const struct ethqos_emac_por emac_v2_3_0_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x00C01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642C },
{ .offset = SDCC_HC_REG_DDR_CONFIG, .value = 0x00000000 },
{ .offset = SDCC_HC_REG_DLL_CONFIG2, .value = 0x00200000 },
{ .offset = SDCC_USR_CTL, .value = 0x00010800 },
{ .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 },
};
static const struct ethqos_emac_driver_data emac_v2_3_0_data = {
.por = emac_v2_3_0_por,
.num_por = ARRAY_SIZE(emac_v2_3_0_por),
};
static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
{
unsigned int val;
int retry = 1000;
/* Set CDR_EN */
rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EN,
SDCC_DLL_CONFIG_CDR_EN, SDCC_HC_REG_DLL_CONFIG);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EN,
0, SDCC_HC_REG_DLL_CONFIG);
else
rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EN,
SDCC_DLL_CONFIG_CDR_EN, SDCC_HC_REG_DLL_CONFIG);
/* Set CDR_EXT_EN */
rgmii_updatel(ethqos, SDCC_DLL_CONFIG_CDR_EXT_EN,
@ -202,12 +169,13 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
rgmii_updatel(ethqos, SDCC_DLL_CONFIG_DLL_EN,
SDCC_DLL_CONFIG_DLL_EN, SDCC_HC_REG_DLL_CONFIG);
rgmii_updatel(ethqos, SDCC_DLL_MCLK_GATING_EN,
0, SDCC_HC_REG_DLL_CONFIG);
rgmii_updatel(ethqos, SDCC_DLL_CDR_FINE_PHASE,
0, SDCC_HC_REG_DLL_CONFIG);
if (ethqos->emac_ver != EMAC_HW_v2_3_2_RG) {
rgmii_updatel(ethqos, SDCC_DLL_MCLK_GATING_EN,
0, SDCC_HC_REG_DLL_CONFIG);
rgmii_updatel(ethqos, SDCC_DLL_CDR_FINE_PHASE,
0, SDCC_HC_REG_DLL_CONFIG);
}
/* Wait for CK_OUT_EN clear */
do {
val = rgmii_readl(ethqos, SDCC_HC_REG_DLL_CONFIG);
@ -241,18 +209,20 @@ static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_CAL_EN,
SDCC_DLL_CONFIG2_DDR_CAL_EN, SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DLL_CLOCK_DIS,
0, SDCC_HC_REG_DLL_CONFIG2);
if (ethqos->emac_ver != EMAC_HW_v2_3_2_RG) {
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DLL_CLOCK_DIS,
0, SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_MCLK_FREQ_CALC,
0x1A << 10, SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_MCLK_FREQ_CALC,
0x1A << 10, SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL,
BIT(2), SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SEL,
BIT(2), SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
SDCC_HC_REG_DLL_CONFIG2);
rgmii_updatel(ethqos, SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
SDCC_DLL_CONFIG2_DDR_TRAFFIC_INIT_SW,
SDCC_HC_REG_DLL_CONFIG2);
}
return 0;
}
@ -290,13 +260,22 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
RGMII_IO_MACRO_CONFIG2);
/* Set PRG_RCLK_DLY to 57 for 1.8 ns delay */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
57, SDCC_HC_REG_DDR_CONFIG);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
69, SDCC_HC_REG_DDR_CONFIG);
else
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_RCLK_DLY,
57, SDCC_HC_REG_DDR_CONFIG);
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_PRG_DLY_EN,
SDCC_DDR_CONFIG_PRG_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
0, RGMII_IO_MACRO_CONFIG);
else
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN,
RGMII_IO_MACRO_CONFIG);
break;
case SPEED_100:
@ -318,8 +297,13 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
BIT(6), RGMII_IO_MACRO_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
else
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
(BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
@ -329,8 +313,13 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
0, RGMII_IO_MACRO_CONFIG);
else
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN,
RGMII_IO_MACRO_CONFIG);
break;
case SPEED_10:
@ -345,15 +334,27 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
0, RGMII_IO_MACRO_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG2_DATA_DIVIDE_CLK_SEL,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
0, RGMII_IO_MACRO_CONFIG2);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos,
RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
RGMII_IO_MACRO_CONFIG2);
else
rgmii_updatel(ethqos,
RGMII_CONFIG2_TX_CLK_PHASE_SHIFT_EN,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9,
BIT(12) | GENMASK(9, 8),
RGMII_IO_MACRO_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
0, RGMII_IO_MACRO_CONFIG2);
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_CONFIG2_RX_PROG_SWAP,
RGMII_IO_MACRO_CONFIG2);
else
rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
0, RGMII_IO_MACRO_CONFIG2);
/* Write 0x5 to PRG_RCLK_DLY_CODE */
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
(BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
@ -363,8 +364,13 @@ static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_EN,
SDCC_HC_REG_DDR_CONFIG);
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN, RGMII_IO_MACRO_CONFIG);
if (ethqos->emac_ver == EMAC_HW_v2_3_2_RG)
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
0, RGMII_IO_MACRO_CONFIG);
else
rgmii_updatel(ethqos, RGMII_CONFIG_LOOPBACK_EN,
RGMII_CONFIG_LOOPBACK_EN,
RGMII_IO_MACRO_CONFIG);
break;
default:
dev_err(&ethqos->pdev->dev,
@ -461,19 +467,21 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (ret)
return ret;
ethqos = devm_kzalloc(&pdev->dev, sizeof(*ethqos), GFP_KERNEL);
if (!ethqos) {
ret = -ENOMEM;
goto err_mem;
}
ethqos->pdev = pdev;
ethqos_init_reqgulators(ethqos);
plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
if (IS_ERR(plat_dat)) {
dev_err(&pdev->dev, "dt configuration failed\n");
return PTR_ERR(plat_dat);
}
ethqos = devm_kzalloc(&pdev->dev, sizeof(*ethqos), GFP_KERNEL);
if (!ethqos) {
ret = -ENOMEM;
goto err_mem;
}
ethqos->pdev = pdev;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rgmii");
ethqos->rgmii_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(ethqos->rgmii_base)) {
@ -510,6 +518,9 @@ static int qcom_ethqos_probe(struct platform_device *pdev)
if (ret)
goto err_clk;
ethqos->emac_ver = rgmii_readl(ethqos,
EMAC_I0_EMAC_CORE_HW_VERSION_RGOFFADDR);
rgmii_dump(ethqos);
return ret;
@ -534,12 +545,14 @@ static int qcom_ethqos_remove(struct platform_device *pdev)
ret = stmmac_pltfr_remove(pdev);
clk_disable_unprepare(ethqos->rgmii_clk);
ethqos_disable_regulators(ethqos);
return ret;
}
static const struct of_device_id qcom_ethqos_match[] = {
{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_por},
{ .compatible = "qcom,sdxprairie-ethqos", .data = &emac_v2_3_2_por},
{ }
};
MODULE_DEVICE_TABLE(of, qcom_ethqos_match);

View file

@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#ifndef _DWMAC_QCOM_ETHQOS_H
#define _DWMAC_QCOM_ETHQOS_H
#define DRV_NAME "qcom-ethqos"
#define ETHQOSDBG(fmt, args...) \
pr_debug(DRV_NAME " %s:%d " fmt, __func__, ## args)
#define ETHQOSERR(fmt, args...) \
pr_err(DRV_NAME " %s:%d " fmt, __func__, ## args)
#define ETHQOSINFO(fmt, args...) \
pr_info(DRV_NAME " %s:%d " fmt, __func__, ## args)
#define RGMII_IO_MACRO_CONFIG 0x0
#define SDCC_HC_REG_DLL_CONFIG 0x4
#define SDCC_HC_REG_DDR_CONFIG 0xC
#define SDCC_HC_REG_DLL_CONFIG2 0x10
#define SDC4_STATUS 0x14
#define SDCC_USR_CTL 0x18
#define RGMII_IO_MACRO_CONFIG2 0x1C
struct ethqos_emac_por {
unsigned int offset;
unsigned int value;
};
static const struct ethqos_emac_por emac_v2_3_0_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x00C01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642C },
{ .offset = SDCC_HC_REG_DDR_CONFIG, .value = 0x00000000 },
{ .offset = SDCC_HC_REG_DLL_CONFIG2, .value = 0x00200000 },
{ .offset = SDCC_USR_CTL, .value = 0x00010800 },
{ .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 },
};
static const struct ethqos_emac_por emac_v2_3_2_por[] = {
{ .offset = RGMII_IO_MACRO_CONFIG, .value = 0x00C01343 },
{ .offset = SDCC_HC_REG_DLL_CONFIG, .value = 0x2004642C },
{ .offset = SDCC_HC_REG_DDR_CONFIG, .value = 0x80040800 },
{ .offset = SDCC_HC_REG_DLL_CONFIG2, .value = 0x00200000 },
{ .offset = SDCC_USR_CTL, .value = 0x00010800 },
{ .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 },
};
struct qcom_ethqos {
struct platform_device *pdev;
void __iomem *rgmii_base;
unsigned int rgmii_clk_rate;
struct clk *rgmii_clk;
unsigned int speed;
const struct ethqos_emac_por *por;
unsigned int num_por;
unsigned int emac_ver;
struct regulator *gdsc_emac;
struct regulator *reg_rgmii;
struct regulator *reg_emac_phy;
struct regulator *reg_rgmii_io_pads;
};
int ethqos_init_reqgulators(struct qcom_ethqos *ethqos);
void ethqos_disable_regulators(struct qcom_ethqos *ethqos);
#endif

View file

@ -0,0 +1,129 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/regulator/consumer.h>
#include "stmmac.h"
#include "dwmac-qcom-ethqos.h"
#define EMAC_GDSC_EMAC_NAME "gdsc_emac"
#define EMAC_VREG_RGMII_NAME "vreg_rgmii"
#define EMAC_VREG_EMAC_PHY_NAME "vreg_emac_phy"
#define EMAC_VREG_RGMII_IO_PADS_NAME "vreg_rgmii_io_pads"
int ethqos_init_reqgulators(struct qcom_ethqos *ethqos)
{
int ret = 0;
if (of_property_read_bool(ethqos->pdev->dev.of_node,
"gdsc_emac-supply")) {
ethqos->gdsc_emac =
devm_regulator_get(&ethqos->pdev->dev, EMAC_GDSC_EMAC_NAME);
if (IS_ERR(ethqos->gdsc_emac)) {
ETHQOSERR("Can not get <%s>\n", EMAC_GDSC_EMAC_NAME);
return PTR_ERR(ethqos->gdsc_emac);
}
ret = regulator_enable(ethqos->gdsc_emac);
if (ret) {
ETHQOSERR("Can not enable <%s>\n", EMAC_GDSC_EMAC_NAME);
goto reg_error;
}
ETHQOSDBG("Enabled <%s>\n", EMAC_GDSC_EMAC_NAME);
}
if (of_property_read_bool(ethqos->pdev->dev.of_node,
"vreg_rgmii-supply")) {
ethqos->reg_rgmii =
devm_regulator_get(&ethqos->pdev->dev, EMAC_VREG_RGMII_NAME);
if (IS_ERR(ethqos->reg_rgmii)) {
ETHQOSERR("Can not get <%s>\n", EMAC_VREG_RGMII_NAME);
return PTR_ERR(ethqos->reg_rgmii);
}
ret = regulator_enable(ethqos->reg_rgmii);
if (ret) {
ETHQOSERR("Can not enable <%s>\n",
EMAC_VREG_RGMII_NAME);
goto reg_error;
}
ETHQOSDBG("Enabled <%s>\n", EMAC_VREG_RGMII_NAME);
}
if (of_property_read_bool(ethqos->pdev->dev.of_node,
"vreg_emac_phy-supply")) {
ethqos->reg_emac_phy =
devm_regulator_get(&ethqos->pdev->dev, EMAC_VREG_EMAC_PHY_NAME);
if (IS_ERR(ethqos->reg_emac_phy)) {
ETHQOSERR("Can not get <%s>\n",
EMAC_VREG_EMAC_PHY_NAME);
return PTR_ERR(ethqos->reg_emac_phy);
}
ret = regulator_enable(ethqos->reg_emac_phy);
if (ret) {
ETHQOSERR("Can not enable <%s>\n",
EMAC_VREG_EMAC_PHY_NAME);
goto reg_error;
}
ETHQOSDBG("Enabled <%s>\n", EMAC_VREG_EMAC_PHY_NAME);
}
if (of_property_read_bool(ethqos->pdev->dev.of_node,
"vreg_rgmii_io_pads-supply")) {
ethqos->reg_rgmii_io_pads = devm_regulator_get
(&ethqos->pdev->dev, EMAC_VREG_RGMII_IO_PADS_NAME);
if (IS_ERR(ethqos->reg_rgmii_io_pads)) {
ETHQOSERR("Can not get <%s>\n",
EMAC_VREG_RGMII_IO_PADS_NAME);
return PTR_ERR(ethqos->reg_rgmii_io_pads);
}
ret = regulator_enable(ethqos->reg_rgmii_io_pads);
if (ret) {
ETHQOSERR("Can not enable <%s>\n",
EMAC_VREG_RGMII_IO_PADS_NAME);
goto reg_error;
}
ETHQOSDBG("Enabled <%s>\n", EMAC_VREG_RGMII_IO_PADS_NAME);
}
return ret;
reg_error:
ETHQOSERR("%s failed\n", __func__);
ethqos_disable_regulators(ethqos);
return ret;
}
void ethqos_disable_regulators(struct qcom_ethqos *ethqos)
{
if (ethqos->reg_rgmii) {
regulator_disable(ethqos->reg_rgmii);
ethqos->reg_rgmii = NULL;
}
if (ethqos->reg_emac_phy) {
regulator_disable(ethqos->reg_emac_phy);
ethqos->reg_emac_phy = NULL;
}
if (ethqos->reg_rgmii_io_pads) {
regulator_disable(ethqos->reg_rgmii_io_pads);
ethqos->reg_rgmii_io_pads = NULL;
}
if (ethqos->gdsc_emac) {
regulator_disable(ethqos->gdsc_emac);
ethqos->gdsc_emac = NULL;
}
}