// SPDX-License-Identifier: GPL-2.0-only
/*
 * Purna Chandra Mandal,<purna.mandal@microchip.com>
 * Copyright (C) 2015 Microchip Technology Inc.  All rights reserved.
 */
#include <dt-bindings/clock/microchip,pic32-clock.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <asm/traps.h>

#include "clk-core.h"

/* FRC Postscaler */
#define OSC_FRCDIV_MASK		0x07
#define OSC_FRCDIV_SHIFT	24

/* SPLL fields */
#define PLL_ICLK_MASK		0x01
#define PLL_ICLK_SHIFT		7

#define DECLARE_PERIPHERAL_CLOCK(__clk_name, __reg, __flags)	\
	{							\
		.ctrl_reg = (__reg),				\
		.init_data = {					\
			.name = (__clk_name),			\
			.parent_names = (const char *[]) {	\
				"sys_clk"			\
			},					\
			.num_parents = 1,			\
			.ops = &pic32_pbclk_ops,		\
			.flags = (__flags),			\
		},						\
	}

#define DECLARE_REFO_CLOCK(__clkid, __reg)				\
	{								\
		.ctrl_reg = (__reg),					\
		.init_data = {						\
			.name = "refo" #__clkid "_clk",			\
			.parent_names = (const char *[]) {		\
				"sys_clk", "pb1_clk", "posc_clk",	\
				"frc_clk", "lprc_clk", "sosc_clk",	\
				"sys_pll", "refi" #__clkid "_clk",	\
				"bfrc_clk",				\
			},						\
			.num_parents = 9,				\
			.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE,\
			.ops = &pic32_roclk_ops,			\
		},							\
		.parent_map = (const u32[]) {				\
			0, 1, 2, 3, 4, 5, 7, 8, 9			\
		},							\
	}

static const struct pic32_ref_osc_data ref_clks[] = {
	DECLARE_REFO_CLOCK(1, 0x80),
	DECLARE_REFO_CLOCK(2, 0xa0),
	DECLARE_REFO_CLOCK(3, 0xc0),
	DECLARE_REFO_CLOCK(4, 0xe0),
	DECLARE_REFO_CLOCK(5, 0x100),
};

static const struct pic32_periph_clk_data periph_clocks[] = {
	DECLARE_PERIPHERAL_CLOCK("pb1_clk", 0x140, 0),
	DECLARE_PERIPHERAL_CLOCK("pb2_clk", 0x150, CLK_IGNORE_UNUSED),
	DECLARE_PERIPHERAL_CLOCK("pb3_clk", 0x160, 0),
	DECLARE_PERIPHERAL_CLOCK("pb4_clk", 0x170, 0),
	DECLARE_PERIPHERAL_CLOCK("pb5_clk", 0x180, 0),
	DECLARE_PERIPHERAL_CLOCK("pb6_clk", 0x190, 0),
	DECLARE_PERIPHERAL_CLOCK("cpu_clk", 0x1a0, CLK_IGNORE_UNUSED),
};

static const struct pic32_sys_clk_data sys_mux_clk = {
	.slew_reg = 0x1c0,
	.slew_div = 2, /* step of div_4 -> div_2 -> no_div */
	.init_data = {
		.name = "sys_clk",
		.parent_names = (const char *[]) {
			"frcdiv_clk", "sys_pll", "posc_clk",
			"sosc_clk", "lprc_clk", "frcdiv_clk",
		},
		.num_parents = 6,
		.ops = &pic32_sclk_ops,
	},
	.parent_map = (const u32[]) {
		0, 1, 2, 4, 5, 7,
	},
};

static const struct pic32_sys_pll_data sys_pll = {
	.ctrl_reg = 0x020,
	.status_reg = 0x1d0,
	.lock_mask = BIT(7),
	.init_data = {
		.name = "sys_pll",
		.parent_names = (const char *[]) {
			"spll_mux_clk"
		},
		.num_parents = 1,
		.ops = &pic32_spll_ops,
	},
};

static const struct pic32_sec_osc_data sosc_clk = {
	.status_reg = 0x1d0,
	.enable_mask = BIT(1),
	.status_mask = BIT(4),
	.fixed_rate = 32768,
	.init_data = {
		.name = "sosc_clk",
		.parent_names = NULL,
		.ops = &pic32_sosc_ops,
	},
};

static int pic32mzda_critical_clks[] = {
	PB2CLK, PB7CLK
};

/* PIC32MZDA clock data */
struct pic32mzda_clk_data {
	struct clk *clks[MAXCLKS];
	struct pic32_clk_common core;
	struct clk_onecell_data onecell_data;
	struct notifier_block failsafe_notifier;
};

static int pic32_fscm_nmi(struct notifier_block *nb,
			  unsigned long action, void *data)
{
	struct pic32mzda_clk_data *cd;

	cd  = container_of(nb, struct pic32mzda_clk_data, failsafe_notifier);

	/* SYSCLK is now running from BFRCCLK. Report clock failure. */
	if (readl(cd->core.iobase) & BIT(2))
		pr_alert("pic32-clk: FSCM detected clk failure.\n");

	/* TODO: detect reason of failure and recover accordingly */

	return NOTIFY_OK;
}

