18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Pistachio platform setup
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2014 Google, Inc.
68c2ecf20Sopenharmony_ci * Copyright (C) 2016 Imagination Technologies
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/init.h>
108c2ecf20Sopenharmony_ci#include <linux/io.h>
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/of_address.h>
138c2ecf20Sopenharmony_ci#include <linux/of_fdt.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <asm/cacheflush.h>
168c2ecf20Sopenharmony_ci#include <asm/dma-coherence.h>
178c2ecf20Sopenharmony_ci#include <asm/fw/fw.h>
188c2ecf20Sopenharmony_ci#include <asm/mips-boards/generic.h>
198c2ecf20Sopenharmony_ci#include <asm/mips-cps.h>
208c2ecf20Sopenharmony_ci#include <asm/prom.h>
218c2ecf20Sopenharmony_ci#include <asm/smp-ops.h>
228c2ecf20Sopenharmony_ci#include <asm/traps.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * Core revision register decoding
268c2ecf20Sopenharmony_ci * Bits 23 to 20: Major rev
278c2ecf20Sopenharmony_ci * Bits 15 to 8: Minor rev
288c2ecf20Sopenharmony_ci * Bits 7 to 0: Maintenance rev
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci#define PISTACHIO_CORE_REV_REG	0xB81483D0
318c2ecf20Sopenharmony_ci#define PISTACHIO_CORE_REV_A1	0x00100006
328c2ecf20Sopenharmony_ci#define PISTACHIO_CORE_REV_B0	0x00100106
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciconst char *get_system_type(void)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	u32 core_rev;
378c2ecf20Sopenharmony_ci	const char *sys_type;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	core_rev = __raw_readl((const void *)PISTACHIO_CORE_REV_REG);
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	switch (core_rev) {
428c2ecf20Sopenharmony_ci	case PISTACHIO_CORE_REV_B0:
438c2ecf20Sopenharmony_ci		sys_type = "IMG Pistachio SoC (B0)";
448c2ecf20Sopenharmony_ci		break;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	case PISTACHIO_CORE_REV_A1:
478c2ecf20Sopenharmony_ci		sys_type = "IMG Pistachio SoC (A1)";
488c2ecf20Sopenharmony_ci		break;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	default:
518c2ecf20Sopenharmony_ci		sys_type = "IMG Pistachio SoC";
528c2ecf20Sopenharmony_ci		break;
538c2ecf20Sopenharmony_ci	}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	return sys_type;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_civoid __init *plat_get_fdt(void)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	if (fw_arg0 != -2)
618c2ecf20Sopenharmony_ci		panic("Device-tree not present");
628c2ecf20Sopenharmony_ci	return (void *)fw_arg1;
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid __init plat_mem_setup(void)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	__dt_setup_arch(plat_get_fdt());
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define DEFAULT_CPC_BASE_ADDR	0x1bde0000
718c2ecf20Sopenharmony_ci#define DEFAULT_CDMM_BASE_ADDR	0x1bdd0000
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciphys_addr_t mips_cpc_default_phys_base(void)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	return DEFAULT_CPC_BASE_ADDR;
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ciphys_addr_t mips_cdmm_phys_base(void)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	return DEFAULT_CDMM_BASE_ADDR;
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic void __init mips_nmi_setup(void)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	void *base;
868c2ecf20Sopenharmony_ci	extern char except_vec_nmi[];
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	base = cpu_has_veic ?
898c2ecf20Sopenharmony_ci		(void *)(CAC_BASE + 0xa80) :
908c2ecf20Sopenharmony_ci		(void *)(CAC_BASE + 0x380);
918c2ecf20Sopenharmony_ci	memcpy(base, except_vec_nmi, 0x80);
928c2ecf20Sopenharmony_ci	flush_icache_range((unsigned long)base,
938c2ecf20Sopenharmony_ci			   (unsigned long)base + 0x80);
948c2ecf20Sopenharmony_ci}
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_cistatic void __init mips_ejtag_setup(void)
978c2ecf20Sopenharmony_ci{
988c2ecf20Sopenharmony_ci	void *base;
998c2ecf20Sopenharmony_ci	extern char except_vec_ejtag_debug[];
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	base = cpu_has_veic ?
1028c2ecf20Sopenharmony_ci		(void *)(CAC_BASE + 0xa00) :
1038c2ecf20Sopenharmony_ci		(void *)(CAC_BASE + 0x300);
1048c2ecf20Sopenharmony_ci	memcpy(base, except_vec_ejtag_debug, 0x80);
1058c2ecf20Sopenharmony_ci	flush_icache_range((unsigned long)base,
1068c2ecf20Sopenharmony_ci			   (unsigned long)base + 0x80);
1078c2ecf20Sopenharmony_ci}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_civoid __init prom_init(void)
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci	board_nmi_handler_setup = mips_nmi_setup;
1128c2ecf20Sopenharmony_ci	board_ejtag_handler_setup = mips_ejtag_setup;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	mips_cm_probe();
1158c2ecf20Sopenharmony_ci	mips_cpc_probe();
1168c2ecf20Sopenharmony_ci	register_cps_smp_ops();
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	pr_info("SoC Type: %s\n", get_system_type());
1198c2ecf20Sopenharmony_ci}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_civoid __init prom_free_prom_memory(void)
1228c2ecf20Sopenharmony_ci{
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_civoid __init device_tree_init(void)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	if (!initial_boot_params)
1288c2ecf20Sopenharmony_ci		return;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	unflatten_and_copy_device_tree();
1318c2ecf20Sopenharmony_ci}
132