// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.xyz>
 */

#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>

#include "ccu_common.h"
#include "ccu_reset.h"

#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_mp.h"
#include "ccu_nm.h"

#include "ccu-sun50i-h6-r.h"

/*
 * Information about AR100 and AHB/APB clocks in R_CCU are gathered from
 * clock definitions in the BSP source code.
 */

static const char * const ar100_r_apb2_parents[] = { "osc24M", "osc32k",
						     "iosc", "pll-periph0" };
static const struct ccu_mux_var_prediv ar100_r_apb2_predivs[] = {
	{ .index = 3, .shift = 0, .width = 5 },
};

static struct ccu_div ar100_clk = {
	.div		= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),

	.mux		= {
		.shift	= 24,
		.width	= 2,

		.var_predivs	= ar100_r_apb2_predivs,
		.n_var_predivs	= ARRAY_SIZE(ar100_r_apb2_predivs),
	},

	.common		= {
		.reg		= 0x000,
		.features	= CCU_FEATURE_VARIABLE_PREDIV,
		.hw.init	= CLK_HW_INIT_PARENTS("ar100",
						      ar100_r_apb2_parents,
						      &ccu_div_ops,
						      0),
	},
};

static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &ar100_clk.common.hw, 1, 1, 0);

static SUNXI_CCU_M(r_apb1_clk, "r-apb1", "r-ahb", 0x00c, 0, 2, 0);

static struct ccu_div r_apb2_clk = {
	.div		= _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),

	.mux		= {
		.shift	= 24,
		.width	= 2,

		.var_predivs	= ar100_r_apb2_predivs,
		.n_var_predivs	= ARRAY_SIZE(ar100_r_apb2_predivs),
	},

	.common		= {
		.reg		= 0x010,
		.features	= CCU_FEATURE_VARIABLE_PREDIV,
		.hw.init	= CLK_HW_INIT_PARENTS("r-apb2",
						      ar100_r_apb2_parents,
						      &ccu_div_ops,
						      0),
	},
};

/*
 * Information about the gate/resets are gathered from the clock header file
 * in the BSP source code, although most of them are unused. The existence
 * of the hardware block is verified with "3.1 Memory Mapping" chapter in
 * "Allwinner H6 V200 User Manual V1.1"; and the parent APB buses are verified
 * with "3.3.2.1 System Bus Tree" chapter inthe same document.
 */
static SUNXI_CCU_GATE(r_apb1_timer_clk,	"r-apb1-timer",	"r-apb1",
		      0x11c, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb1_twd_clk,	"r-apb1-twd",	"r-apb1",
		      0x12c, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb1_pwm_clk,	"r-apb1-pwm",	"r-apb1",
		      0x13c, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb2_uart_clk,	"r-apb2-uart",	"r-apb2",
		      0x18c, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb2_i2c_clk,	"r-apb2-i2c",	"r-apb2",
		      0x19c, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb2_rsb_clk,	"r-apb2-rsb",	"r-apb2",
		      0x1bc, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb1_ir_clk,	"r-apb1-ir",	"r-apb1",
		      0x1cc, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb1_w1_clk,	"r-apb1-w1",	"r-apb1",
		      0x1ec, BIT(0), 0);
static SUNXI_CCU_GATE(r_apb1_rtc_clk,	"r-apb1-rtc",	"r-apb1",
		      0x20c, BIT(0), CLK_IGNORE_UNUSED);

/* Information of IR(RX) mod clock is gathered from BSP source code */
static const char * const r_mod0_default_parents[] = { "osc32k", "osc24M" };
static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir",
				  r_mod0_default_parents, 0x1c0,
				  0, 5,		/* M */
				  8, 2,		/* P */
				  24, 1,	/* mux */
				  BIT(31),	/* gate */
				  0);

/*
 * BSP didn't use the 1-wire function at all now, and the information about
 * this mod clock is guessed from the IR mod clock above. The existence of
 * this mod clock is proven by BSP clock header, and the dividers are verified
 * by contents in the 1-wire related chapter of the User Manual.
 */

static SUNXI_CCU_MP_WITH_MUX_GATE(w1_clk, "w1",
				  r_mod0_default_parents, 0x1e0,
				  0, 5,		/* M */
				  8, 2,		/* P */
				  24, 1,	/* mux */
				  BIT(31),	/* gate */
				  0);

static struct ccu_common *sun50i_h6_r_ccu_clks[] = {
	&ar100_clk.common,
	&r_apb1_clk.common,
	&r_apb2_clk.common,
	&r_apb1_timer_clk.common,
	&r_apb1_twd_clk.common,
	&r_apb1_pwm_clk.common,
	&r_apb2_uart_clk.common,
	&r_apb2_i2c_clk.common,
	&r_apb2_rsb_clk.common,
	&r_apb1_ir_clk.common,
	&r_apb1_w1_clk.common,
	&ir_clk.common,
	&w1_clk.common,
};

static struct ccu_common *sun50i_h616_r_ccu_clks[] = {
	&r_apb1_clk.common,
	&r_apb2_clk.common,
	&r_apb1_twd_clk.common,
	&r_apb2_i2c_clk.common,
	&r_apb2_rsb_clk.common,
	&r_apb1_ir_clk.common,
	&r_apb1_rtc_clk.common,
	&ir_clk.common,
};

