/*
 * Renesas R-Car USB2.0 clock selector
 *
 * Copyright (C) 2017 Renesas Electronics Corp.
 *
 * Based on renesas-cpg-mssr.c
 *
 * Copyright (C) 2015 Glider bvba
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>

#define USB20_CLKSET0		0x00
#define CLKSET0_INTCLK_EN	BIT(11)
#define CLKSET0_PRIVATE		BIT(0)
#define CLKSET0_EXTAL_ONLY	(CLKSET0_INTCLK_EN | CLKSET0_PRIVATE)

struct usb2_clock_sel_priv {
	void __iomem *base;
	struct clk_hw hw;
	bool extal;
	bool xtal;
};
#define to_priv(_hw)	container_of(_hw, struct usb2_clock_sel_priv, hw)

static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv)
{
	u16 val = readw(priv->base + USB20_CLKSET0);

	pr_debug("%s: enter %d %d %x\n", __func__,
		 priv->extal, priv->xtal, val);

	if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY)
		writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0);
}

static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv)
{
	if (priv->extal && !priv->xtal)
		writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0);
}

static int usb2_clock_sel_enable(struct clk_hw *hw)
{
	usb2_clock_sel_enable_extal_only(to_priv(hw));

	return 0;
}

static void usb2_clock_sel_disable(struct clk_hw *hw)
{
	usb2_clock_sel_disable_extal_only(to_priv(hw));
}

/*
 * This module seems a mux, but this driver assumes a gate because
 * ehci/ohci platform drivers don't support clk_set_parent() for now.
 * If this driver acts as a gate, ehci/ohci-platform drivers don't need
 * any modification.
 */
static const struct clk_ops usb2_clock_sel_clock_ops = {
	.enable = usb2_clock_sel_enable,
	.disable = usb2_clock_sel_disable,
};

static const struct of_device_id rcar_usb2_clock_sel_match[] = {
	{ .compatible = "renesas,rcar-gen3-usb2-clock-sel" },
	{ }
};

static int rcar_usb2_clock_sel_suspend(struct device *dev)
{
	struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);

	usb2_clock_sel_disable_extal_only(priv);
	pm_runtime_put(dev);

	return 0;
}

static int rcar_usb2_clock_sel_resume(struct device *dev)
{
	struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev);

	pm_runtime_get_sync(dev);
	usb2_clock_sel_enable_extal_only(priv);

	return 0;
}

static int rcar_usb2_clock_sel_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev);

	of_clk_del_provider(dev->of_node);
	clk_hw_unregister(&priv->hw);
	pm_runtime_put(dev);
	pm_runtime_disable(dev);

	return 0;
}

static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct usb2_clock_sel_priv *priv;
	struct resource *res;
	struct clk *clk;
	struct clk_init_data init;

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

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

	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);

	clk = devm_clk_get(dev, "usb_extal");
	if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
		priv->extal = !!clk_get_rate(clk);
		clk_disable_unprepare(clk);
	}
	clk = devm_clk_get(dev, "usb_xtal");
	if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
		priv->xtal = !!clk_get_rate(clk);
		clk_disable_unprepare(clk);
	}

	if (!priv->extal && !priv->xtal) {
		dev_err(dev, "This driver needs usb_extal or usb_xtal\n");
		return -ENOENT;
	}

	platform_set_drvdata(pdev, priv);
	dev_set_drvdata(dev, priv);

	init.name = "rcar_usb2_clock_sel";
	init.ops = &usb2_clock_sel_clock_ops;
	init.flags = 0;
	init.parent_names = NULL;
	init.num_parents = 0;
	priv->hw.init = &init;

	clk = clk_register(NULL, &priv->hw);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw);
}

static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = {
	.suspend	= rcar_usb2_clock_sel_suspend,
	.resume		= rcar_usb2_clock_sel_resume,
};

static struct platform_driver rcar_usb2_clock_sel_driver = {
	.driver		= {
		.name	= "rcar-usb2-clock-sel",
		.of_match_table = rcar_usb2_clock_sel_match,
		.pm	= &rcar_usb2_clock_sel_pm_ops,
	},
	.probe		= rcar_usb2_clock_sel_probe,
	.remove		= rcar_usb2_clock_sel_remove,
};
builtin_platform_driver(rcar_usb2_clock_sel_driver);

MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver");
MODULE_LICENSE("GPL v2");
