// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for the ICST307 VCO clock found in the ARM Reference designs.
 * We wrap the custom interface from <asm/hardware/icst.h> into the generic
 * clock framework.
 *
 * Copyright (C) 2012-2015 Linus Walleij
 *
 * TODO: when all ARM reference designs are migrated to generic clocks, the
 * ICST clock code from the ARM tree should probably be merged into this
 * file.
 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>

#include "icst.h"
#include "clk-icst.h"

/* Magic unlocking token used on all Versatile boards */
#define VERSATILE_LOCK_VAL	0xA05F

#define VERSATILE_AUX_OSC_BITS 0x7FFFF
#define INTEGRATOR_AP_CM_BITS 0xFF
#define INTEGRATOR_AP_SYS_BITS 0xFF
#define INTEGRATOR_CP_CM_CORE_BITS 0x7FF
#define INTEGRATOR_CP_CM_MEM_BITS 0x7FF000

#define INTEGRATOR_AP_PCI_25_33_MHZ BIT(8)

/**
 * struct clk_icst - ICST VCO clock wrapper
 * @hw: corresponding clock hardware entry
 * @map: register map
 * @vcoreg_off: VCO register address
 * @lockreg_off: VCO lock register address
 * @params: parameters for this ICST instance
 * @rate: current rate
 * @ctype: the type of control register for the ICST
 */
struct clk_icst {
	struct clk_hw hw;
	struct regmap *map;
	u32 vcoreg_off;
	u32 lockreg_off;
	struct icst_params *params;
	unsigned long rate;
	enum icst_control_type ctype;
};

#define to_icst(_hw) container_of(_hw, struct clk_icst, hw)

/**
 * vco_get() - get ICST VCO settings from a certain ICST
 * @icst: the ICST clock to get
 * @vco: the VCO struct to return the value in
 */
static int vco_get(struct clk_icst *icst, struct icst_vco *vco)
{
	u32 val;
	int ret;

	ret = regmap_read(icst->map, icst->vcoreg_off, &val);
	if (ret)
		return ret;

	/*
	 * The Integrator/AP core clock can only access the low eight
	 * bits of the v PLL divider. Bit 8 is tied low and always zero,
	 * r is hardwired to 22 and output divider s is hardwired to 1
	 * (divide by 2) according to the document
	 * "Integrator CM926EJ-S, CM946E-S, CM966E-S, CM1026EJ-S and
	 * CM1136JF-S User Guide" ARM DUI 0138E, page 3-13 thru 3-14.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_CM) {
		vco->v = val & INTEGRATOR_AP_CM_BITS;
		vco->r = 22;
		vco->s = 1;
		return 0;
	}

	/*
	 * The Integrator/AP system clock on the base board can only
	 * access the low eight bits of the v PLL divider. Bit 8 is tied low
	 * and always zero, r is hardwired to 46, and the output divider is
	 * hardwired to 3 (divide by 4) according to the document
	 * "Integrator AP ASIC Development Motherboard" ARM DUI 0098B,
	 * page 3-16.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
		vco->v = val & INTEGRATOR_AP_SYS_BITS;
		vco->r = 46;
		vco->s = 3;
		return 0;
	}

	/*
	 * The Integrator/AP PCI clock is using an odd pattern to create
	 * the child clock, basically a single bit called DIVX/Y is used
	 * to select between two different hardwired values: setting the
	 * bit to 0 yields v = 17, r = 22 and OD = 1, whereas setting the
	 * bit to 1 yields v = 14, r = 14 and OD = 1 giving the frequencies
	 * 33 or 25 MHz respectively.
	 */
	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
		bool divxy = !!(val & INTEGRATOR_AP_PCI_25_33_MHZ);

		vco->v = divxy ? 17 : 14;
		vco->r = divxy ? 22 : 14;
		vco->s = 1;
		return 0;
	}

	/*
	 * The Integrator/CP core clock can access the low eight bits
	 * of the v PLL divider. Bit 8 is tied low and always zero,
	 * r is hardwired to 22 and the output divider s is accessible
	 * in bits 8 thru 10 according to the document
	 * "Integrator/CM940T, CM920T, CM740T, and CM720T User Guide"
	 * ARM DUI 0157A, page 3-20 thru 3-23 and 4-10.
	 */
	if (icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
		vco->v = val & 0xFF;
		vco->r = 22;
		vco->s = (val >> 8) & 7;
		return 0;
	}

	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
		vco->v = (val >> 12) & 0xFF;
		vco->r = 22;
		vco->s = (val >> 20) & 7;
		return 0;
	}

	vco->v = val & 0x1ff;
	vco->r = (val >> 9) & 0x7f;
	vco->s = (val >> 16) & 03;
	return 0;
}

