Commit 1f76f731 authored by David S. Miller's avatar David S. Miller

Merge branch 'emac-RK3036'

Xing Zheng says:

====================
Add support emac for the RK3036 SoC platform

  We have supported the emac for RK3066/RK3188, but the RK3036 have
some configuration different with them. We should let the driver of
emac_rockchip compatible with other Rockchip SoCs.

Changes in v2:
- Separate DTS from patch series.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0652cb5b af72261f
...@@ -34,9 +34,9 @@ config EMAC_ROCKCHIP ...@@ -34,9 +34,9 @@ config EMAC_ROCKCHIP
select ARC_EMAC_CORE select ARC_EMAC_CORE
depends on OF_IRQ && OF_NET && REGULATOR && HAS_DMA depends on OF_IRQ && OF_NET && REGULATOR && HAS_DMA
---help--- ---help---
Support for Rockchip RK3066/RK3188 EMAC ethernet controllers. Support for Rockchip RK3036/RK3066/RK3188 EMAC ethernet controllers.
This selects Rockchip SoC glue layer support for the This selects Rockchip SoC glue layer support for the
emac device driver. This driver is used for RK3066/RK3188 emac device driver. This driver is used for RK3036/RK3066/RK3188
EMAC ethernet controller. EMAC ethernet controller.
endif # NET_VENDOR_ARC endif # NET_VENDOR_ARC
...@@ -25,17 +25,13 @@ ...@@ -25,17 +25,13 @@
#include "emac.h" #include "emac.h"
#define DRV_NAME "rockchip_emac" #define DRV_NAME "rockchip_emac"
#define DRV_VERSION "1.0" #define DRV_VERSION "1.1"
#define GRF_MODE_MII (1UL << 0)
#define GRF_MODE_RMII (0UL << 0)
#define GRF_SPEED_10M (0UL << 1)
#define GRF_SPEED_100M (1UL << 1)
#define GRF_SPEED_ENABLE_BIT (1UL << 17)
#define GRF_MODE_ENABLE_BIT (1UL << 16)
struct emac_rockchip_soc_data { struct emac_rockchip_soc_data {
int grf_offset; unsigned int grf_offset;
unsigned int grf_mode_offset;
unsigned int grf_speed_offset;
bool need_div_macclk;
}; };
struct rockchip_priv_data { struct rockchip_priv_data {
...@@ -44,23 +40,22 @@ struct rockchip_priv_data { ...@@ -44,23 +40,22 @@ struct rockchip_priv_data {
const struct emac_rockchip_soc_data *soc_data; const struct emac_rockchip_soc_data *soc_data;
struct regulator *regulator; struct regulator *regulator;
struct clk *refclk; struct clk *refclk;
struct clk *macclk;
}; };
static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
{ {
struct rockchip_priv_data *emac = priv; struct rockchip_priv_data *emac = priv;
u32 speed_offset = emac->soc_data->grf_speed_offset;
u32 data; u32 data;
int err = 0; int err = 0;
/* write-enable bits */
data = GRF_SPEED_ENABLE_BIT;
switch(speed) { switch(speed) {
case 10: case 10:
data |= GRF_SPEED_10M; data = (1 << (speed_offset + 16)) | (0 << speed_offset);
break; break;
case 100: case 100:
data |= GRF_SPEED_100M; data = (1 << (speed_offset + 16)) | (1 << speed_offset);
break; break;
default: default:
pr_err("speed %u not supported\n", speed); pr_err("speed %u not supported\n", speed);
...@@ -72,14 +67,25 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed) ...@@ -72,14 +67,25 @@ static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
pr_err("unable to apply speed %u to grf (%d)\n", speed, err); pr_err("unable to apply speed %u to grf (%d)\n", speed, err);
} }
static const struct emac_rockchip_soc_data emac_rockchip_dt_data[] = { static const struct emac_rockchip_soc_data emac_rk3036_emac_data = {
{ .grf_offset = 0x154 }, /* rk3066 */ .grf_offset = 0x140, .grf_mode_offset = 8,
{ .grf_offset = 0x0a4 }, /* rk3188 */ .grf_speed_offset = 9, .need_div_macclk = 1,
};
static const struct emac_rockchip_soc_data emac_rk3066_emac_data = {
.grf_offset = 0x154, .grf_mode_offset = 0,
.grf_speed_offset = 1, .need_div_macclk = 0,
};
static const struct emac_rockchip_soc_data emac_rk3188_emac_data = {
.grf_offset = 0x0a4, .grf_mode_offset = 0,
.grf_speed_offset = 1, .need_div_macclk = 0,
}; };
static const struct of_device_id emac_rockchip_dt_ids[] = { static const struct of_device_id emac_rockchip_dt_ids[] = {
{ .compatible = "rockchip,rk3066-emac", .data = &emac_rockchip_dt_data[0] }, { .compatible = "rockchip,rk3036-emac", .data = &emac_rk3036_emac_data },
{ .compatible = "rockchip,rk3188-emac", .data = &emac_rockchip_dt_data[1] }, { .compatible = "rockchip,rk3066-emac", .data = &emac_rk3066_emac_data },
{ .compatible = "rockchip,rk3188-emac", .data = &emac_rk3188_emac_data },
{ /* Sentinel */ } { /* Sentinel */ }
}; };
...@@ -110,7 +116,7 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -110,7 +116,7 @@ static int emac_rockchip_probe(struct platform_device *pdev)
interface = of_get_phy_mode(dev->of_node); interface = of_get_phy_mode(dev->of_node);
/* RK3066 and RK3188 SoCs only support RMII */ /* RK3036/RK3066/RK3188 SoCs only support RMII */
if (interface != PHY_INTERFACE_MODE_RMII) { if (interface != PHY_INTERFACE_MODE_RMII) {
dev_err(dev, "unsupported phy interface mode %d\n", interface); dev_err(dev, "unsupported phy interface mode %d\n", interface);
err = -ENOTSUPP; err = -ENOTSUPP;
...@@ -164,15 +170,12 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -164,15 +170,12 @@ static int emac_rockchip_probe(struct platform_device *pdev)
} }
} }
err = arc_emac_probe(ndev, interface); /* Set speed 100M */
if (err) data = (1 << (priv->soc_data->grf_speed_offset + 16)) |
goto out_regulator_disable; (1 << priv->soc_data->grf_speed_offset);
/* Set RMII mode */
/* write-enable bits */ data |= (1 << (priv->soc_data->grf_mode_offset + 16)) |
data = GRF_MODE_ENABLE_BIT | GRF_SPEED_ENABLE_BIT; (0 << priv->soc_data->grf_mode_offset);
data |= GRF_SPEED_100M;
data |= GRF_MODE_RMII;
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) {
...@@ -184,6 +187,33 @@ static int emac_rockchip_probe(struct platform_device *pdev) ...@@ -184,6 +187,33 @@ static int emac_rockchip_probe(struct platform_device *pdev)
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) {
priv->macclk = devm_clk_get(dev, "macclk");
if (IS_ERR(priv->macclk)) {
dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk));
err = PTR_ERR(priv->macclk);
goto out_regulator_disable;
}
err = clk_prepare_enable(priv->macclk);
if (err) {
dev_err(dev, "failed to enable mac clock (%d)\n", err);
goto out_regulator_disable;
}
/* RMII TX/RX needs always a rate of 25MHz */
err = clk_set_rate(priv->macclk, 25000000);
if (err)
dev_err(dev, "failed to change mac clock rate (%d)\n", err);
}
err = arc_emac_probe(ndev, interface);
if (err) {
dev_err(dev, "failed to probe arc emac (%d)\n", err);
goto out_regulator_disable;
}
return 0; return 0;
out_regulator_disable: out_regulator_disable:
......
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