static struct clk_hw_onecell_data sun50i_h6_r_hw_clks = {
	.hws	= {
		[CLK_AR100]		= &ar100_clk.common.hw,
		[CLK_R_AHB]		= &r_ahb_clk.hw,
		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
		[CLK_R_APB1_TIMER]	= &r_apb1_timer_clk.common.hw,
		[CLK_R_APB1_TWD]	= &r_apb1_twd_clk.common.hw,
		[CLK_R_APB1_PWM]	= &r_apb1_pwm_clk.common.hw,
		[CLK_R_APB2_UART]	= &r_apb2_uart_clk.common.hw,
		[CLK_R_APB2_I2C]	= &r_apb2_i2c_clk.common.hw,
		[CLK_R_APB2_RSB]	= &r_apb2_rsb_clk.common.hw,
		[CLK_R_APB1_IR]		= &r_apb1_ir_clk.common.hw,
		[CLK_R_APB1_W1]		= &r_apb1_w1_clk.common.hw,
		[CLK_R_APB1_RTC]	= &r_apb1_rtc_clk.common.hw,
		[CLK_IR]		= &ir_clk.common.hw,
		[CLK_W1]		= &w1_clk.common.hw,
	},
	.num	= CLK_NUMBER,
};

static struct clk_hw_onecell_data sun50i_h616_r_hw_clks = {
	.hws	= {
		[CLK_R_AHB]		= &r_ahb_clk.hw,
		[CLK_R_APB1]		= &r_apb1_clk.common.hw,
		[CLK_R_APB2]		= &r_apb2_clk.common.hw,
		[CLK_R_APB1_TWD]	= &r_apb1_twd_clk.common.hw,
		[CLK_R_APB2_I2C]	= &r_apb2_i2c_clk.common.hw,
		[CLK_R_APB2_RSB]	= &r_apb2_rsb_clk.common.hw,
		[CLK_R_APB1_IR]		= &r_apb1_ir_clk.common.hw,
		[CLK_R_APB1_RTC]	= &r_apb1_rtc_clk.common.hw,
		[CLK_IR]		= &ir_clk.common.hw,
	},
	.num	= CLK_NUMBER,
};

static struct ccu_reset_map sun50i_h6_r_ccu_resets[] = {
	[RST_R_APB1_TIMER]	=  { 0x11c, BIT(16) },
	[RST_R_APB1_TWD]	=  { 0x12c, BIT(16) },
	[RST_R_APB1_PWM]	=  { 0x13c, BIT(16) },
	[RST_R_APB2_UART]	=  { 0x18c, BIT(16) },
	[RST_R_APB2_I2C]	=  { 0x19c, BIT(16) },
	[RST_R_APB2_RSB]	=  { 0x1bc, BIT(16) },
	[RST_R_APB1_IR]		=  { 0x1cc, BIT(16) },
	[RST_R_APB1_W1]		=  { 0x1ec, BIT(16) },
};

static struct ccu_reset_map sun50i_h616_r_ccu_resets[] = {
	[RST_R_APB1_TWD]	=  { 0x12c, BIT(16) },
	[RST_R_APB2_I2C]	=  { 0x19c, BIT(16) },
	[RST_R_APB2_RSB]	=  { 0x1bc, BIT(16) },
	[RST_R_APB1_IR]		=  { 0x1cc, BIT(16) },
};

static const struct sunxi_ccu_desc sun50i_h6_r_ccu_desc = {
	.ccu_clks	= sun50i_h6_r_ccu_clks,
	.num_ccu_clks	= ARRAY_SIZE(sun50i_h6_r_ccu_clks),

	.hw_clks	= &sun50i_h6_r_hw_clks,

	.resets		= sun50i_h6_r_ccu_resets,
	.num_resets	= ARRAY_SIZE(sun50i_h6_r_ccu_resets),
};

static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
	.ccu_clks	= sun50i_h616_r_ccu_clks,
	.num_ccu_clks	= ARRAY_SIZE(sun50i_h616_r_ccu_clks),

	.hw_clks	= &sun50i_h616_r_hw_clks,

	.resets		= sun50i_h616_r_ccu_resets,
	.num_resets	= ARRAY_SIZE(sun50i_h616_r_ccu_resets),
};

static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
{
	const struct sunxi_ccu_desc *desc;
	void __iomem *reg;

	desc = of_device_get_match_data(&pdev->dev);
	if (!desc)
		return -EINVAL;

	reg = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(reg))
		return PTR_ERR(reg);

	return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
}

static const struct of_device_id sun50i_h6_r_ccu_ids[] = {
	{
		.compatible = "allwinner,sun50i-h6-r-ccu",
		.data = &sun50i_h6_r_ccu_desc,
	},
	{
		.compatible = "allwinner,sun50i-h616-r-ccu",
		.data = &sun50i_h616_r_ccu_desc,
	},
	{ }
};

static struct platform_driver sun50i_h6_r_ccu_driver = {
	.probe	= sun50i_h6_r_ccu_probe,
	.driver	= {
		.name			= "sun50i-h6-r-ccu",
		.suppress_bind_attrs	= true,
		.of_match_table		= sun50i_h6_r_ccu_ids,
	},
};
module_platform_driver(sun50i_h6_r_ccu_driver);

MODULE_IMPORT_NS(SUNXI_CCU);
MODULE_LICENSE("GPL");