/**
 * vco_set() - commit changes to an ICST VCO
 * @icst: the ICST clock to set
 * @vco: the VCO struct to set the changes from
 */
static int vco_set(struct clk_icst *icst, struct icst_vco vco)
{
	u32 mask;
	u32 val;
	int ret;

	/* Mask the bits used by the VCO */
	switch (icst->ctype) {
	case ICST_INTEGRATOR_AP_CM:
		mask = INTEGRATOR_AP_CM_BITS;
		val = vco.v & 0xFF;
		if (vco.v & 0x100)
			pr_err("ICST error: tried to set bit 8 of VDW\n");
		if (vco.s != 1)
			pr_err("ICST error: tried to use VOD != 1\n");
		if (vco.r != 22)
			pr_err("ICST error: tried to use RDW != 22\n");
		break;
	case ICST_INTEGRATOR_AP_SYS:
		mask = INTEGRATOR_AP_SYS_BITS;
		val = vco.v & 0xFF;
		if (vco.v & 0x100)
			pr_err("ICST error: tried to set bit 8 of VDW\n");
		if (vco.s != 3)
			pr_err("ICST error: tried to use VOD != 1\n");
		if (vco.r != 46)
			pr_err("ICST error: tried to use RDW != 22\n");
		break;
	case ICST_INTEGRATOR_CP_CM_CORE:
		mask = INTEGRATOR_CP_CM_CORE_BITS; /* Uses 12 bits */
		val = (vco.v & 0xFF) | vco.s << 8;
		if (vco.v & 0x100)
			pr_err("ICST error: tried to set bit 8 of VDW\n");
		if (vco.r != 22)
			pr_err("ICST error: tried to use RDW != 22\n");
		break;
	case ICST_INTEGRATOR_CP_CM_MEM:
		mask = INTEGRATOR_CP_CM_MEM_BITS; /* Uses 12 bits */
		val = ((vco.v & 0xFF) << 12) | (vco.s << 20);
		if (vco.v & 0x100)
			pr_err("ICST error: tried to set bit 8 of VDW\n");
		if (vco.r != 22)
			pr_err("ICST error: tried to use RDW != 22\n");
		break;
	default:
		/* Regular auxilary oscillator */
		mask = VERSATILE_AUX_OSC_BITS;
		val = vco.v | (vco.r << 9) | (vco.s << 16);
		break;
	}

	pr_debug("ICST: new val = 0x%08x\n", val);

	/* This magic unlocks the VCO so it can be controlled */
	ret = regmap_write(icst->map, icst->lockreg_off, VERSATILE_LOCK_VAL);
	if (ret)
		return ret;
	ret = regmap_update_bits(icst->map, icst->vcoreg_off, mask, val);
	if (ret)
		return ret;
	/* This locks the VCO again */
	ret = regmap_write(icst->map, icst->lockreg_off, 0);
	if (ret)
		return ret;
	return 0;
}

static unsigned long icst_recalc_rate(struct clk_hw *hw,
				      unsigned long parent_rate)
{
	struct clk_icst *icst = to_icst(hw);
	struct icst_vco vco;
	int ret;

	if (parent_rate)
		icst->params->ref = parent_rate;
	ret = vco_get(icst, &vco);
	if (ret) {
		pr_err("ICST: could not get VCO setting\n");
		return 0;
	}
	icst->rate = icst_hz(icst->params, vco);
	return icst->rate;
}

