// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2019 Julien Masson <jmasson@baylibre.com>
 * (C) Copyright 2019 Neil Armstrong <narmstrong@baylibre.com>
 */

#include <common.h>
#include <init.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <dm.h>
#include <linux/bitfield.h>
#include <regmap.h>
#include <syscon.h>
#include <linux/bitops.h>
#include <linux/err.h>

#define AO_SEC_SD_CFG8		0xe0
#define AO_SEC_SOCINFO_OFFSET	AO_SEC_SD_CFG8

#define SOCINFO_MAJOR	GENMASK(31, 24)
#define SOCINFO_PACK	GENMASK(23, 16)
#define SOCINFO_MINOR	GENMASK(15, 8)
#define SOCINFO_MISC	GENMASK(7, 0)

static const struct meson_gx_soc_id {
	const char *name;
	unsigned int id;
} soc_ids[] = {
	{ "GXBB",   0x1f },
	{ "GXTVBB", 0x20 },
	{ "GXL",    0x21 },
	{ "GXM",    0x22 },
	{ "TXL",    0x23 },
	{ "TXLX",   0x24 },
	{ "AXG",    0x25 },
	{ "GXLX",   0x26 },
	{ "TXHD",   0x27 },
	{ "G12A",   0x28 },
	{ "G12B",   0x29 },
	{ "SM1",    0x2b },
	{ "A1",	    0x2c },
};

static const struct meson_gx_package_id {
	const char *name;
	unsigned int major_id;
	unsigned int pack_id;
	unsigned int pack_mask;
} soc_packages[] = {
	{ "S905",   0x1f, 0,    0x20 }, /* pack_id != 0x20 */
	{ "S905H",  0x1f, 0x3,  0xf },  /* pack_id & 0xf == 0x3 */
	{ "S905M",  0x1f, 0x20, 0xf0 }, /* pack_id == 0x20 */
	{ "S905D",  0x21, 0,    0xf0 },
	{ "S905X",  0x21, 0x80, 0xf0 },
	{ "S905W",  0x21, 0xa0, 0xf0 },
	{ "S905L",  0x21, 0xc0, 0xf0 },
	{ "S905M2", 0x21, 0xe0, 0xf0 },
	{ "S805X",  0x21, 0x30, 0xf0 },
	{ "S805Y",  0x21, 0xb0, 0xf0 },
	{ "S912",   0x22, 0,    0x0 },  /* Only S912 is known for GXM */
	{ "962X",   0x24, 0x10, 0xf0 },
	{ "962E",   0x24, 0x20, 0xf0 },
	{ "A113X",  0x25, 0x37, 0xff },
	{ "A113D",  0x25, 0x22, 0xff },
	{ "S905D2", 0x28, 0x10, 0xf0 },
	{ "S905Y2", 0x28, 0x30, 0xf0 },
	{ "S905X2", 0x28, 0x40, 0xf0 },
	{ "A311D",  0x29, 0x10, 0xf0 },
	{ "S922X",  0x29, 0x40, 0xf0 },
	{ "S905D3", 0x2b, 0x4, 0xf5 },
	{ "S905X3", 0x2b, 0x5, 0xf5 },
	{ "S905X3", 0x2b, 0x10, 0x3f },
	{ "S905D3", 0x2b, 0x30, 0x3f },
	{ "A113L", 0x2c, 0x0, 0xf8 },
};

DECLARE_GLOBAL_DATA_PTR;

static inline unsigned int socinfo_to_major(u32 socinfo)
{
	return FIELD_GET(SOCINFO_MAJOR, socinfo);
}

static inline unsigned int socinfo_to_minor(u32 socinfo)
{
	return FIELD_GET(SOCINFO_MINOR, socinfo);
}

static inline unsigned int socinfo_to_pack(u32 socinfo)
{
	return FIELD_GET(SOCINFO_PACK, socinfo);
}

static inline unsigned int socinfo_to_misc(u32 socinfo)
{
	return FIELD_GET(SOCINFO_MISC, socinfo);
}

static const char *socinfo_to_package_id(u32 socinfo)
{
	unsigned int pack = socinfo_to_pack(socinfo);
	unsigned int major = socinfo_to_major(socinfo);
	int i;

	for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
		if (soc_packages[i].major_id == major &&
		    soc_packages[i].pack_id ==
		    (pack & soc_packages[i].pack_mask))
			return soc_packages[i].name;
	}

	return "Unknown";
}

static const char *socinfo_to_soc_id(u32 socinfo)
{
	unsigned int id = socinfo_to_major(socinfo);
	int i;

	for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
		if (soc_ids[i].id == id)
			return soc_ids[i].name;
	}

	return "Unknown";
}

static unsigned int get_socinfo(void)
{
	struct regmap *regmap;
	int nodeoffset, ret;
	ofnode node;
	unsigned int socinfo;

	/* find the offset of compatible node */
	nodeoffset = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
						   "amlogic,meson-gx-ao-secure");
	if (nodeoffset < 0)
		return 0;

	/* check if chip-id is available */
	if (!fdt_getprop(gd->fdt_blob, nodeoffset, "amlogic,has-chip-id", NULL))
		return 0;

	/* get regmap from the syscon node */
	node = offset_to_ofnode(nodeoffset);
	regmap = syscon_node_to_regmap(node);
	if (IS_ERR(regmap)) {
		printf("%s: failed to get regmap\n", __func__);
		return 0;
	}

	/* read soc info */
	ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
	if (ret && !socinfo) {
		printf("%s: invalid chipid value\n", __func__);
		return 0;
	}

	return socinfo;
}

int checkboard(void)
{
	unsigned int socinfo;

	socinfo = get_socinfo();
	if (!socinfo)
		return 0;

	printf("SoC:   Amlogic Meson %s (%s) Revision %x:%x (%x:%x)\n",
	       socinfo_to_soc_id(socinfo),
	       socinfo_to_package_id(socinfo),
	       socinfo_to_major(socinfo),
	       socinfo_to_minor(socinfo),
	       socinfo_to_pack(socinfo),
	       socinfo_to_misc(socinfo));

	return 0;
}

int meson_get_soc_rev(char *buff, size_t buff_len)
{
	unsigned int socinfo;

	socinfo = get_socinfo();
	if (!socinfo)
		return -1;

	/* Write SoC info */
	return snprintf(buff, buff_len, "%x", socinfo_to_minor(socinfo));
}
