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

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
Loading
Loading
Loading
Loading
+79 −22
Original line number Diff line number Diff line
@@ -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,32 +49,46 @@
#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)		|
@@ -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);