Commit c8f5d298 authored by David S. Miller's avatar David S. Miller

Merge branch 'arc_emac-next'

Caesar Wang says:

====================
arc_emac: fixes the emac issues and cleanup emac drivers

This series patches are based on kernel 4.5-rc7+ version.
Linux version 4.5.0-rc7-next-20160311+ (wxt@nb) (...) #45 SMP Sun Mar 13 16:17:56

The history patch in here:
Patch-v1: https://lkml.org/lkml/2016/3/11/209
Patch-v2: https://lkml.org/lkml/2016/3/13/39

Verified on kylin board with my github.
https://github.com/Caesar-github/rockchip/tree/kylin/next

That's verified on kylin board with ubuntu os.

This series patches are built all pass with Mr.robot on
https://github.com/Caesar-github/linux/tree/build-emac-v3

How to test and verify?

You can refer to the following wiki document.
http://rockchip.wikidot.com/linux-develop-guide

bootup log:
[    1.264740] rockchip_emac 10200000.ethernet: no regulator found
[    1.270908] rockchip_emac 10200000.ethernet: ARC EMAC detected with id: 0x7fd02
[    1.278362] rockchip_emac 10200000.ethernet: IRQ is 29
[    1.283747] rockchip_emac 10200000.ethernet: MAC address is now 06:5d:61:c7:39:41
[    1.291314] rockchip_emac 10200000.ethernet: GPIO lookup for consumer phy-reset
[    1.291333] rockchip_emac 10200000.ethernet: using device tree for GPIO lookup
[    1.663155] rockchip_emac 10200000.ethernet: connected to Generic PHY phy with id 0xffffc816
[    8.863448] rockchip_emac 10200000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off

root@localhost:/# busybox ping www.baidu.com
PING www.baidu.com (14.215.177.38): 56 data bytes
64 bytes from 14.215.177.38: seq=0 ttl=48 time=35.046 ms
64 bytes from 14.215.177.38: seq=1 ttl=48 time=35.095 ms
64 bytes from 14.215.177.38: seq=2 ttl=48 time=34.203 ms
64 bytes from 14.215.177.38: seq=3 ttl=48 time=38.516 ms
...
---

1) This series has 6 patches: (1--->9)
net: arc_emac: make the rockchip emac document more compatible
net: arc_emac: add phy reset is optional for device tree
net: arc_emac: support the phy reset for emac driver
net: arc: trivial: cleanup the emac driver
clk: rockchip: add node-id for rk3036 emac hclk
clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
clk: rockchip: add clock-id for rk3036 emac pll source clock
clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on rk3036
ARM: dts: rockchip: add support emac for RK3036

2) This series patches have the following descriptions:

Hi Rob, David:
PATCH[1/9-2/9]: ====>
net: arc_emac: make the rockchip emac document more compatible
net: arc_emac: add phy reset is optional for device tree

The patches change the rockchip emac document for more compatible and
Add the phy reset property for document.
---

Hi David
PATCH[3/9]: ====>
net: arc_emac: support the phy reset for emac driver

The emac didn't work on kylin board since in some case the clocks parent changed.
The kylin hardware connects the phy reset pin, we should use it with real world.
As the previous patch discuss on https://patchwork.kernel.org/patch/8186801/

And as sergei/Heiko suggestions on
https://patchwork.kernel.org/patch/8564571/
---

Hi David
PATCH[4/9]: ====>
net: arc: trivial: cleanup the emac driver

The first time to look the emac drivers, I think that have to cleanup the drivers with scripts.
Although it's the trivial things, in order to be more read.
---

Hi Heiko,Michael,Stephen:
PATCH[5/9-8/9]: ====> clk: rockchip: rk3036: fix and add node id for emac clock

Four-part from https://patchwork.kernel.org/patch/8564581/
clk: rockchip: add node-id for rk3036 emac hclk
clk: rockchip: associate the rk3036 HCLK_EMAC clock-id
clk: rockchip: add clock-id for rk3036 emac pll source clock
clk: rockchip: associate SCLK_MAC_PLL and disable reparenting on rk3036

Add the emac needed clocks for rk3036 SoCs
---

Hi Heiko:
PATCH[9/9]: ====>
ARM: dts: rockchip: add support emac for RK3036

