// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com>
 * Copyright (C) 2015 John Crispin <john@phrozen.org>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sys_soc.h>
#include <linux/memblock.h>

#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
#include <asm/smp-ops.h>
#include <asm/mips-cps.h>
#include <asm/mach-ralink/ralink_regs.h>
#include <asm/mach-ralink/mt7621.h>

#include "common.h"

#define MT7621_MEM_TEST_PATTERN         0xaa5555aa

static u32 detect_magic __initdata;
static struct ralink_soc_info *soc_info_ptr;

phys_addr_t mips_cpc_default_phys_base(void)
{
	panic("Cannot detect cpc address");
}

static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
{
	void *dm = (void *)KSEG1ADDR(&detect_magic);

	if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
		return true;
	__raw_writel(MT7621_MEM_TEST_PATTERN, dm);
	if (__raw_readl(dm) != __raw_readl(dm + size))
		return false;
	__raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
	return __raw_readl(dm) == __raw_readl(dm + size);
}

static void __init mt7621_memory_detect(void)
{
	phys_addr_t size;

	for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
		if (mt7621_addr_wraparound_test(size)) {
			memblock_add(MT7621_LOWMEM_BASE, size);
			return;
		}
	}

	memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
	memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
}

void __init ralink_of_remap(void)
{
	rt_sysc_membase = plat_of_remap_node("mediatek,mt7621-sysc");
	rt_memc_membase = plat_of_remap_node("mediatek,mt7621-memc");

	if (!rt_sysc_membase || !rt_memc_membase)
		panic("Failed to remap core resources");
}

static unsigned int __init mt7621_get_soc_name0(void)
{
	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME0);
}

static unsigned int __init mt7621_get_soc_name1(void)
{
	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_NAME1);
}

static bool __init mt7621_soc_valid(void)
{
	if (mt7621_get_soc_name0() == MT7621_CHIP_NAME0 &&
			mt7621_get_soc_name1() == MT7621_CHIP_NAME1)
		return true;
	else
		return false;
}

static const char __init *mt7621_get_soc_id(void)
{
	if (mt7621_soc_valid())
		return "MT7621";
	else
		return "invalid";
}

static unsigned int __init mt7621_get_soc_rev(void)
{
	return __raw_readl(MT7621_SYSC_BASE + SYSC_REG_CHIP_REV);
}

static unsigned int __init mt7621_get_soc_ver(void)
{
	return (mt7621_get_soc_rev() >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK;
}

static unsigned int __init mt7621_get_soc_eco(void)
{
	return (mt7621_get_soc_rev() & CHIP_REV_ECO_MASK);
}

static const char __init *mt7621_get_soc_revision(void)
{
	if (mt7621_get_soc_rev() == 1 && mt7621_get_soc_eco() == 1)
		return "E2";
	else
		return "E1";
}

static int __init mt7621_soc_dev_init(void)
{
	struct soc_device *soc_dev;
	struct soc_device_attribute *soc_dev_attr;

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

	soc_dev_attr->soc_id = "mt7621";
	soc_dev_attr->family = "Ralink";
	soc_dev_attr->revision = mt7621_get_soc_revision();

	soc_dev_attr->data = soc_info_ptr;

	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree(soc_dev_attr);
		return PTR_ERR(soc_dev);
	}

	return 0;
}
device_initcall(mt7621_soc_dev_init);

void __init prom_soc_init(struct ralink_soc_info *soc_info)
{
	/* Early detection of CMP support */
	mips_cm_probe();
	mips_cpc_probe();

	if (mips_cps_numiocu(0)) {
		/*
		 * mips_cm_probe() wipes out bootloader
		 * config for CM regions and we have to configure them
		 * again. This SoC cannot talk to pamlbus devices
		 * witout proper iocu region set up.
		 *
		 * FIXME: it would be better to do this with values
		 * from DT, but we need this very early because
		 * without this we cannot talk to pretty much anything
		 * including serial.
		 */
		write_gcr_reg0_base(MT7621_PALMBUS_BASE);
		write_gcr_reg0_mask(~MT7621_PALMBUS_SIZE |
				    CM_GCR_REGn_MASK_CMTGT_IOCU0);
		__sync();
	}

	if (mt7621_soc_valid())
		soc_info->compatible = "mediatek,mt7621-soc";
	else
		panic("mt7621: unknown SoC, n0:%08x n1:%08x\n",
				mt7621_get_soc_name0(),
				mt7621_get_soc_name1());
	ralink_soc = MT762X_SOC_MT7621AT;

	snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN,
		"MediaTek %s ver:%u eco:%u",
		mt7621_get_soc_id(),
		mt7621_get_soc_ver(),
		mt7621_get_soc_eco());

	soc_info->mem_detect = mt7621_memory_detect;

	soc_info_ptr = soc_info;

	if (!register_cps_smp_ops())
		return;
	if (!register_cmp_smp_ops())
		return;
	if (!register_vsmp_smp_ops())
		return;
}
