// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2018
 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
 */

#include <common.h>
#include <bitfield.h>
#include <clk.h>
#include <cpu.h>
#include <dm.h>

#include "mpc83xx_cpu.h"

/**
 * struct mpc83xx_cpu_priv - Private data for MPC83xx CPUs
 * @e300_type:      The e300 core type of the MPC83xx CPU
 * @family:         The MPC83xx family the CPU belongs to
 * @type:           The MPC83xx type of the CPU
 * @is_e_processor: Flag indicating whether the CPU is a E processor or not
 * @is_a_variant:   Flag indicating whtther the CPU is a A variant or not
 * @revid:          The revision ID of the CPU
 * @revid.major:    The major part of the CPU's revision ID
 * @revid.minor:    The minor part of the CPU's revision ID
 */
struct mpc83xx_cpu_priv {
	enum e300_type e300_type;
	enum mpc83xx_cpu_family family;
	enum mpc83xx_cpu_type type;
	bool is_e_processor;
	bool is_a_variant;
	struct {
		uint major;
		uint minor;
	} revid;
};

int checkcpu(void)
{
	/* Activate all CPUs  from board_f.c */
	return cpu_probe_all();
}

/**
 * get_spridr() - Read SPRIDR (System Part and Revision ID Register) of CPU
 *
 * Return: The SPRIDR value
 */
static inline u32 get_spridr(void)
{
	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;

	return in_be32(&immr->sysconf.spridr);
}

/**
 * determine_type() - Determine CPU family of MPC83xx device
 * @dev: CPU device from which to read CPU family from
 */
static inline void determine_family(struct udevice *dev)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	/* Upper 12 bits of PARTID field (bits 0-23 in SPRIDR) */
	const u32 PARTID_FAMILY_MASK = 0xFFF00000;

	switch (bitfield_extract_by_mask(get_spridr(), PARTID_FAMILY_MASK)) {
	case 0x810:
	case 0x811:
		priv->family = FAMILY_830X;
		break;
	case 0x80B:
		priv->family = FAMILY_831X;
		break;
	case 0x806:
		priv->family = FAMILY_832X;
		break;
	case 0x803:
		priv->family = FAMILY_834X;
		break;
	case 0x804:
		priv->family = FAMILY_836X;
		break;
	case 0x80C:
		priv->family = FAMILY_837X;
		break;
	default:
		priv->family = FAMILY_UNKNOWN;
	}
}

/**
 * determine_type() - Determine CPU type of MPC83xx device
 * @dev: CPU device from which to read CPU type from
 */
static inline void determine_type(struct udevice *dev)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	/* Upper 16 bits of PVR (Processor Version Register) */
	const u32 PCR_UPPER_MASK = 0xFFFF0000;
	u32 val;

	val = bitfield_extract_by_mask(get_spridr(), PCR_UPPER_MASK);

	/* Mask out E-variant bit */
	switch (val & 0xFFFE) {
	case 0x8100:
		priv->type = TYPE_8308;
		break;
	case 0x8110:
		priv->type = TYPE_8309;
		break;
	case 0x80B2:
		priv->type = TYPE_8311;
		break;
	case 0x80B0:
		priv->type = TYPE_8313;
		break;
	case 0x80B6:
		priv->type = TYPE_8314;
		break;
	case 0x80B4:
		priv->type = TYPE_8315;
		break;
	case 0x8066:
		priv->type = TYPE_8321;
		break;
	case 0x8062:
		priv->type = TYPE_8323;
		break;
	case 0x8036:
		priv->type = TYPE_8343;
		break;
	case 0x8032:
		priv->type = TYPE_8347_TBGA;
		break;
	case 0x8034:
		priv->type = TYPE_8347_PBGA;
		break;
	case 0x8030:
		priv->type = TYPE_8349;
		break;
	case 0x804A:
		priv->type = TYPE_8358_TBGA;
		break;
	case 0x804E:
		priv->type = TYPE_8358_PBGA;
		break;
	case 0x8048:
		priv->type = TYPE_8360;
		break;
	case 0x80C6:
		priv->type = TYPE_8377;
		break;
	case 0x80C4:
		priv->type = TYPE_8378;
		break;
	case 0x80C2:
		priv->type = TYPE_8379;
		break;
	default:
		priv->type = TYPE_UNKNOWN;
	}
}

/**
 * determine_e300_type() - Determine e300 core type of MPC83xx device
 * @dev: CPU device from which to read e300 core type from
 */
static inline void determine_e300_type(struct udevice *dev)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	/* Upper 16 bits of PVR (Processor Version Register) */
	const u32 PCR_UPPER_MASK = 0xFFFF0000;
	u32 pvr = get_pvr();

	switch ((pvr & PCR_UPPER_MASK) >> 16) {
	case 0x8083:
		priv->e300_type = E300C1;
		break;
	case 0x8084:
		priv->e300_type = E300C2;
		break;
	case 0x8085:
		priv->e300_type = E300C3;
		break;
	case 0x8086:
		priv->e300_type = E300C4;
		break;
	default:
		priv->e300_type = E300_UNKNOWN;
	}
}