static long icst_round_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long *prate)
{
	struct clk_icst *icst = to_icst(hw);
	struct icst_vco vco;

	if (icst->ctype == ICST_INTEGRATOR_AP_CM ||
	    icst->ctype == ICST_INTEGRATOR_CP_CM_CORE) {
		if (rate <= 12000000)
			return 12000000;
		if (rate >= 160000000)
			return 160000000;
		/* Slam to closest megahertz */
		return DIV_ROUND_CLOSEST(rate, 1000000) * 1000000;
	}

	if (icst->ctype == ICST_INTEGRATOR_CP_CM_MEM) {
		if (rate <= 6000000)
			return 6000000;
		if (rate >= 66000000)
			return 66000000;
		/* Slam to closest 0.5 megahertz */
		return DIV_ROUND_CLOSEST(rate, 500000) * 500000;
	}

	if (icst->ctype == ICST_INTEGRATOR_AP_SYS) {
		/* Divides between 3 and 50 MHz in steps of 0.25 MHz */
		if (rate <= 3000000)
			return 3000000;
		if (rate >= 50000000)
			return 5000000;
		/* Slam to closest 0.25 MHz */
		return DIV_ROUND_CLOSEST(rate, 250000) * 250000;
	}

	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
		/*
		 * If we're below or less than halfway from 25 to 33 MHz
		 * select 25 MHz
		 */
		if (rate <= 25000000 || rate < 29000000)
			return 25000000;
		/* Else just return the default frequency */
		return 33000000;
	}

	vco = icst_hz_to_vco(icst->params, rate);
	return icst_hz(icst->params, vco);
}

static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
			 unsigned long parent_rate)
{
	struct clk_icst *icst = to_icst(hw);
	struct icst_vco vco;

	if (icst->ctype == ICST_INTEGRATOR_AP_PCI) {
		/* This clock is especially primitive */
		unsigned int val;
		int ret;

		if (rate == 25000000) {
			val = 0;
		} else if (rate == 33000000) {
			val = INTEGRATOR_AP_PCI_25_33_MHZ;
		} else {
			pr_err("ICST: cannot set PCI frequency %lu\n",
			       rate);
			return -EINVAL;
		}
		ret = regmap_write(icst->map, icst->lockreg_off,
				   VERSATILE_LOCK_VAL);
		if (ret)
			return ret;
		ret = regmap_update_bits(icst->map, icst->vcoreg_off,
					 INTEGRATOR_AP_PCI_25_33_MHZ,
					 val);
		if (ret)
			return ret;
		/* This locks the VCO again */
		ret = regmap_write(icst->map, icst->lockreg_off, 0);
		if (ret)
			return ret;
		return 0;
	}

	if (parent_rate)
		icst->params->ref = parent_rate;
	vco = icst_hz_to_vco(icst->params, rate);
	icst->rate = icst_hz(icst->params, vco);
	return vco_set(icst, vco);
}

static const struct clk_ops icst_ops = {
	.recalc_rate = icst_recalc_rate,
	.round_rate = icst_round_rate,
	.set_rate = icst_set_rate,
};

struct clk *icst_clk_setup(struct device *dev,
			   const struct clk_icst_desc *desc,
			   const char *name,
			   const char *parent_name,
			   struct regmap *map,
			   enum icst_control_type ctype)
{
	struct clk *clk;
	struct clk_icst *icst;
	struct clk_init_data init;
	struct icst_params *pclone;

	icst = kzalloc(sizeof(*icst), GFP_KERNEL);
	if (!icst)
		return ERR_PTR(-ENOMEM);

	pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
	if (!pclone) {
		kfree(icst);
		return ERR_PTR(-ENOMEM);
	}

