mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "net: stmmac: SDx55 EMAC HW configuration changes"
This commit is contained in:
commit
9bef368bcd
4 changed files with 288 additions and 79 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(ðqos->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);
|
||||
|
|
|
|||
66
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h
Normal file
66
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.h
Normal 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
|
||||
129
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-gpio.c
Normal file
129
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-gpio.c
Normal 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(ðqos->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(ðqos->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(ðqos->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
|
||||
(ðqos->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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue