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

#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));
}