	init.name = name;
	init.ops = &icst_ops;
	init.flags = 0;
	init.parent_names = (parent_name ? &parent_name : NULL);
	init.num_parents = (parent_name ? 1 : 0);
	icst->map = map;
	icst->hw.init = &init;
	icst->params = pclone;
	icst->vcoreg_off = desc->vco_offset;
	icst->lockreg_off = desc->lock_offset;
	icst->ctype = ctype;

	clk = clk_register(dev, &icst->hw);
	if (IS_ERR(clk)) {
		kfree(pclone);
		kfree(icst);
	}

	return clk;
}
EXPORT_SYMBOL_GPL(icst_clk_setup);

struct clk *icst_clk_register(struct device *dev,
			const struct clk_icst_desc *desc,
			const char *name,
			const char *parent_name,
			void __iomem *base)
{
	struct regmap_config icst_regmap_conf = {
		.reg_bits = 32,
		.val_bits = 32,
		.reg_stride = 4,
	};
	struct regmap *map;

	map = regmap_init_mmio(dev, base, &icst_regmap_conf);
	if (IS_ERR(map)) {
		pr_err("could not initialize ICST regmap\n");
		return ERR_CAST(map);
	}
	return icst_clk_setup(dev, desc, name, parent_name, map,
			      ICST_VERSATILE);
}
EXPORT_SYMBOL_GPL(icst_clk_register);

#ifdef CONFIG_OF
/*
 * In a device tree, an memory-mapped ICST clock appear as a child
 * of a syscon node. Assume this and probe it only as a child of a
 * syscon.
 */

static const struct icst_params icst525_params = {
	.vco_max	= ICST525_VCO_MAX_5V,
	.vco_min	= ICST525_VCO_MIN,
	.vd_min		= 8,
	.vd_max		= 263,
	.rd_min		= 3,
	.rd_max		= 65,
	.s2div		= icst525_s2div,
	.idx2s		= icst525_idx2s,
};

static const struct icst_params icst307_params = {
	.vco_max	= ICST307_VCO_MAX,
	.vco_min	= ICST307_VCO_MIN,
	.vd_min		= 4 + 8,
	.vd_max		= 511 + 8,
	.rd_min		= 1 + 2,
	.rd_max		= 127 + 2,
	.s2div		= icst307_s2div,
	.idx2s		= icst307_idx2s,
};

/*
 * The core modules on the Integrator/AP and Integrator/CP have
 * especially crippled ICST525 control.
 */
static const struct icst_params icst525_apcp_cm_params = {
	.vco_max	= ICST525_VCO_MAX_5V,
	.vco_min	= ICST525_VCO_MIN,
	/* Minimum 12 MHz, VDW = 4 */
	.vd_min		= 12,
	/*
	 * Maximum 160 MHz, VDW = 152 for all core modules, but
	 * CM926EJ-S, CM1026EJ-S and CM1136JF-S can actually
	 * go to 200 MHz (max VDW = 192).
	 */
	.vd_max		= 192,
	/* r is hardcoded to 22 and this is the actual divisor, +2 */
	.rd_min		= 24,
	.rd_max		= 24,
	.s2div		= icst525_s2div,
	.idx2s		= icst525_idx2s,
};

static const struct icst_params icst525_ap_sys_params = {
	.vco_max	= ICST525_VCO_MAX_5V,
	.vco_min	= ICST525_VCO_MIN,
	/* Minimum 3 MHz, VDW = 4 */
	.vd_min		= 3,
	/* Maximum 50 MHz, VDW = 192 */
	.vd_max		= 50,
	/* r is hardcoded to 46 and this is the actual divisor, +2 */
	.rd_min		= 48,
	.rd_max		= 48,
	.s2div		= icst525_s2div,
	.idx2s		= icst525_idx2s,
};

