// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2013-2014, 2018 Synopsys, Inc. All rights reserved.
 */

#include <config.h>
#include <clock_legacy.h>
#include <init.h>
#include <malloc.h>
#include <vsprintf.h>
#include <asm/arcregs.h>
#include <asm/cache.h>
#include <asm/global_data.h>
#include <linux/bitops.h>

DECLARE_GLOBAL_DATA_PTR;

int arch_cpu_init(void)
{
	timer_init();

	gd->cpu_clk = get_board_sys_clk();
	gd->ram_size = CFG_SYS_SDRAM_SIZE;

	cache_init();

	return 0;
}

/* This is a dummy function on arc */
int dram_init(void)
{
	return 0;
}

#ifdef CONFIG_DISPLAY_CPUINFO
const char *arc_700_version(int arcver, char *name, int name_len)
{
	const char *arc_ver;

	switch (arcver) {
	case 0x32:
		arc_ver = "v4.4-4.5";
		break;
	case 0x33:
		arc_ver = "v4.6-v4.9";
		break;
	case 0x34:
		arc_ver = "v4.10";
		break;
	case 0x35:
		arc_ver = "v4.11";
		break;
	default:
		arc_ver = "unknown version";
	}

	snprintf(name, name_len, "ARC 700 %s", arc_ver);

	return name;
}

struct em_template_t {
	const bool cache;
	const bool dsp;
	const bool xymem;
	const char name[8];
};

static const struct em_template_t em_versions[] = {
	{false,	false,	false,	"EM4"},
	{true,	false,	false,	"EM6"},
	{false,	true,	false,	"EM5D"},
	{true,	true,	false,	"EM7D"},
	{false,	true,	true,	"EM9D"},
	{true,	true,	true,	"EM11D"},
};

const char *arc_em_version(int arcver, char *name, int name_len)
{
	const char *arc_name = "EM";
	const char *arc_ver;
	bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
	bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
	bool xymem = ARC_FEATURE_EXISTS(ARC_AUX_XY_BUILD);
	int i;

	for (i = 0; i < sizeof(em_versions) / sizeof(struct em_template_t); i++) {
		if (em_versions[i].cache == cache &&
		    em_versions[i].dsp == dsp &&
		    em_versions[i].xymem == xymem) {
			arc_name = em_versions[i].name;
			break;
		}
	}

	switch (arcver) {
	case 0x41:
		arc_ver = "v1.1a";
		break;
	case 0x42:
		arc_ver = "v3.0";
		break;
	case 0x43:
		arc_ver = "v4.0";
		break;
	case 0x44:
		arc_ver = "v5.0";
		break;
	default:
		arc_ver = "unknown version";
	}

	snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);

	return name;
}

struct hs_template_t {
	const bool cache;
	const bool mmu;
	const bool dual_issue;
	const bool dsp;
	const char name[8];
};

static const struct hs_template_t hs_versions[] = {
	{false,	false,	false,	false,	"HS34"},
	{true,	false,	false,	false,	"HS36"},
	{true,	true,	false,	false,	"HS38"},
	{false,	false,	true,	false,	"HS44"},
	{true,	false,	true,	false,	"HS46"},
	{true,	true,	true,	false,	"HS48"},
	{false,	false,	true,	true,	"HS45D"},
	{true,	false,	true,	true,	"HS47D"},
};

const char *arc_hs_version(int arcver, char *name, int name_len)
{
	const char *arc_name = "HS";
	const char *arc_ver;
	bool cache = ARC_FEATURE_EXISTS(ARC_BCR_IC_BUILD);
	bool dsp = ARC_FEATURE_EXISTS(ARC_AUX_DSP_BUILD);
	bool mmu = !!read_aux_reg(ARC_AUX_MMU_BCR);
	bool dual_issue = arcver == 0x54 ? true : false;
	int i;

	for (i = 0; i < sizeof(hs_versions) / sizeof(struct hs_template_t); i++) {
		if (hs_versions[i].cache == cache &&
		    hs_versions[i].mmu == mmu &&
		    hs_versions[i].dual_issue == dual_issue &&
		    hs_versions[i].dsp == dsp) {
			arc_name = hs_versions[i].name;
			break;
		}
	}

	switch (arcver) {
	case 0x50:
		arc_ver = "v1.0";
		break;
	case 0x51:
		arc_ver = "v2.0";
		break;
	case 0x52:
		arc_ver = "v2.1c";
		break;
	case 0x53:
		arc_ver = "v3.0";
		break;
	case 0x54:
		arc_ver = "v4.0";
		break;
	default:
		arc_ver = "unknown version";
	}

	snprintf(name, name_len, "ARC %s %s", arc_name, arc_ver);

	return name;
}

const char *decode_identity(void)
{
#define MAX_CPU_NAME_LEN	64

	int arcver = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
	char *name = malloc(MAX_CPU_NAME_LEN);

	if (arcver >= 0x50)
		return arc_hs_version(arcver, name, MAX_CPU_NAME_LEN);
	else if (arcver >= 0x40)
		return arc_em_version(arcver, name, MAX_CPU_NAME_LEN);
	else if (arcver >= 0x30)
		return arc_700_version(arcver, name, MAX_CPU_NAME_LEN);
	else
		return "Unknown ARC core";
}

const char *decode_subsystem(void)
{
	int subsys_type = read_aux_reg(ARC_AUX_SUBSYS_BUILD) & GENMASK(3, 0);

	switch (subsys_type) {
	case 0: return NULL;
	case 2: return "ARC Sensor & Control IP Subsystem";
	case 3: return "ARC Data Fusion IP Subsystem";
	case 4: return "ARC Secure Subsystem";
	default: return "Unknown subsystem";
	};
}

__weak int print_cpuinfo(void)
{
	const char *subsys_name = decode_subsystem();
	char mhz[8];

	printf("CPU:   %s at %s MHz\n", decode_identity(),
	       strmhz(mhz, gd->cpu_clk));

	if (subsys_name)
		printf("Subsys:%s\n", subsys_name);

	return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
