diff options
-rw-r--r-- | target/linux/ramips/dts/mt7628an.dtsi | 4 | ||||
-rw-r--r-- | target/linux/ramips/dts/rt3050.dtsi | 4 | ||||
-rw-r--r-- | target/linux/ramips/dts/rt3352.dtsi | 4 | ||||
-rw-r--r-- | target/linux/ramips/dts/rt5350.dtsi | 4 | ||||
-rw-r--r-- | target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c | 44 |
5 files changed, 45 insertions, 15 deletions
diff --git a/target/linux/ramips/dts/mt7628an.dtsi b/target/linux/ramips/dts/mt7628an.dtsi index d622aa9077..9bf20cecdd 100644 --- a/target/linux/ramips/dts/mt7628an.dtsi +++ b/target/linux/ramips/dts/mt7628an.dtsi @@ -439,8 +439,8 @@ compatible = "mediatek,mt7628-esw", "ralink,rt3050-esw"; reg = <0x10110000 0x8000>; - resets = <&rstctrl 23>; - reset-names = "esw"; + resets = <&rstctrl 23 &rstctrl 24>; + reset-names = "esw", "ephy"; interrupt-parent = <&intc>; interrupts = <17>; diff --git a/target/linux/ramips/dts/rt3050.dtsi b/target/linux/ramips/dts/rt3050.dtsi index 0cecd5d8cf..492474fdc4 100644 --- a/target/linux/ramips/dts/rt3050.dtsi +++ b/target/linux/ramips/dts/rt3050.dtsi @@ -319,8 +319,8 @@ compatible = "ralink,rt3050-esw"; reg = <0x10110000 0x8000>; - resets = <&rstctrl 23>; - reset-names = "esw"; + resets = <&rstctrl 23 &rstctrl 24>; + reset-names = "esw", "ephy"; interrupt-parent = <&intc>; interrupts = <17>; diff --git a/target/linux/ramips/dts/rt3352.dtsi b/target/linux/ramips/dts/rt3352.dtsi index 84d6ed5905..608222cb5c 100644 --- a/target/linux/ramips/dts/rt3352.dtsi +++ b/target/linux/ramips/dts/rt3352.dtsi @@ -331,8 +331,8 @@ compatible = "ralink,rt3352-esw", "ralink,rt3050-esw"; reg = <0x10110000 0x8000>; - resets = <&rstctrl 23>; - reset-names = "esw"; + resets = <&rstctrl 23 &rstctrl 24>; + reset-names = "esw", "ephy"; interrupt-parent = <&intc>; interrupts = <17>; diff --git a/target/linux/ramips/dts/rt5350.dtsi b/target/linux/ramips/dts/rt5350.dtsi index ac4c6d9db2..1058069016 100644 --- a/target/linux/ramips/dts/rt5350.dtsi +++ b/target/linux/ramips/dts/rt5350.dtsi @@ -356,8 +356,8 @@ compatible = "ralink,rt5350-esw", "ralink,rt3050-esw"; reg = <0x10110000 0x8000>; - resets = <&rstctrl 23>; - reset-names = "esw"; + resets = <&rstctrl 23 &rstctrl 24>; + reset-names = "esw", "ephy"; interrupt-parent = <&intc>; interrupts = <17>; diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c index 292f11a170..cd6ae07595 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c @@ -17,9 +17,11 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <asm/mach-ralink/ralink_regs.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/switch.h> +#include <linux/reset.h> #include "mtk_eth_soc.h" @@ -172,7 +174,6 @@ #define RT5350_ESW_REG_PXTPC(_x) (0x150 + (4 * _x)) #define RT5350_EWS_REG_LED_POLARITY 0x168 -#define RT5350_RESET_EPHY BIT(24) enum { /* Global attributes. */ @@ -232,6 +233,8 @@ struct rt305x_esw { int led_frequency; struct esw_vlan vlans[RT305X_ESW_NUM_VLANS]; struct esw_port ports[RT305X_ESW_NUM_PORTS]; + struct reset_control *rst_esw; + struct reset_control *rst_ephy; }; @@ -254,6 +257,29 @@ static inline void esw_rmw_raw(struct rt305x_esw *esw, unsigned reg, __raw_writel(t | val, esw->base + reg); } +static void esw_reset(struct rt305x_esw *esw) +{ + if (!esw->rst_esw) + return; + + reset_control_assert(esw->rst_esw); + usleep_range(60, 120); + reset_control_deassert(esw->rst_esw); + /* the esw takes long to reset otherwise the board hang */ + msleep(10); +} + +static void esw_reset_ephy(struct rt305x_esw *esw) +{ + if (!esw->rst_ephy) + return; + + reset_control_assert(esw->rst_ephy); + usleep_range(60, 120); + reset_control_deassert(esw->rst_ephy); + usleep_range(60, 120); +} + static void esw_rmw(struct rt305x_esw *esw, unsigned reg, unsigned long mask, unsigned long val) { @@ -505,8 +531,7 @@ static void esw_hw_init(struct rt305x_esw *esw) esw->ports[i].disable = (port_disable & (1 << i)) != 0; if (ralink_soc == RT305X_SOC_RT3352) { - /* reset EPHY */ - fe_reset(RT5350_RESET_EPHY); + esw_reset_ephy(esw); rt305x_mii_write(esw, 0, 31, 0x8000); for (i = 0; i < 5; i++) { @@ -556,8 +581,7 @@ static void esw_hw_init(struct rt305x_esw *esw) /* select local register */ rt305x_mii_write(esw, 0, 31, 0x8000); } else if (ralink_soc == RT305X_SOC_RT5350) { - /* reset EPHY */ - fe_reset(RT5350_RESET_EPHY); + esw_reset_ephy(esw); /* set the led polarity */ esw_w32(esw, esw->reg_led_polarity & 0x1F, @@ -614,8 +638,7 @@ static void esw_hw_init(struct rt305x_esw *esw) } else if (ralink_soc == MT762X_SOC_MT7628AN || ralink_soc == MT762X_SOC_MT7688) { int i; - /* reset EPHY */ - fe_reset(RT5350_RESET_EPHY); + esw_reset_ephy(esw); /* set the led polarity */ esw_w32(esw, esw->reg_led_polarity & 0x1F, @@ -1385,6 +1408,13 @@ static int esw_probe(struct platform_device *pdev) if (reg_init) esw->reg_led_polarity = be32_to_cpu(*reg_init); + esw->rst_esw = devm_reset_control_get(&pdev->dev, "esw"); + if (IS_ERR(esw->rst_esw)) + esw->rst_esw = NULL; + esw->rst_ephy = devm_reset_control_get(&pdev->dev, "ephy"); + if (IS_ERR(esw->rst_ephy)) + esw->rst_ephy = NULL; + swdev = &esw->swdev; swdev->of_node = pdev->dev.of_node; swdev->name = "rt305x-esw"; |