static const struct icst_params icst525_ap_pci_params = {
	.vco_max	= ICST525_VCO_MAX_5V,
	.vco_min	= ICST525_VCO_MIN,
	/* Minimum 25 MHz */
	.vd_min		= 25,
	/* Maximum 33 MHz */
	.vd_max		= 33,
	/* r is hardcoded to 14 or 22 and this is the actual divisors +2 */
	.rd_min		= 16,
	.rd_max		= 24,
	.s2div		= icst525_s2div,
	.idx2s		= icst525_idx2s,
};

static void __init of_syscon_icst_setup(struct device_node *np)
{
	struct device_node *parent;
	struct regmap *map;
	struct clk_icst_desc icst_desc;
	const char *name;
	const char *parent_name;
	struct clk *regclk;
	enum icst_control_type ctype;

	/* We do not release this reference, we are using it perpetually */
	parent = of_get_parent(np);
	if (!parent) {
		pr_err("no parent node for syscon ICST clock\n");
		return;
	}
	map = syscon_node_to_regmap(parent);
	if (IS_ERR(map)) {
		pr_err("no regmap for syscon ICST clock parent\n");
		return;
	}

	if (of_property_read_u32(np, "reg", &icst_desc.vco_offset) &&
	    of_property_read_u32(np, "vco-offset", &icst_desc.vco_offset)) {
		pr_err("no VCO register offset for ICST clock\n");
		return;
	}
	if (of_property_read_u32(np, "lock-offset", &icst_desc.lock_offset)) {
		pr_err("no lock register offset for ICST clock\n");
		return;
	}

	if (of_device_is_compatible(np, "arm,syscon-icst525")) {
		icst_desc.params = &icst525_params;
		ctype = ICST_VERSATILE;
	} else if (of_device_is_compatible(np, "arm,syscon-icst307")) {
		icst_desc.params = &icst307_params;
		ctype = ICST_VERSATILE;
	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-cm")) {
		icst_desc.params = &icst525_apcp_cm_params;
		ctype = ICST_INTEGRATOR_AP_CM;
	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-sys")) {
		icst_desc.params = &icst525_ap_sys_params;
		ctype = ICST_INTEGRATOR_AP_SYS;
	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorap-pci")) {
		icst_desc.params = &icst525_ap_pci_params;
		ctype = ICST_INTEGRATOR_AP_PCI;
	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-core")) {
		icst_desc.params = &icst525_apcp_cm_params;
		ctype = ICST_INTEGRATOR_CP_CM_CORE;
	} else if (of_device_is_compatible(np, "arm,syscon-icst525-integratorcp-cm-mem")) {
		icst_desc.params = &icst525_apcp_cm_params;
		ctype = ICST_INTEGRATOR_CP_CM_MEM;
	} else {
		pr_err("unknown ICST clock %pOF\n", np);
		return;
	}

	/* Parent clock name is not the same as node parent */
	parent_name = of_clk_get_parent_name(np, 0);
	name = kasprintf(GFP_KERNEL, "%pOFP", np);

	regclk = icst_clk_setup(NULL, &icst_desc, name, parent_name, map, ctype);
	if (IS_ERR(regclk)) {
		kfree(name);
		pr_err("error setting up syscon ICST clock %s\n", name);
		return;
	}
	of_clk_add_provider(np, of_clk_src_simple_get, regclk);
	pr_debug("registered syscon ICST clock %s\n", name);
}

CLK_OF_DECLARE(arm_syscon_icst525_clk,
	       "arm,syscon-icst525", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_icst307_clk,
	       "arm,syscon-icst307", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_integratorap_cm_clk,
	       "arm,syscon-icst525-integratorap-cm", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_integratorap_sys_clk,
	       "arm,syscon-icst525-integratorap-sys", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_integratorap_pci_clk,
	       "arm,syscon-icst525-integratorap-pci", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_integratorcp_cm_core_clk,
	       "arm,syscon-icst525-integratorcp-cm-core", of_syscon_icst_setup);
CLK_OF_DECLARE(arm_syscon_integratorcp_cm_mem_clk,
	       "arm,syscon-icst525-integratorcp-cm-mem", of_syscon_icst_setup);
#endif
