/*
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License version 2 as published
 *  by the Free Software Foundation.
 *
 *  Copyright (C) 2012 John Crispin <blogic@phrozen.org>
 *  Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 *  Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/property.h>
#include <dt-bindings/mips/lantiq_rcu_gphy.h>

#include <lantiq_soc.h>

#define XRX200_GPHY_FW_ALIGN	(16 * 1024)

struct xway_gphy_priv {
	struct clk *gphy_clk_gate;
	struct reset_control *gphy_reset;
	struct reset_control *gphy_reset2;
	void __iomem *membase;
	char *fw_name;
};

struct xway_gphy_match_data {
	char *fe_firmware_name;
	char *ge_firmware_name;
};

static const struct xway_gphy_match_data xrx200a1x_gphy_data = {
	.fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin",
	.ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin",
};

static const struct xway_gphy_match_data xrx200a2x_gphy_data = {
	.fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin",
	.ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin",
};

static const struct xway_gphy_match_data xrx300_gphy_data = {
	.fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin",
	.ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin",
};

static const struct of_device_id xway_gphy_match[] = {
	{ .compatible = "lantiq,xrx200a1x-gphy", .data = &xrx200a1x_gphy_data },
	{ .compatible = "lantiq,xrx200a2x-gphy", .data = &xrx200a2x_gphy_data },
	{ .compatible = "lantiq,xrx300-gphy", .data = &xrx300_gphy_data },
	{ .compatible = "lantiq,xrx330-gphy", .data = &xrx300_gphy_data },
	{},
};
MODULE_DEVICE_TABLE(of, xway_gphy_match);

static int xway_gphy_load(struct device *dev, struct xway_gphy_priv *priv,
			  dma_addr_t *dev_addr)
{
	const struct firmware *fw;
	void *fw_addr;
	dma_addr_t dma_addr;
	size_t size;
	int ret;

	ret = request_firmware(&fw, priv->fw_name, dev);
	if (ret) {
		dev_err(dev, "failed to load firmware: %s, error: %i\n",
			priv->fw_name, ret);
		return ret;
	}

	/*
	 * GPHY cores need the firmware code in a persistent and contiguous
	 * memory area with a 16 kB boundary aligned start address.
	 */
	size = fw->size + XRX200_GPHY_FW_ALIGN;

	fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL);
	if (fw_addr) {
		fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN);
		*dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
		memcpy(fw_addr, fw->data, fw->size);
	} else {
		dev_err(dev, "failed to alloc firmware memory\n");
		ret = -ENOMEM;
	}

	release_firmware(fw);

	return ret;
}

static int xway_gphy_of_probe(struct platform_device *pdev,
			      struct xway_gphy_priv *priv)
{
	struct device *dev = &pdev->dev;
	const struct xway_gphy_match_data *gphy_fw_name_cfg;
	u32 gphy_mode;
	int ret;
	struct resource *res_gphy;

	gphy_fw_name_cfg = of_device_get_match_data(dev);

	priv->gphy_clk_gate = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->gphy_clk_gate)) {
		dev_err(dev, "Failed to lookup gate clock\n");
		return PTR_ERR(priv->gphy_clk_gate);
	}

	res_gphy = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->membase = devm_ioremap_resource(dev, res_gphy);
	if (IS_ERR(priv->membase))
		return PTR_ERR(priv->membase);

	priv->gphy_reset = devm_reset_control_get(dev, "gphy");
	if (IS_ERR(priv->gphy_reset)) {
		if (PTR_ERR(priv->gphy_reset) != -EPROBE_DEFER)
			dev_err(dev, "Failed to lookup gphy reset\n");
		return PTR_ERR(priv->gphy_reset);
	}

	priv->gphy_reset2 = devm_reset_control_get_optional(dev, "gphy2");
	if (IS_ERR(priv->gphy_reset2))
		return PTR_ERR(priv->gphy_reset2);

	ret = device_property_read_u32(dev, "lantiq,gphy-mode", &gphy_mode);
	/* Default to GE mode */
	if (ret)
		gphy_mode = GPHY_MODE_GE;

	switch (gphy_mode) {
	case GPHY_MODE_FE:
		priv->fw_name = gphy_fw_name_cfg->fe_firmware_name;
		break;
	case GPHY_MODE_GE:
		priv->fw_name = gphy_fw_name_cfg->ge_firmware_name;
		break;
	default:
		dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
		return -EINVAL;
	}

	return 0;
}

static int xway_gphy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct xway_gphy_priv *priv;
	dma_addr_t fw_addr = 0;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	ret = xway_gphy_of_probe(pdev, priv);
	if (ret)
		return ret;

	ret = clk_prepare_enable(priv->gphy_clk_gate);
	if (ret)
		return ret;

	ret = xway_gphy_load(dev, priv, &fw_addr);
	if (ret) {
		clk_disable_unprepare(priv->gphy_clk_gate);
		return ret;
	}

	reset_control_assert(priv->gphy_reset);
	reset_control_assert(priv->gphy_reset2);

	iowrite32be(fw_addr, priv->membase);

	reset_control_deassert(priv->gphy_reset);
	reset_control_deassert(priv->gphy_reset2);

	platform_set_drvdata(pdev, priv);

	return ret;
}

static int xway_gphy_remove(struct platform_device *pdev)
{
	struct xway_gphy_priv *priv = platform_get_drvdata(pdev);

	iowrite32be(0, priv->membase);

	clk_disable_unprepare(priv->gphy_clk_gate);

	return 0;
}

static struct platform_driver xway_gphy_driver = {
	.probe = xway_gphy_probe,
	.remove = xway_gphy_remove,
	.driver = {
		.name = "xway-rcu-gphy",
		.of_match_table = xway_gphy_match,
	},
};

module_platform_driver(xway_gphy_driver);

MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader");
MODULE_LICENSE("GPL");
