Commit 72f1f7e4 authored by Neil Armstrong's avatar Neil Armstrong Committed by Jakub Kicinski

net: stmmac: dwmac-oxnas: Add support for OX810SE

Add support for OX810SE dwmac glue setup, which is a simplified version
of the OX820 introduced later with more control on the PHY interface.
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 8973d7b8
......@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
......@@ -48,46 +49,60 @@
#define DWMAC_RX_VARDELAY(d) ((d) << DWMAC_RX_VARDELAY_SHIFT)
#define DWMAC_RXN_VARDELAY(d) ((d) << DWMAC_RXN_VARDELAY_SHIFT)
struct oxnas_dwmac;
struct oxnas_dwmac_data {
int (*setup)(struct oxnas_dwmac *dwmac);
};
struct oxnas_dwmac {
struct device *dev;
struct clk *clk;
struct regmap *regmap;
const struct oxnas_dwmac_data *data;
};
static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
static int oxnas_dwmac_setup_ox810se(struct oxnas_dwmac *dwmac)
{
struct oxnas_dwmac *dwmac = priv;
unsigned int value;
int ret;
/* Reset HW here before changing the glue configuration */
ret = device_reset(dwmac->dev);
if (ret)
ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
if (ret < 0)
return ret;
ret = clk_prepare_enable(dwmac->clk);
if (ret)
return ret;
/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
value |= BIT(DWMAC_CKEN_GTX) |
/* Use simple mux for 25/125 Mhz clock switching */
BIT(DWMAC_SIMPLE_MUX);
regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
return 0;
}
static int oxnas_dwmac_setup_ox820(struct oxnas_dwmac *dwmac)
{
unsigned int value;
int ret;
ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
if (ret < 0) {
clk_disable_unprepare(dwmac->clk);
if (ret < 0)
return ret;
}
/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
value |= BIT(DWMAC_CKEN_GTX) |
/* Use simple mux for 25/125 Mhz clock switching */
BIT(DWMAC_SIMPLE_MUX) |
/* set auto switch tx clock source */
BIT(DWMAC_AUTO_TX_SOURCE) |
/* enable tx & rx vardelay */
BIT(DWMAC_CKEN_TX_OUT) |
BIT(DWMAC_CKEN_TXN_OUT) |
BIT(DWMAC_CKEN_TX_IN) |
BIT(DWMAC_CKEN_RX_OUT) |
BIT(DWMAC_CKEN_RXN_OUT) |
BIT(DWMAC_CKEN_RX_IN);
BIT(DWMAC_SIMPLE_MUX) |
/* set auto switch tx clock source */
BIT(DWMAC_AUTO_TX_SOURCE) |
/* enable tx & rx vardelay */
BIT(DWMAC_CKEN_TX_OUT) |
BIT(DWMAC_CKEN_TXN_OUT) |
BIT(DWMAC_CKEN_TX_IN) |
BIT(DWMAC_CKEN_RX_OUT) |
BIT(DWMAC_CKEN_RXN_OUT) |
BIT(DWMAC_CKEN_RX_IN);
regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
/* set tx & rx vardelay */
......@@ -100,6 +115,27 @@ static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
return 0;
}
static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
{
struct oxnas_dwmac *dwmac = priv;
int ret;
/* Reset HW here before changing the glue configuration */
ret = device_reset(dwmac->dev);
if (ret)
return ret;
ret = clk_prepare_enable(dwmac->clk);
if (ret)
return ret;
ret = dwmac->data->setup(dwmac);
if (ret)
clk_disable_unprepare(dwmac->clk);
return ret;
}
static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv)
{
struct oxnas_dwmac *dwmac = priv;
......@@ -128,6 +164,12 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
goto err_remove_config_dt;
}
dwmac->data = (const struct oxnas_dwmac_data *)of_device_get_match_data(&pdev->dev);
if (!dwmac->data) {
ret = -EINVAL;
goto err_remove_config_dt;
}
dwmac->dev = &pdev->dev;
plat_dat->bsp_priv = dwmac;
plat_dat->init = oxnas_dwmac_init;
......@@ -166,8 +208,23 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
return ret;
}
static const struct oxnas_dwmac_data ox810se_dwmac_data = {
.setup = oxnas_dwmac_setup_ox810se,
};
static const struct oxnas_dwmac_data ox820_dwmac_data = {
.setup = oxnas_dwmac_setup_ox820,
};
static const struct of_device_id oxnas_dwmac_match[] = {
{ .compatible = "oxsemi,ox820-dwmac" },
{
.compatible = "oxsemi,ox810se-dwmac",
.data = &ox810se_dwmac_data,
},
{
.compatible = "oxsemi,ox820-dwmac",
.data = &ox820_dwmac_data,
},
{ }
};
MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);
......
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