static int pic32mzda_clk_probe(struct platform_device *pdev)
{
	const char *const pll_mux_parents[] = {"posc_clk", "frc_clk"};
	struct device_node *np = pdev->dev.of_node;
	struct pic32mzda_clk_data *cd;
	struct pic32_clk_common *core;
	struct clk *pll_mux_clk, *clk;
	struct clk **clks;
	int nr_clks, i, ret;

	cd = devm_kzalloc(&pdev->dev, sizeof(*cd), GFP_KERNEL);
	if (!cd)
		return -ENOMEM;

	core = &cd->core;
	core->iobase = of_io_request_and_map(np, 0, of_node_full_name(np));
	if (IS_ERR(core->iobase)) {
		dev_err(&pdev->dev, "pic32-clk: failed to map registers\n");
		return PTR_ERR(core->iobase);
	}

	spin_lock_init(&core->reg_lock);
	core->dev = &pdev->dev;
	clks = &cd->clks[0];

	/* register fixed rate clocks */
	clks[POSCCLK] = clk_register_fixed_rate(&pdev->dev, "posc_clk", NULL,
						0, 24000000);
	clks[FRCCLK] =  clk_register_fixed_rate(&pdev->dev, "frc_clk", NULL,
						0, 8000000);
	clks[BFRCCLK] = clk_register_fixed_rate(&pdev->dev, "bfrc_clk", NULL,
						0, 8000000);
	clks[LPRCCLK] = clk_register_fixed_rate(&pdev->dev, "lprc_clk", NULL,
						0, 32000);
	clks[UPLLCLK] = clk_register_fixed_rate(&pdev->dev, "usbphy_clk", NULL,
						0, 24000000);
	/* fixed rate (optional) clock */
	if (of_find_property(np, "microchip,pic32mzda-sosc", NULL)) {
		pr_info("pic32-clk: dt requests SOSC.\n");
		clks[SOSCCLK] = pic32_sosc_clk_register(&sosc_clk, core);
	}
	/* divider clock */
	clks[FRCDIVCLK] = clk_register_divider(&pdev->dev, "frcdiv_clk",
					       "frc_clk", 0,
					       core->iobase,
					       OSC_FRCDIV_SHIFT,
					       OSC_FRCDIV_MASK,
					       CLK_DIVIDER_POWER_OF_TWO,
					       &core->reg_lock);
	/* PLL ICLK mux */
	pll_mux_clk = clk_register_mux(&pdev->dev, "spll_mux_clk",
				       pll_mux_parents, 2, 0,
				       core->iobase + 0x020,
				       PLL_ICLK_SHIFT, 1, 0, &core->reg_lock);
	if (IS_ERR(pll_mux_clk))
		pr_err("spll_mux_clk: clk register failed\n");

	/* PLL */
	clks[PLLCLK] = pic32_spll_clk_register(&sys_pll, core);
	/* SYSTEM clock */
	clks[SCLK] = pic32_sys_clk_register(&sys_mux_clk, core);
	/* Peripheral bus clocks */
	for (nr_clks = PB1CLK, i = 0; nr_clks <= PB7CLK; i++, nr_clks++)
		clks[nr_clks] = pic32_periph_clk_register(&periph_clocks[i],
							  core);
	/* Reference oscillator clock */
	for (nr_clks = REF1CLK, i = 0; nr_clks <= REF5CLK; i++, nr_clks++)
		clks[nr_clks] = pic32_refo_clk_register(&ref_clks[i], core);

	/* register clkdev */
	for (i = 0; i < MAXCLKS; i++) {
		if (IS_ERR(clks[i]))
			continue;
		clk_register_clkdev(clks[i], NULL, __clk_get_name(clks[i]));
	}

	/* register clock provider */
	cd->onecell_data.clks = clks;
	cd->onecell_data.clk_num = MAXCLKS;
	ret = of_clk_add_provider(np, of_clk_src_onecell_get,
				  &cd->onecell_data);
	if (ret)
		return ret;

	/* force enable critical clocks */
	for (i = 0; i < ARRAY_SIZE(pic32mzda_critical_clks); i++) {
		clk = clks[pic32mzda_critical_clks[i]];
		if (clk_prepare_enable(clk))
			dev_err(&pdev->dev, "clk_prepare_enable(%s) failed\n",
				__clk_get_name(clk));
	}

	/* register NMI for failsafe clock monitor */
	cd->failsafe_notifier.notifier_call = pic32_fscm_nmi;
	return register_nmi_notifier(&cd->failsafe_notifier);
}

static const struct of_device_id pic32mzda_clk_match_table[] = {
	{ .compatible = "microchip,pic32mzda-clk", },
	{ }
};
MODULE_DEVICE_TABLE(of, pic32mzda_clk_match_table);

static struct platform_driver pic32mzda_clk_driver = {
	.probe		= pic32mzda_clk_probe,
	.driver		= {
		.name	= "clk-pic32mzda",
		.of_match_table = pic32mzda_clk_match_table,
	},
};

static int __init microchip_pic32mzda_clk_init(void)
{
	return platform_driver_register(&pic32mzda_clk_driver);
}
core_initcall(microchip_pic32mzda_clk_init);

MODULE_DESCRIPTION("Microchip PIC32MZDA Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:clk-pic32mzda");
