Commit 25ae15fb authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by David S. Miller

net: stmmac: dwmac-sun8i: Use regmap_field for syscon register access

On the Allwinner R40, the "GMAC clock" register is located in the CCU
block, at a different register address than the other SoCs that have
it in the "system control" block.

This patch converts the use of regmap to regmap_field for mapping and
accessing the syscon register, so we can have the register address in
the variants data, and not in the actual register manipulation code.

This patch only converts regmap_read() and regmap_write() calls to
regmap_field_read() and regmap_field_write() calls. There are some
places where it might make sense to switch to regmap_field_update_bits(),
but this is not done here to keep the patch simple.
Signed-off-by: default avatarChen-Yu Tsai <wens@csie.org>
Acked-by: default avatarMaxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eef8811d
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
* This value is used for disabling properly EMAC * This value is used for disabling properly EMAC
* and used as a good starting value in case of the * and used as a good starting value in case of the
* boot process(uboot) leave some stuff. * boot process(uboot) leave some stuff.
* @syscon_field reg_field for the syscon's gmac register
* @soc_has_internal_phy: Does the MAC embed an internal PHY * @soc_has_internal_phy: Does the MAC embed an internal PHY
* @support_mii: Does the MAC handle MII * @support_mii: Does the MAC handle MII
* @support_rmii: Does the MAC handle RMII * @support_rmii: Does the MAC handle RMII
...@@ -49,6 +50,7 @@ ...@@ -49,6 +50,7 @@
*/ */
struct emac_variant { struct emac_variant {
u32 default_syscon_value; u32 default_syscon_value;
const struct reg_field *syscon_field;
bool soc_has_internal_phy; bool soc_has_internal_phy;
bool support_mii; bool support_mii;
bool support_rmii; bool support_rmii;
...@@ -71,13 +73,21 @@ struct sunxi_priv_data { ...@@ -71,13 +73,21 @@ struct sunxi_priv_data {
struct regulator *regulator; struct regulator *regulator;
struct reset_control *rst_ephy; struct reset_control *rst_ephy;
const struct emac_variant *variant; const struct emac_variant *variant;
struct regmap *regmap; struct regmap_field *regmap_field;
bool internal_phy_powered; bool internal_phy_powered;
void *mux_handle; void *mux_handle;
}; };
/* EMAC clock register @ 0x30 in the "system control" address range */
static const struct reg_field sun8i_syscon_reg_field = {
.reg = 0x30,
.lsb = 0,
.msb = 31,
};
static const struct emac_variant emac_variant_h3 = { static const struct emac_variant emac_variant_h3 = {
.default_syscon_value = 0x58000, .default_syscon_value = 0x58000,
.syscon_field = &sun8i_syscon_reg_field,
.soc_has_internal_phy = true, .soc_has_internal_phy = true,
.support_mii = true, .support_mii = true,
.support_rmii = true, .support_rmii = true,
...@@ -86,12 +96,14 @@ static const struct emac_variant emac_variant_h3 = { ...@@ -86,12 +96,14 @@ static const struct emac_variant emac_variant_h3 = {
static const struct emac_variant emac_variant_v3s = { static const struct emac_variant emac_variant_v3s = {
.default_syscon_value = 0x38000, .default_syscon_value = 0x38000,
.syscon_field = &sun8i_syscon_reg_field,
.soc_has_internal_phy = true, .soc_has_internal_phy = true,
.support_mii = true .support_mii = true
}; };
static const struct emac_variant emac_variant_a83t = { static const struct emac_variant emac_variant_a83t = {
.default_syscon_value = 0, .default_syscon_value = 0,
.syscon_field = &sun8i_syscon_reg_field,
.soc_has_internal_phy = false, .soc_has_internal_phy = false,
.support_mii = true, .support_mii = true,
.support_rgmii = true .support_rgmii = true
...@@ -99,6 +111,7 @@ static const struct emac_variant emac_variant_a83t = { ...@@ -99,6 +111,7 @@ static const struct emac_variant emac_variant_a83t = {
static const struct emac_variant emac_variant_a64 = { static const struct emac_variant emac_variant_a64 = {
.default_syscon_value = 0, .default_syscon_value = 0,
.syscon_field = &sun8i_syscon_reg_field,
.soc_has_internal_phy = false, .soc_has_internal_phy = false,
.support_mii = true, .support_mii = true,
.support_rmii = true, .support_rmii = true,
...@@ -216,7 +229,6 @@ static const struct emac_variant emac_variant_a64 = { ...@@ -216,7 +229,6 @@ static const struct emac_variant emac_variant_a64 = {
#define SYSCON_ETCS_MII 0x0 #define SYSCON_ETCS_MII 0x0
#define SYSCON_ETCS_EXT_GMII 0x1 #define SYSCON_ETCS_EXT_GMII 0x1
#define SYSCON_ETCS_INT_GMII 0x2 #define SYSCON_ETCS_INT_GMII 0x2
#define SYSCON_EMAC_REG 0x30
/* sun8i_dwmac_dma_reset() - reset the EMAC /* sun8i_dwmac_dma_reset() - reset the EMAC
* Called from stmmac via stmmac_dma_ops->reset * Called from stmmac via stmmac_dma_ops->reset
...@@ -745,7 +757,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, ...@@ -745,7 +757,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
bool need_power_ephy = false; bool need_power_ephy = false;
if (current_child ^ desired_child) { if (current_child ^ desired_child) {
regmap_read(gmac->regmap, SYSCON_EMAC_REG, &reg); regmap_field_read(gmac->regmap_field, &reg);
switch (desired_child) { switch (desired_child) {
case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID:
dev_info(priv->device, "Switch mux to internal PHY"); dev_info(priv->device, "Switch mux to internal PHY");
...@@ -763,7 +775,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child, ...@@ -763,7 +775,7 @@ static int mdio_mux_syscon_switch_fn(int current_child, int desired_child,
desired_child); desired_child);
return -EINVAL; return -EINVAL;
} }
regmap_write(gmac->regmap, SYSCON_EMAC_REG, val); regmap_field_write(gmac->regmap_field, val);
if (need_power_ephy) { if (need_power_ephy) {
ret = sun8i_dwmac_power_internal_phy(priv); ret = sun8i_dwmac_power_internal_phy(priv);
if (ret) if (ret)
...@@ -801,7 +813,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) ...@@ -801,7 +813,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
int ret; int ret;
u32 reg, val; u32 reg, val;
regmap_read(gmac->regmap, SYSCON_EMAC_REG, &val); regmap_field_read(gmac->regmap_field, &val);
reg = gmac->variant->default_syscon_value; reg = gmac->variant->default_syscon_value;
if (reg != val) if (reg != val)
dev_warn(priv->device, dev_warn(priv->device,
...@@ -883,7 +895,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv) ...@@ -883,7 +895,7 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
return -EINVAL; return -EINVAL;
} }
regmap_write(gmac->regmap, SYSCON_EMAC_REG, reg); regmap_field_write(gmac->regmap_field, reg);
return 0; return 0;
} }
...@@ -892,7 +904,7 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac) ...@@ -892,7 +904,7 @@ static void sun8i_dwmac_unset_syscon(struct sunxi_priv_data *gmac)
{ {
u32 reg = gmac->variant->default_syscon_value; u32 reg = gmac->variant->default_syscon_value;
regmap_write(gmac->regmap, SYSCON_EMAC_REG, reg); regmap_field_write(gmac->regmap_field, reg);
} }
static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv) static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
...@@ -980,6 +992,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) ...@@ -980,6 +992,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
int ret; int ret;
struct stmmac_priv *priv; struct stmmac_priv *priv;
struct net_device *ndev; struct net_device *ndev;
struct regmap *regmap;
ret = stmmac_get_platform_resources(pdev, &stmmac_res); ret = stmmac_get_platform_resources(pdev, &stmmac_res);
if (ret) if (ret)
...@@ -1014,14 +1027,21 @@ static int sun8i_dwmac_probe(struct platform_device *pdev) ...@@ -1014,14 +1027,21 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
gmac->regulator = NULL; gmac->regulator = NULL;
} }
gmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "syscon");
"syscon"); if (IS_ERR(regmap)) {
if (IS_ERR(gmac->regmap)) { ret = PTR_ERR(regmap);
ret = PTR_ERR(gmac->regmap);
dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret); dev_err(&pdev->dev, "Unable to map syscon: %d\n", ret);
return ret; return ret;
} }
gmac->regmap_field = devm_regmap_field_alloc(dev, regmap,
*gmac->variant->syscon_field);
if (IS_ERR(gmac->regmap_field)) {
ret = PTR_ERR(gmac->regmap_field);
dev_err(dev, "Unable to map syscon register: %d\n", ret);
return ret;
}
plat_dat->interface = of_get_phy_mode(dev->of_node); plat_dat->interface = of_get_phy_mode(dev->of_node);
/* platform data specifying hardware features and callbacks. /* platform data specifying hardware features and callbacks.
......
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