Add the emac needed main info for rk3036 dts.
---

Thanks your reviewing! :)

Changes in v3:
- %s/he/the
- Add the Cc people
- As Sergei comments, the original name is better, so
  %s/reset-gpios/phy-reset-gpios
- Add the Cc people.
- Caused the build error since the missing include head file.
- %s/reset/phy-reset to match the device tree.
- Add the Cc people
- Add the Cc people.
- Add the Cc people.
- Add the Cc people.
- Add the Cc people.
- Add the Cc people.
- rename reset-gpio to phy-reset-gpios.
- change the commit.
- remove the pcfg_output_high, that's really not needed for emac.
- Add the Cc people.
- Fixes the 'zhengxing' to 'Xing Zheng'.

Changes in v2:
- change the commit and remove the repeat the name 'rockchip'.
- %s/phy-reset-gpios/reset-gpios
- As the pervious version, Sergei and Heiko comments on
  https://patchwork.kernel.org/patch/8564571/.
- Nevermind, add signed-off since Heiko the original patch,
  refer the Heiko's test patch on
  https://github.com/mmind/linux-rockchip/commit/a943c588783438ff1c508dfa8c79f1709aa5775e
  :)
- As the robot notice the build error since overflow in implicit
  constant conversion.
- rename phy-reset-gpio to reset-gpios.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 793cf87d af671e7b
...@@ -7,6 +7,13 @@ Required properties: ...@@ -7,6 +7,13 @@ Required properties:
- max-speed: see ethernet.txt file in the same directory. - max-speed: see ethernet.txt file in the same directory.
- phy: see ethernet.txt file in the same directory. - phy: see ethernet.txt file in the same directory.
Optional properties:
- phy-reset-gpios : Should specify the gpio for phy reset
- phy-reset-duration : Reset duration in milliseconds. Should present
only if property "phy-reset-gpios" is available. Missing the property
will have the duration be 1 millisecond. Numbers greater than 1000 are
invalid and 1 millisecond will be used instead.
Clock handling: Clock handling:
The clock frequency is needed to calculate and set polling period of EMAC. The clock frequency is needed to calculate and set polling period of EMAC.
It must be provided by one of: It must be provided by one of:
......
* ARC EMAC 10/100 Ethernet platform driver for Rockchip Rk3066/RK3188 SoCs * ARC EMAC 10/100 Ethernet platform driver for Rockchip RK3036/RK3066/RK3188 SoCs
Required properties: Required properties:
- compatible: Should be "rockchip,rk3066-emac" or "rockchip,rk3188-emac" - compatible: should be "rockchip,<name>-emac"
according to the target SoC. "rockchip,rk3036-emac": found on RK3036 SoCs
"rockchip,rk3066-emac": found on RK3066 SoCs
"rockchip,rk3188-emac": found on RK3188 SoCs
- reg: Address and length of the register set for the device - reg: Address and length of the register set for the device
- interrupts: Should contain the EMAC interrupts - interrupts: Should contain the EMAC interrupts
- rockchip,grf: phandle to the syscon grf used to control speed and mode - rockchip,grf: phandle to the syscon grf used to control speed and mode
......
...@@ -47,6 +47,20 @@ / { ...@@ -47,6 +47,20 @@ / {
compatible = "rockchip,rk3036-evb", "rockchip,rk3036"; compatible = "rockchip,rk3036-evb", "rockchip,rk3036";
}; };
&emac {
pinctrl-names = "default";
pinctrl-0 = <&emac_xfer>, <&emac_mdio>;
phy = <&phy0>;
phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */
phy-reset-duration = <10>; /* millisecond */
status = "okay";
phy0: ethernet-phy@0 {
reg = <0>;
};
};
&i2c1 { &i2c1 {
status = "okay"; status = "okay";
......
...@@ -60,6 +60,20 @@ &acodec { ...@@ -60,6 +60,20 @@ &acodec {
status = "okay"; status = "okay";
}; };
&emac {
pinctrl-names = "default";
pinctrl-0 = <&emac_xfer>, <&emac_mdio>;
phy = <&phy0>;
phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */
phy-reset-duration = <10>; /* millisecond */
status = "okay";
phy0: ethernet-phy@0 {
reg = <0>;
};
};
&emmc { &emmc {
status = "okay"; status = "okay";
}; };
......
...@@ -186,6 +186,27 @@ usb_host: usb@101c0000 { ...@@ -186,6 +186,27 @@ usb_host: usb@101c0000 {
status = "disabled"; status = "disabled";
}; };
emac: ethernet@10200000 {
compatible = "rockchip,rk3036-emac", "snps,arc-emac";
reg = <0x10200000 0x4000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&grf>;
clocks = <&cru HCLK_MAC>, <&cru SCLK_MACREF>, <&cru SCLK_MAC>;
clock-names = "hclk", "macref", "macclk";
/*
* Fix the emac parent clock is DPLL instead of APLL.
* since that will cause some unstable things if the cpufreq
* is working. (e.g: the accurate 50MHz what mac_ref need)
*/
assigned-clocks = <&cru SCLK_MACPLL>;
assigned-clock-parents = <&cru PLL_DPLL>;
max-speed = <100>;
phy-mode = "rmii";
status = "disabled";
};
sdmmc: dwmmc@10214000 { sdmmc: dwmmc@10214000 {
compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc"; compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x10214000 0x4000>; reg = <0x10214000 0x4000>;
...@@ -556,6 +577,24 @@ emmc_bus8: emmc-bus8 { ...@@ -556,6 +577,24 @@ emmc_bus8: emmc-bus8 {
}; };
}; };
emac {
emac_xfer: emac-xfer {
rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_default>, /* crs_dvalid */
<2 13 RK_FUNC_1 &pcfg_pull_default>, /* tx_en */
<2 14 RK_FUNC_1 &pcfg_pull_default>, /* mac_clk */
<2 15 RK_FUNC_1 &pcfg_pull_default>, /* rx_err */
<2 16 RK_FUNC_1 &pcfg_pull_default>, /* rxd1 */
<2 17 RK_FUNC_1 &pcfg_pull_default>, /* rxd0 */
<2 18 RK_FUNC_1 &pcfg_pull_default>, /* txd1 */
<2 19 RK_FUNC_1 &pcfg_pull_default>; /* txd0 */
};
emac_mdio: emac-mdio {
rockchip,pins = <2 12 RK_FUNC_1 &pcfg_pull_default>, /* mac_md */
<2 25 RK_FUNC_1 &pcfg_pull_default>; /* mac_mdclk */
};
};
i2c0 { i2c0 {
i2c0_xfer: i2c0-xfer { i2c0_xfer: i2c0-xfer {
rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>, rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>,
......
...@@ -343,7 +343,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { ...@@ -343,7 +343,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS, RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS,
RK2928_CLKGATE_CON(10), 5, GFLAGS), RK2928_CLKGATE_CON(10), 5, GFLAGS),
COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0, COMPOSITE_NOGATE(SCLK_MACPLL, "mac_pll_src", mux_pll_src_3plls_p, CLK_SET_RATE_NO_REPARENT,
RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 9, 5, DFLAGS), RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 9, 5, DFLAGS),
MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT, MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT,
RK2928_CLKSEL_CON(21), 3, 1, MFLAGS), RK2928_CLKSEL_CON(21), 3, 1, MFLAGS),
...@@ -404,7 +404,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { ...@@ -404,7 +404,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS),
GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS),
GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS),
GATE(0, "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS), GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS),
/* pclk_peri gates */ /* pclk_peri gates */
GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS),
......
...@@ -14,36 +14,36 @@ ...@@ -14,36 +14,36 @@
#include <linux/clk.h> #include <linux/clk.h>
/* STATUS and ENABLE Register bit masks */ /* STATUS and ENABLE Register bit masks */
#define TXINT_MASK (1<<0) /* Transmit interrupt */ #define TXINT_MASK (1 << 0) /* Transmit interrupt */
#define RXINT_MASK (1<<1) /* Receive interrupt */ #define RXINT_MASK (1 << 1) /* Receive interrupt */
#define ERR_MASK (1<<2) /* Error interrupt */ #define ERR_MASK (1 << 2) /* Error interrupt */
#define TXCH_MASK (1<<3) /* Transmit chaining error interrupt */ #define TXCH_MASK (1 << 3) /* Transmit chaining error interrupt */
#define MSER_MASK (1<<4) /* Missed packet counter error */ #define MSER_MASK (1 << 4) /* Missed packet counter error */
#define RXCR_MASK (1<<8) /* RXCRCERR counter rolled over */ #define RXCR_MASK (1 << 8) /* RXCRCERR counter rolled over */
#define RXFR_MASK (1<<9) /* RXFRAMEERR counter rolled over */ #define RXFR_MASK (1 << 9) /* RXFRAMEERR counter rolled over */
#define RXFL_MASK (1<<10) /* RXOFLOWERR counter rolled over */ #define RXFL_MASK (1 << 10) /* RXOFLOWERR counter rolled over */
#define MDIO_MASK (1<<12) /* MDIO complete interrupt */ #define MDIO_MASK (1 << 12) /* MDIO complete interrupt */
#define TXPL_MASK (1<<31) /* Force polling of BD by EMAC */ #define TXPL_MASK (1 << 31) /* Force polling of BD by EMAC */
/* CONTROL Register bit masks */ /* CONTROL Register bit masks */
#define EN_MASK (1<<0) /* VMAC enable */ #define EN_MASK (1 << 0) /* VMAC enable */
#define TXRN_MASK (1<<3) /* TX enable */ #define TXRN_MASK (1 << 3) /* TX enable */
#define RXRN_MASK (1<<4) /* RX enable */ #define RXRN_MASK (1 << 4) /* RX enable */
#define DSBC_MASK (1<<8) /* Disable receive broadcast */ #define DSBC_MASK (1 << 8) /* Disable receive broadcast */
#define ENFL_MASK (1<<10) /* Enable Full-duplex */ #define ENFL_MASK (1 << 10) /* Enable Full-duplex */
#define PROM_MASK (1<<11) /* Promiscuous mode */ #define PROM_MASK (1 << 11) /* Promiscuous mode */
/* Buffer descriptor INFO bit masks */ /* Buffer descriptor INFO bit masks */
#define OWN_MASK (1<<31) /* 0-CPU owns buffer, 1-EMAC owns buffer */ #define OWN_MASK (1 << 31) /* 0-CPU or 1-EMAC owns buffer */
#define FIRST_MASK (1<<16) /* First buffer in chain */ #define FIRST_MASK (1 << 16) /* First buffer in chain */
#define LAST_MASK (1<<17) /* Last buffer in chain */ #define LAST_MASK (1 << 17) /* Last buffer in chain */
#define LEN_MASK 0x000007FF /* last 11 bits */ #define LEN_MASK 0x000007FF /* last 11 bits */
#define CRLS (1<<21) #define CRLS (1 << 21)
#define DEFR (1<<22) #define DEFR (1 << 22)
#define DROP (1<<23) #define DROP (1 << 23)
#define RTRY (1<<24) #define RTRY (1 << 24)
#define LTCL (1<<28) #define LTCL (1 << 28)
#define UFLO (1<<29) #define UFLO (1 << 29)
#define FOR_EMAC OWN_MASK #define FOR_EMAC OWN_MASK
#define FOR_CPU 0 #define FOR_CPU 0
...@@ -66,7 +66,7 @@ enum { ...@@ -66,7 +66,7 @@ enum {
R_MDIO, R_MDIO,
}; };
#define TX_TIMEOUT (400*HZ/1000) /* Transmission timeout */ #define TX_TIMEOUT (400 * HZ / 1000) /* Transmission timeout */
#define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */ #define ARC_EMAC_NAPI_WEIGHT 40 /* Workload for NAPI */
...@@ -102,6 +102,11 @@ struct buffer_state { ...@@ -102,6 +102,11 @@ struct buffer_state {
DEFINE_DMA_UNMAP_LEN(len); DEFINE_DMA_UNMAP_LEN(len);
}; };
struct arc_emac_mdio_bus_data {
struct gpio_desc *reset_gpio;
int msec;
};
/** /**
* struct arc_emac_priv - Storage of EMAC's private information. * struct arc_emac_priv - Storage of EMAC's private information.
* @dev: Pointer to the current device. * @dev: Pointer to the current device.
...@@ -131,6 +136,7 @@ struct arc_emac_priv { ...@@ -131,6 +136,7 @@ struct arc_emac_priv {
struct device *dev; struct device *dev;
struct phy_device *phy_dev; struct phy_device *phy_dev;
struct mii_bus *bus; struct mii_bus *bus;
struct arc_emac_mdio_bus_data bus_data;
void __iomem *regs; void __iomem *regs;
struct clk *clk; struct clk *clk;
...@@ -190,6 +196,7 @@ static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg) ...@@ -190,6 +196,7 @@ static inline unsigned int arc_reg_get(struct arc_emac_priv *priv, int reg)
static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask) static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
{ {
unsigned int value = arc_reg_get(priv, reg); unsigned int value = arc_reg_get(priv, reg);
arc_reg_set(priv, reg, value | mask); arc_reg_set(priv, reg, value | mask);
} }
...@@ -205,6 +212,7 @@ static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask) ...@@ -205,6 +212,7 @@ static inline void arc_reg_or(struct arc_emac_priv *priv, int reg, int mask)
static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask) static inline void arc_reg_clr(struct arc_emac_priv *priv, int reg, int mask)
{ {
unsigned int value = arc_reg_get(priv, reg); unsigned int value = arc_reg_get(priv, reg);
arc_reg_set(priv, reg, value & ~mask); arc_reg_set(priv, reg, value & ~mask);
} }
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "emac.h" #include "emac.h"
/** /**
* arc_emac_tx_avail - Return the number of available slots in the tx ring. * arc_emac_tx_avail - Return the number of available slots in the tx ring.
* @priv: Pointer to ARC EMAC private data structure. * @priv: Pointer to ARC EMAC private data structure.
...@@ -66,7 +65,7 @@ static void arc_emac_adjust_link(struct net_device *ndev) ...@@ -66,7 +65,7 @@ static void arc_emac_adjust_link(struct net_device *ndev)
if (priv->duplex != phy_dev->duplex) { if (priv->duplex != phy_dev->duplex) {
reg = arc_reg_get(priv, R_CTRL); reg = arc_reg_get(priv, R_CTRL);
if (DUPLEX_FULL == phy_dev->duplex) if (phy_dev->duplex == DUPLEX_FULL)
reg |= ENFL_MASK; reg |= ENFL_MASK;
else else
reg &= ~ENFL_MASK; reg &= ~ENFL_MASK;
...@@ -466,9 +465,9 @@ static int arc_emac_open(struct net_device *ndev) ...@@ -466,9 +465,9 @@ static int arc_emac_open(struct net_device *ndev)
/* Set CONTROL */ /* Set CONTROL */
arc_reg_set(priv, R_CTRL, arc_reg_set(priv, R_CTRL,
(RX_BD_NUM << 24) | /* RX BD table length */ (RX_BD_NUM << 24) | /* RX BD table length */
(TX_BD_NUM << 16) | /* TX BD table length */ (TX_BD_NUM << 16) | /* TX BD table length */
TXRN_MASK | RXRN_MASK); TXRN_MASK | RXRN_MASK);
napi_enable(&priv->napi); napi_enable(&priv->napi);
...@@ -533,8 +532,10 @@ static void arc_free_tx_queue(struct net_device *ndev) ...@@ -533,8 +532,10 @@ static void arc_free_tx_queue(struct net_device *ndev)
struct buffer_state *tx_buff = &priv->tx_buff[i]; struct buffer_state *tx_buff = &priv->tx_buff[i];
if (tx_buff->skb) { if (tx_buff->skb) {
dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr), dma_unmap_single(&ndev->dev,
dma_unmap_len(tx_buff, len), DMA_TO_DEVICE); dma_unmap_addr(tx_buff, addr),
dma_unmap_len(tx_buff, len),
DMA_TO_DEVICE);
/* return the sk_buff to system */ /* return the sk_buff to system */
dev_kfree_skb_irq(tx_buff->skb); dev_kfree_skb_irq(tx_buff->skb);
...@@ -562,8 +563,10 @@ static void arc_free_rx_queue(struct net_device *ndev) ...@@ -562,8 +563,10 @@ static void arc_free_rx_queue(struct net_device *ndev)
struct buffer_state *rx_buff = &priv->rx_buff[i]; struct buffer_state *rx_buff = &priv->rx_buff[i];
if (rx_buff->skb) { if (rx_buff->skb) {
dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr), dma_unmap_single(&ndev->dev,
dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE); dma_unmap_addr(rx_buff, addr),
dma_unmap_len(rx_buff, len),
DMA_FROM_DEVICE);
/* return the sk_buff to system */ /* return the sk_buff to system */
dev_kfree_skb_irq(rx_buff->skb); dev_kfree_skb_irq(rx_buff->skb);
...@@ -717,8 +720,8 @@ static void arc_emac_set_address_internal(struct net_device *ndev) ...@@ -717,8 +720,8 @@ static void arc_emac_set_address_internal(struct net_device *ndev)
struct arc_emac_priv *priv = netdev_priv(ndev); struct arc_emac_priv *priv = netdev_priv(ndev);
unsigned int addr_low, addr_hi; unsigned int addr_low, addr_hi;
addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]); addr_low = le32_to_cpu(*(__le32 *)&ndev->dev_addr[0]);
addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]); addr_hi = le16_to_cpu(*(__le16 *)&ndev->dev_addr[4]);
arc_reg_set(priv, R_ADDRL, addr_low); arc_reg_set(priv, R_ADDRL, addr_low);
arc_reg_set(priv, R_ADDRH, addr_hi); arc_reg_set(priv, R_ADDRH, addr_hi);
...@@ -774,7 +777,6 @@ int arc_emac_probe(struct net_device *ndev, int interface) ...@@ -774,7 +777,6 @@ int arc_emac_probe(struct net_device *ndev, int interface)
unsigned int id, clock_frequency, irq; unsigned int id, clock_frequency, irq;
int err; int err;
/* Get PHY from device tree */ /* Get PHY from device tree */
phy_node = of_parse_phandle(dev->of_node, "phy", 0); phy_node = of_parse_phandle(dev->of_node, "phy", 0);
if (!phy_node) { if (!phy_node) {
...@@ -796,7 +798,6 @@ int arc_emac_probe(struct net_device *ndev, int interface) ...@@ -796,7 +798,6 @@ int arc_emac_probe(struct net_device *ndev, int interface)
return -ENODEV; return -ENODEV;
} }
ndev->netdev_ops = &arc_emac_netdev_ops; ndev->netdev_ops = &arc_emac_netdev_ops;
ndev->ethtool_ops = &arc_emac_ethtool_ops; ndev->ethtool_ops = &arc_emac_ethtool_ops;
ndev->watchdog_timeo = TX_TIMEOUT; ndev->watchdog_timeo = TX_TIMEOUT;
...@@ -807,9 +808,9 @@ int arc_emac_probe(struct net_device *ndev, int interface) ...@@ -807,9 +808,9 @@ int arc_emac_probe(struct net_device *ndev, int interface)
priv->dev = dev; priv->dev = dev;
priv->regs = devm_ioremap_resource(dev, &res_regs); priv->regs = devm_ioremap_resource(dev, &res_regs);
if (IS_ERR(priv->regs)) { if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs); return PTR_ERR(priv->regs);
}
dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs); dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs);
if (priv->clk) { if (priv->clk) {
...@@ -930,10 +931,8 @@ int arc_emac_remove(struct net_device *ndev) ...@@ -930,10 +931,8 @@ int arc_emac_remove(struct net_device *ndev)
unregister_netdev(ndev); unregister_netdev(ndev);
netif_napi_del(&priv->napi); netif_napi_del(&priv->napi);
if (!IS_ERR(priv->clk)) { if (!IS_ERR(priv->clk))
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
}
return 0; return 0;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include "emac.h" #include "emac.h"
...@@ -93,11 +94,30 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr, ...@@ -93,11 +94,30 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
phy_addr, reg_num, value); phy_addr, reg_num, value);
arc_reg_set(priv, R_MDIO, arc_reg_set(priv, R_MDIO,
0x50020000 | (phy_addr << 23) | (reg_num << 18) | value); 0x50020000 | (phy_addr << 23) | (reg_num << 18) | value);
return arc_mdio_complete_wait(priv); return arc_mdio_complete_wait(priv);
} }
/**
* arc_mdio_reset
* @bus: points to the mii_bus structure
* Description: reset the MII bus
*/
int arc_mdio_reset(struct mii_bus *bus)
{
struct arc_emac_priv *priv = bus->priv;
struct arc_emac_mdio_bus_data *data = &priv->bus_data;
if (data->reset_gpio) {
gpiod_set_value_cansleep(data->reset_gpio, 1);
msleep(data->msec);
gpiod_set_value_cansleep(data->reset_gpio, 0);
}
return 0;
}
/** /**
* arc_mdio_probe - MDIO probe function. * arc_mdio_probe - MDIO probe function.
* @priv: Pointer to ARC EMAC private data structure. * @priv: Pointer to ARC EMAC private data structure.
...@@ -109,6 +129,8 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr, ...@@ -109,6 +129,8 @@ static int arc_mdio_write(struct mii_bus *bus, int phy_addr,
*/ */
int arc_mdio_probe(struct arc_emac_priv *priv) int arc_mdio_probe(struct arc_emac_priv *priv)
{ {
struct arc_emac_mdio_bus_data *data = &priv->bus_data;
struct device_node *np = priv->dev->of_node;
struct mii_bus *bus; struct mii_bus *bus;
int error; int error;
...@@ -122,6 +144,21 @@ int arc_mdio_probe(struct arc_emac_priv *priv) ...@@ -122,6 +144,21 @@ int arc_mdio_probe(struct arc_emac_priv *priv)
bus->name = "Synopsys MII Bus", bus->name = "Synopsys MII Bus",
bus->read = &arc_mdio_read; bus->read = &arc_mdio_read;
bus->write = &arc_mdio_write; bus->write = &arc_mdio_write;
bus->reset = &arc_mdio_reset;
/* optional reset-related properties */
data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset",
GPIOD_OUT_LOW);
if (IS_ERR(data->reset_gpio)) {
error = PTR_ERR(data->reset_gpio);
dev_err(priv->dev, "Failed to request gpio: %d\n", error);
return error;
}
of_property_read_u32(np, "phy-reset-duration", &data->msec);
/* A sane reset duration should not be longer than 1s */
if (data->msec > 1000)
data->msec = 1;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name); snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
......
...@@ -50,7 +50,7 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) ...@@ -50,7 +50,7 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
u32 data; u32 data;
int err = 0; int err = 0;
switch(speed) { switch (speed) {
case 10: case 10:
data = (1 << (speed_offset + 16)) | (0 << speed_offset); data = (1 << (speed_offset + 16)) | (0 << speed_offset);
break; break;
...@@ -83,9 +83,18 @@ static const struct emac_rockchip_soc_data emac_rk3188_emac_data = { ...@@ -83,9 +83,18 @@ static const struct emac_rockchip_soc_data emac_rk3188_emac_data = {
}; };
static const struct of_device_id emac_rockchip_dt_ids[] = { static const struct of_device_id emac_rockchip_dt_ids[] = {
{ .compatible = "rockchip,rk3036-emac", .data = &emac_rk3036_emac_data }, {
{ .compatible = "rockchip,rk3066-emac", .data = &emac_rk3066_emac_data }, .compatible = "rockchip,rk3036-emac",
{ .compatible = "rockchip,rk3188-emac", .data = &emac_rk3188_emac_data }, .data = &emac_rk3036_emac_data,
},
{
.compatible = "rockchip,rk3066-emac",
.data = &emac_rk3066_emac_data,
},
{
.compatible = "rockchip,rk3188-emac",
.data = &emac_rk3188_emac_data,
},
{ /* Sentinel */ } { /* Sentinel */ }
}; };
...@@ -123,9 +132,11 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -123,9 +132,11 @@ static int emac_rockchip_probe(struct platform_device *pdev)
goto out_netdev; goto out_netdev;
} }
priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
"rockchip,grf");
if (IS_ERR(priv->grf)) { if (IS_ERR(priv->grf)) {
dev_err(dev, "failed to retrieve global register file (%ld)\n", PTR_ERR(priv->grf)); dev_err(dev, "failed to retrieve global register file (%ld)\n",
PTR_ERR(priv->grf));
err = PTR_ERR(priv->grf); err = PTR_ERR(priv->grf);
goto out_netdev; goto out_netdev;
} }
...@@ -135,14 +146,16 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -135,14 +146,16 @@ static int emac_rockchip_probe(struct platform_device *pdev)
priv->emac.clk = devm_clk_get(dev, "hclk"); priv->emac.clk = devm_clk_get(dev, "hclk");
if (IS_ERR(priv->emac.clk)) { if (IS_ERR(priv->emac.clk)) {
dev_err(dev, "failed to retrieve host clock (%ld)\n", PTR_ERR(priv->emac.clk)); dev_err(dev, "failed to retrieve host clock (%ld)\n",
PTR_ERR(priv->emac.clk));
err = PTR_ERR(priv->emac.clk); err = PTR_ERR(priv->emac.clk);
goto out_netdev; goto out_netdev;
} }
priv->refclk = devm_clk_get(dev, "macref"); priv->refclk = devm_clk_get(dev, "macref");
if (IS_ERR(priv->refclk)) { if (IS_ERR(priv->refclk)) {
dev_err(dev, "failed to retrieve reference clock (%ld)\n", PTR_ERR(priv->refclk)); dev_err(dev, "failed to retrieve reference clock (%ld)\n",
PTR_ERR(priv->refclk));
err = PTR_ERR(priv->refclk); err = PTR_ERR(priv->refclk);
goto out_netdev; goto out_netdev;
} }
...@@ -179,19 +192,22 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -179,19 +192,22 @@ static int emac_rockchip_probe(struct platform_device *pdev)
err = regmap_write(priv->grf, priv->soc_data->grf_offset, data); err = regmap_write(priv->grf, priv->soc_data->grf_offset, data);
if (err) { if (err) {
dev_err(dev, "unable to apply initial settings to grf (%d)\n", err); dev_err(dev, "unable to apply initial settings to grf (%d)\n",
err);
goto out_regulator_disable; goto out_regulator_disable;
} }
/* RMII interface needs always a rate of 50MHz */ /* RMII interface needs always a rate of 50MHz */
err = clk_set_rate(priv->refclk, 50000000); err = clk_set_rate(priv->refclk, 50000000);
if (err) if (err)
dev_err(dev, "failed to change reference clock rate (%d)\n", err); dev_err(dev,
"failed to change reference clock rate (%d)\n", err);
if (priv->soc_data->need_div_macclk) { if (priv->soc_data->need_div_macclk) {
priv->macclk = devm_clk_get(dev, "macclk"); priv->macclk = devm_clk_get(dev, "macclk");
if (IS_ERR(priv->macclk)) { if (IS_ERR(priv->macclk)) {
dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk)); dev_err(dev, "failed to retrieve mac clock (%ld)\n",
PTR_ERR(priv->macclk));
err = PTR_ERR(priv->macclk); err = PTR_ERR(priv->macclk);
goto out_regulator_disable; goto out_regulator_disable;
} }
...@@ -205,7 +221,8 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -205,7 +221,8 @@ static int emac_rockchip_probe(struct platform_device *pdev)
/* RMII TX/RX needs always a rate of 25MHz */ /* RMII TX/RX needs always a rate of 25MHz */
err = clk_set_rate(priv->macclk, 25000000); err = clk_set_rate(priv->macclk, 25000000);
if (err) if (err)
dev_err(dev, "failed to change mac clock rate (%d)\n", err); dev_err(dev,
"failed to change mac clock rate (%d)\n", err);
} }
err = arc_emac_probe(ndev, interface); err = arc_emac_probe(ndev, interface);
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define SCLK_PVTM_VIDEO 125 #define SCLK_PVTM_VIDEO 125
#define SCLK_MAC 151 #define SCLK_MAC 151
#define SCLK_MACREF 152 #define SCLK_MACREF 152
#define SCLK_MACPLL 153
#define SCLK_SFC 160 #define SCLK_SFC 160
/* aclk gates */ /* aclk gates */
...@@ -92,6 +93,7 @@ ...@@ -92,6 +93,7 @@
#define HCLK_SDMMC 456 #define HCLK_SDMMC 456
#define HCLK_SDIO 457 #define HCLK_SDIO 457
#define HCLK_EMMC 459 #define HCLK_EMMC 459
#define HCLK_MAC 460
#define HCLK_I2S 462 #define HCLK_I2S 462
#define HCLK_LCDC 465 #define HCLK_LCDC 465
#define HCLK_ROM 467 #define HCLK_ROM 467
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment