summaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/cpu/cpuinfo.c
blob: ef2f49471a2a069a9efe6c11c56653387d0186cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
/*
 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2007-2009 PetaLogix
 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License. See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/clk.h>
#include <linux/init.h>
#include <asm/cpuinfo.h>
#include <asm/pvr.h>

const struct cpu_ver_key cpu_ver_lookup[] = {
	/* These key value are as per MBV field in PVR0 */
	{"5.00.a", 0x01},
	{"5.00.b", 0x02},
	{"5.00.c", 0x03},
	{"6.00.a", 0x04},
	{"6.00.b", 0x06},
	{"7.00.a", 0x05},
	{"7.00.b", 0x07},
	{"7.10.a", 0x08},
	{"7.10.b", 0x09},
	{"7.10.c", 0x0a},
	{"7.10.d", 0x0b},
	{"7.20.a", 0x0c},
	{"7.20.b", 0x0d},
	{"7.20.c", 0x0e},
	{"7.20.d", 0x0f},
	{"7.30.a", 0x10},
	{"7.30.b", 0x11},
	{"8.00.a", 0x12},
	{"8.00.b", 0x13},
	{"8.10.a", 0x14},
	{"8.20.a", 0x15},
	{"8.20.b", 0x16},
	{"8.30.a", 0x17},
	{"8.40.a", 0x18},
	{"8.40.b", 0x19},
	{"8.50.a", 0x1a},
	{"8.50.b", 0x1c},
	{"8.50.c", 0x1e},
	{"9.0", 0x1b},
	{"9.1", 0x1d},
	{"9.2", 0x1f},
	{"9.3", 0x20},
	{"9.4", 0x21},
	{"9.5", 0x22},
	{"9.6", 0x23},
	{"10.0", 0x24},
	{NULL, 0},
};

/*
 * FIXME Not sure if the actual key is defined by Xilinx in the PVR
 */
const struct family_string_key family_string_lookup[] = {
	{"virtex2", 0x4},
	{"virtex2pro", 0x5},
	{"spartan3", 0x6},
	{"virtex4", 0x7},
	{"virtex5", 0x8},
	{"spartan3e", 0x9},
	{"spartan3a", 0xa},
	{"spartan3an", 0xb},
	{"spartan3adsp", 0xc},
	{"spartan6", 0xd},
	{"virtex6", 0xe},
	{"virtex7", 0xf},
	/* FIXME There is no key code defined for spartan2 */
	{"spartan2", 0xf0},
	{"kintex7", 0x10},
	{"artix7", 0x11},
	{"zynq7000", 0x12},
	{"UltraScale Virtex", 0x13},
	{"UltraScale Kintex", 0x14},
	{"UltraScale+ Zynq", 0x15},
	{"UltraScale+ Virtex", 0x16},
	{"UltraScale+ Kintex", 0x17},
	{"Spartan7", 0x18},
	{NULL, 0},
};

struct cpuinfo cpuinfo;
static struct device_node *cpu;

void __init setup_cpuinfo(void)
{
	cpu = of_get_cpu_node(0, NULL);
	if (!cpu)
		pr_err("You don't have cpu or are missing cpu reg property!!!\n");

	pr_info("%s: initialising\n", __func__);

	switch (cpu_has_pvr()) {
	case 0:
		pr_warn("%s: No PVR support. Using static CPU info from FDT\n",
			__func__);
		set_cpuinfo_static(&cpuinfo, cpu);
		break;
/* FIXME I found weird behavior with MB 7.00.a/b 7.10.a
 * please do not use FULL PVR with MMU */
	case 1:
		pr_info("%s: Using full CPU PVR support\n",
			__func__);
		set_cpuinfo_static(&cpuinfo, cpu);
		set_cpuinfo_pvr_full(&cpuinfo, cpu);
		break;
	default:
		pr_warn("%s: Unsupported PVR setting\n", __func__);
		set_cpuinfo_static(&cpuinfo, cpu);
	}

	if (cpuinfo.mmu_privins)
		pr_warn("%s: Stream instructions enabled"
			" - USERSPACE CAN LOCK THIS KERNEL!\n", __func__);

	of_node_put(cpu);
}

void __init setup_cpuinfo_clk(void)
{
	struct clk *clk;

	clk = of_clk_get(cpu, 0);
	if (IS_ERR(clk)) {
		pr_err("ERROR: CPU CCF input clock not found\n");
		/* take timebase-frequency from DTS */
		cpuinfo.cpu_clock_freq = fcpu(cpu, "timebase-frequency");
	} else {
		cpuinfo.cpu_clock_freq = clk_get_rate(clk);
	}

	if (!cpuinfo.cpu_clock_freq) {
		pr_err("ERROR: CPU clock frequency not setup\n");
		BUG();
	}
}