init.c 3.7 KB
Newer Older
1 2 3 4
/*
 * Pistachio platform setup
 *
 * Copyright (C) 2014 Google, Inc.
5
 * Copyright (C) 2016 Imagination Technologies
6 7 8 9 10 11 12
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 */

#include <linux/init.h>
13
#include <linux/io.h>
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#include <linux/kernel.h>
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/of_platform.h>

#include <asm/cacheflush.h>
#include <asm/dma-coherence.h>
#include <asm/fw/fw.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-cm.h>
#include <asm/mips-cpc.h>
#include <asm/prom.h>
#include <asm/smp-ops.h>
#include <asm/traps.h>

29 30 31 32 33 34 35 36 37 38
/*
 * Core revision register decoding
 * Bits 23 to 20: Major rev
 * Bits 15 to 8: Minor rev
 * Bits 7 to 0: Maintenance rev
 */
#define PISTACHIO_CORE_REV_REG	0xB81483D0
#define PISTACHIO_CORE_REV_A1	0x00100006
#define PISTACHIO_CORE_REV_B0	0x00100106

39 40
const char *get_system_type(void)
{
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
	u32 core_rev;
	const char *sys_type;

	core_rev = __raw_readl((const void *)PISTACHIO_CORE_REV_REG);

	switch (core_rev) {
	case PISTACHIO_CORE_REV_B0:
		sys_type = "IMG Pistachio SoC (B0)";
		break;

	case PISTACHIO_CORE_REV_A1:
		sys_type = "IMG Pistachio SoC (A1)";
		break;

	default:
		sys_type = "IMG Pistachio SoC";
		break;
	}

	return sys_type;
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
}

static void __init plat_setup_iocoherency(void)
{
	/*
	 * Kernel has been configured with software coherency
	 * but we might choose to turn it off and use hardware
	 * coherency instead.
	 */
	if (mips_cm_numiocu() != 0) {
		/* Nothing special needs to be done to enable coherency */
		pr_info("CMP IOCU detected\n");
		hw_coherentio = 1;
		if (coherentio == 0)
			pr_info("Hardware DMA cache coherency disabled\n");
		else
			pr_info("Hardware DMA cache coherency enabled\n");
	} else {
		if (coherentio == 1)
			pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n");
		else
			pr_info("Software DMA cache coherency enabled\n");
	}
}

M
Matt Redfearn 已提交
86
void __init *plat_get_fdt(void)
87 88 89
{
	if (fw_arg0 != -2)
		panic("Device-tree not present");
M
Matt Redfearn 已提交
90 91
	return (void *)fw_arg1;
}
92

M
Matt Redfearn 已提交
93 94 95
void __init plat_mem_setup(void)
{
	__dt_setup_arch(plat_get_fdt());
96 97 98 99

	plat_setup_iocoherency();
}

100 101
#define DEFAULT_CPC_BASE_ADDR	0x1bde0000
#define DEFAULT_CDMM_BASE_ADDR	0x1bdd0000
102 103 104 105 106 107

phys_addr_t mips_cpc_default_phys_base(void)
{
	return DEFAULT_CPC_BASE_ADDR;
}

108 109 110 111 112
phys_addr_t mips_cdmm_phys_base(void)
{
	return DEFAULT_CDMM_BASE_ADDR;
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
static void __init mips_nmi_setup(void)
{
	void *base;
	extern char except_vec_nmi;

	base = cpu_has_veic ?
		(void *)(CAC_BASE + 0xa80) :
		(void *)(CAC_BASE + 0x380);
	memcpy(base, &except_vec_nmi, 0x80);
	flush_icache_range((unsigned long)base,
			   (unsigned long)base + 0x80);
}

static void __init mips_ejtag_setup(void)
{
	void *base;
	extern char except_vec_ejtag_debug;

	base = cpu_has_veic ?
		(void *)(CAC_BASE + 0xa00) :
		(void *)(CAC_BASE + 0x300);
	memcpy(base, &except_vec_ejtag_debug, 0x80);
	flush_icache_range((unsigned long)base,
			   (unsigned long)base + 0x80);
}

void __init prom_init(void)
{
	board_nmi_handler_setup = mips_nmi_setup;
	board_ejtag_handler_setup = mips_ejtag_setup;

	mips_cm_probe();
	mips_cpc_probe();
	register_cps_smp_ops();
147 148

	pr_info("SoC Type: %s\n", get_system_type());
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
}

void __init prom_free_prom_memory(void)
{
}

void __init device_tree_init(void)
{
	if (!initial_boot_params)
		return;

	unflatten_and_copy_device_tree();
}

static int __init plat_of_setup(void)
{
	if (!of_have_populated_dt())
		panic("Device tree not present");

	if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL))
		panic("Failed to populate DT");

	return 0;
}
arch_initcall(plat_of_setup);