// SPDX-License-Identifier: GPL-2.0
/**
 * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller
 *
 * Copyright (C) 2023 StarFive Technology Co., Ltd.
 *
 * Author:	Minda Chen <minda.chen@starfivetech.com>
 */

#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/of_platform.h>
#include <linux/reset.h>
#include <linux/regmap.h>
#include <linux/usb/otg.h>
#include "core.h"

#define USB_STRAP_HOST			BIT(17)
#define USB_STRAP_DEVICE		BIT(18)
#define USB_STRAP_MASK			GENMASK(18, 16)

#define USB_SUSPENDM_HOST		BIT(19)
#define USB_SUSPENDM_MASK		BIT(19)

#define USB_MISC_CFG_MASK		GENMASK(23, 20)
#define USB_SUSPENDM_BYPS		BIT(20)
#define USB_PLL_EN			BIT(22)
#define USB_REFCLK_MODE			BIT(23)

struct cdns_starfive {
	struct device *dev;
	struct regmap *stg_syscon;
	struct reset_control *resets;
	struct clk_bulk_data *clks;
	int num_clks;
	u32 stg_usb_mode;
};

static void cdns_mode_init(struct platform_device *pdev,
			   struct cdns_starfive *data)
{
	enum usb_dr_mode mode;

	regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
			   USB_MISC_CFG_MASK,
			   USB_SUSPENDM_BYPS | USB_PLL_EN | USB_REFCLK_MODE);

	/* dr mode setting */
	mode = usb_get_dr_mode(&pdev->dev);

	switch (mode) {
	case USB_DR_MODE_HOST:
		regmap_update_bits(data->stg_syscon,
				   data->stg_usb_mode,
				   USB_STRAP_MASK,
				   USB_STRAP_HOST);
		regmap_update_bits(data->stg_syscon,
				   data->stg_usb_mode,
				   USB_SUSPENDM_MASK,
				   USB_SUSPENDM_HOST);
		break;

	case USB_DR_MODE_PERIPHERAL:
		regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
				   USB_STRAP_MASK, USB_STRAP_DEVICE);
		regmap_update_bits(data->stg_syscon, data->stg_usb_mode,
				   USB_SUSPENDM_MASK, 0);
		break;
	default:
		break;
	}
}

static int cdns_clk_rst_init(struct cdns_starfive *data)
{
	int ret;

	ret = clk_bulk_prepare_enable(data->num_clks, data->clks);
	if (ret)
		return dev_err_probe(data->dev, ret,
				     "failed to enable clocks\n");

	ret = reset_control_deassert(data->resets);
	if (ret) {
		dev_err(data->dev, "failed to reset clocks\n");
		goto err_clk_init;
	}

	return ret;

err_clk_init:
	clk_bulk_disable_unprepare(data->num_clks, data->clks);
	return ret;
}

static void cdns_clk_rst_deinit(struct cdns_starfive *data)
{
	reset_control_assert(data->resets);
	clk_bulk_disable_unprepare(data->num_clks, data->clks);
}

static int cdns_starfive_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cdns_starfive *data;
	unsigned int args;
	int ret;

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

	data->dev = dev;

	data->stg_syscon =
		syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node,
						     "starfive,stg-syscon", 1, &args);

	if (IS_ERR(data->stg_syscon))
		return dev_err_probe(dev, PTR_ERR(data->stg_syscon),
				     "Failed to parse starfive,stg-syscon\n");

	data->stg_usb_mode = args;

	data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks);
	if (data->num_clks < 0)
		return dev_err_probe(data->dev, -ENODEV,
				     "Failed to get clocks\n");

	data->resets = devm_reset_control_array_get_exclusive(data->dev);
	if (IS_ERR(data->resets))
		return dev_err_probe(data->dev, PTR_ERR(data->resets),
				     "Failed to get resets");

	cdns_mode_init(pdev, data);
	ret = cdns_clk_rst_init(data);
	if (ret)
		return ret;

	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
	if (ret) {
		dev_err(dev, "Failed to create children\n");
		cdns_clk_rst_deinit(data);
		return ret;
	}

	device_set_wakeup_capable(dev, true);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);
	platform_set_drvdata(pdev, data);

	return 0;
}

static int cdns_starfive_remove_core(struct device *dev, void *c)
{
	struct platform_device *pdev = to_platform_device(dev);

	platform_device_unregister(pdev);

	return 0;
}

static void cdns_starfive_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct cdns_starfive *data = dev_get_drvdata(dev);

	pm_runtime_get_sync(dev);
	device_for_each_child(dev, NULL, cdns_starfive_remove_core);

	pm_runtime_disable(dev);
	pm_runtime_put_noidle(dev);
	cdns_clk_rst_deinit(data);
	platform_set_drvdata(pdev, NULL);
}

#ifdef CONFIG_PM
static int cdns_starfive_runtime_resume(struct device *dev)
{
	struct cdns_starfive *data = dev_get_drvdata(dev);

	return clk_bulk_prepare_enable(data->num_clks, data->clks);
}

static int cdns_starfive_runtime_suspend(struct device *dev)
{
	struct cdns_starfive *data = dev_get_drvdata(dev);

	clk_bulk_disable_unprepare(data->num_clks, data->clks);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int cdns_starfive_resume(struct device *dev)
{
	struct cdns_starfive *data = dev_get_drvdata(dev);

	return cdns_clk_rst_init(data);
}

static int cdns_starfive_suspend(struct device *dev)
{
	struct cdns_starfive *data = dev_get_drvdata(dev);

	cdns_clk_rst_deinit(data);

	return 0;
}
#endif
#endif

static const struct dev_pm_ops cdns_starfive_pm_ops = {
	SET_RUNTIME_PM_OPS(cdns_starfive_runtime_suspend,
			   cdns_starfive_runtime_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume)
};

static const struct of_device_id cdns_starfive_of_match[] = {
	{ .compatible = "starfive,jh7110-usb", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, cdns_starfive_of_match);

static struct platform_driver cdns_starfive_driver = {
	.probe		= cdns_starfive_probe,
	.remove_new	= cdns_starfive_remove,
	.driver		= {
		.name	= "cdns3-starfive",
		.of_match_table	= cdns_starfive_of_match,
		.pm	= &cdns_starfive_pm_ops,
	},
};
module_platform_driver(cdns_starfive_driver);

MODULE_ALIAS("platform:cdns3-starfive");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Cadence USB3 StarFive Glue Layer");