/**
 * determine_revid() - Determine revision ID of CPU device
 * @dev: CPU device from which to read revision ID
 */
static inline void determine_revid(struct udevice *dev)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	u32 REVID_MAJOR_MASK;
	u32 REVID_MINOR_MASK;
	u32 spridr = get_spridr();

	if (priv->family == FAMILY_834X) {
		REVID_MAJOR_MASK = 0x0000FF00;
		REVID_MINOR_MASK = 0x000000FF;
	} else {
		REVID_MAJOR_MASK = 0x000000F0;
		REVID_MINOR_MASK = 0x0000000F;
	}

	priv->revid.major = bitfield_extract_by_mask(spridr, REVID_MAJOR_MASK);
	priv->revid.minor = bitfield_extract_by_mask(spridr, REVID_MINOR_MASK);
}

/**
 * determine_cpu_data() - Determine CPU information from hardware
 * @dev: CPU device from which to read information
 */
static void determine_cpu_data(struct udevice *dev)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	const u32 E_FLAG_MASK = 0x00010000;
	u32 spridr = get_spridr();

	determine_family(dev);
	determine_type(dev);
	determine_e300_type(dev);
	determine_revid(dev);

	if ((priv->family == FAMILY_834X ||
	     priv->family == FAMILY_836X) && priv->revid.major >= 2)
		priv->is_a_variant = true;

	priv->is_e_processor = !bitfield_extract_by_mask(spridr, E_FLAG_MASK);
}

static int mpc83xx_cpu_get_desc(struct udevice *dev, char *buf, int size)
{
	struct mpc83xx_cpu_priv *priv = dev_get_priv(dev);
	struct clk core_clk;
	struct clk csb_clk;
	char core_freq[32];
	char csb_freq[32];
	int ret;

	ret = clk_get_by_index(dev, 0, &core_clk);
	if (ret) {
		debug("%s: Failed to get core clock (err = %d)\n",
		      dev->name, ret);
		return ret;
	}

	ret = clk_get_by_index(dev, 1, &csb_clk);
	if (ret) {
		debug("%s: Failed to get CSB clock (err = %d)\n",
		      dev->name, ret);
		return ret;
	}

	determine_cpu_data(dev);

	snprintf(buf, size,
		 "%s, MPC%s%s%s, Rev: %d.%d at %s MHz, CSB: %s MHz",
		 e300_names[priv->e300_type],
		 cpu_type_names[priv->type],
		 priv->is_e_processor ? "E" : "",
		 priv->is_a_variant ? "A" : "",
		 priv->revid.major,
		 priv->revid.minor,
		 strmhz(core_freq, clk_get_rate(&core_clk)),
		 strmhz(csb_freq, clk_get_rate(&csb_clk)));

	return 0;
}

static int mpc83xx_cpu_get_info(struct udevice *dev, struct cpu_info *info)
{
	struct clk clock;
	int ret;
	ulong freq;

	ret = clk_get_by_index(dev, 0, &clock);
	if (ret) {
		debug("%s: Failed to get core clock (err = %d)\n",
		      dev->name, ret);
		return ret;
	}

	freq = clk_get_rate(&clock);
	if (!freq) {
		debug("%s: Core clock speed is zero\n", dev->name);
		return -EINVAL;
	}

	info->cpu_freq = freq;
	info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);

	return 0;
}

static int mpc83xx_cpu_get_count(struct udevice *dev)
{
	/* We have one e300cX core */
	return 1;
}

static int mpc83xx_cpu_get_vendor(struct udevice *dev, char *buf, int size)
{
	snprintf(buf, size, "NXP");

	return 0;
}

static const struct cpu_ops mpc83xx_cpu_ops = {
	.get_desc = mpc83xx_cpu_get_desc,
	.get_info = mpc83xx_cpu_get_info,
	.get_count = mpc83xx_cpu_get_count,
	.get_vendor = mpc83xx_cpu_get_vendor,
};

static int mpc83xx_cpu_probe(struct udevice *dev)
{
	return 0;
}

static const struct udevice_id mpc83xx_cpu_ids[] = {
	{ .compatible = "fsl,mpc83xx", },
	{ .compatible = "fsl,mpc8308", },
	{ .compatible = "fsl,mpc8309", },
	{ .compatible = "fsl,mpc8313", },
	{ .compatible = "fsl,mpc8315", },
	{ .compatible = "fsl,mpc832x", },
	{ .compatible = "fsl,mpc8349", },
	{ .compatible = "fsl,mpc8360", },
	{ .compatible = "fsl,mpc8379", },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(mpc83xx_cpu) = {
	.name = "mpc83xx_cpu",
	.id = UCLASS_CPU,
	.of_match = mpc83xx_cpu_ids,
	.probe = mpc83xx_cpu_probe,
	.priv_auto_alloc_size = sizeof(struct mpc83xx_cpu_priv),
	.ops = &mpc83xx_cpu_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
