1 /*
2  * sys_info.c
3  *
4  * System information functions
5  *
6  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
7  *
8  * Derived from Beagle Board and 3430 SDP code by
9  *      Richard Woodruff <r-woodruff2@ti.com>
10  *      Syed Mohammed Khasim <khasim@ti.com>
11  *
12  * SPDX-License-Identifier:	GPL-2.0+
13  */
14 
15 #include <common.h>
16 #include <asm/io.h>
17 #include <asm/arch/sys_proto.h>
18 #include <asm/arch/cpu.h>
19 #include <asm/arch/clock.h>
20 #include <power/tps65910.h>
21 #include <linux/compiler.h>
22 
23 struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
24 
25 /**
26  * get_cpu_rev(void) - extract rev info
27  */
28 u32 get_cpu_rev(void)
29 {
30 	u32 id;
31 	u32 rev;
32 
33 	id = readl(DEVICE_ID);
34 	rev = (id >> 28) & 0xff;
35 
36 	return rev;
37 }
38 
39 /**
40  * get_cpu_type(void) - extract cpu info
41  */
42 u32 get_cpu_type(void)
43 {
44 	u32 id = 0;
45 	u32 partnum;
46 
47 	id = readl(DEVICE_ID);
48 	partnum = (id >> 12) & 0xffff;
49 
50 	return partnum;
51 }
52 
53 /**
54  * get_device_type(): tell if GP/HS/EMU/TST
55  */
56 u32 get_device_type(void)
57 {
58 	int mode;
59 	mode = readl(&cstat->statusreg) & (DEVICE_MASK);
60 	return mode >>= 8;
61 }
62 
63 /**
64  * get_sysboot_value(void) - return SYS_BOOT[4:0]
65  */
66 u32 get_sysboot_value(void)
67 {
68 	return readl(&cstat->statusreg) & SYSBOOT_MASK;
69 }
70 
71 #ifdef CONFIG_DISPLAY_CPUINFO
72 static char *cpu_revs[] = {
73 		"1.0",
74 		"2.0",
75 		"2.1"};
76 
77 static char *cpu_revs_am43xx[] = {
78 		"1.0",
79 		"1.1",
80 		"1.2"};
81 
82 static char *dev_types[] = {
83 		"TST",
84 		"EMU",
85 		"HS",
86 		"GP"};
87 
88 /**
89  * Print CPU information
90  */
91 int print_cpuinfo(void)
92 {
93 	char *cpu_s, *sec_s, *rev_s;
94 	char **cpu_rev_arr = cpu_revs;
95 
96 	switch (get_cpu_type()) {
97 	case AM335X:
98 		cpu_s = "AM335X";
99 		break;
100 	case TI81XX:
101 		cpu_s = "TI81XX";
102 		break;
103 	case AM437X:
104 		cpu_s = "AM437X";
105 		cpu_rev_arr = cpu_revs_am43xx;
106 		break;
107 	default:
108 		cpu_s = "Unknown CPU type";
109 		break;
110 	}
111 
112 	if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
113 		rev_s = cpu_rev_arr[get_cpu_rev()];
114 	else
115 		rev_s = "?";
116 
117 	if (get_device_type() < ARRAY_SIZE(dev_types))
118 		sec_s = dev_types[get_device_type()];
119 	else
120 		sec_s = "?";
121 
122 	printf("CPU  : %s-%s rev %s\n", cpu_s, sec_s, rev_s);
123 
124 	return 0;
125 }
126 #endif	/* CONFIG_DISPLAY_CPUINFO */
127 
128 #ifdef CONFIG_AM33XX
129 int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev)
130 {
131 	int sil_rev;
132 
133 	sil_rev = readl(&cdev->deviceid) >> 28;
134 
135 	if (sil_rev == 1)
136 		/* PG 2.0, efuse may not be set. */
137 		return MPUPLL_M_800;
138 	else if (sil_rev >= 2) {
139 		/* Check what the efuse says our max speed is. */
140 		int efuse_arm_mpu_max_freq;
141 		efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
142 		switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) {
143 		case AM335X_ZCZ_1000:
144 			return MPUPLL_M_1000;
145 		case AM335X_ZCZ_800:
146 			return MPUPLL_M_800;
147 		case AM335X_ZCZ_720:
148 			return MPUPLL_M_720;
149 		case AM335X_ZCZ_600:
150 		case AM335X_ZCE_600:
151 			return MPUPLL_M_600;
152 		case AM335X_ZCZ_300:
153 		case AM335X_ZCE_300:
154 			return MPUPLL_M_300;
155 		}
156 	}
157 
158 	/* PG 1.0 or otherwise unknown, use the PG1.0 max */
159 	return MPUPLL_M_720;
160 }
161 
162 int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
163 {
164 	/* For PG2.1 and later, we have one set of values. */
165 	if (sil_rev >= 2) {
166 		switch (frequency) {
167 		case MPUPLL_M_1000:
168 			return TPS65910_OP_REG_SEL_1_3_2_5;
169 		case MPUPLL_M_800:
170 			return TPS65910_OP_REG_SEL_1_2_6;
171 		case MPUPLL_M_720:
172 			return TPS65910_OP_REG_SEL_1_2_0;
173 		case MPUPLL_M_600:
174 		case MPUPLL_M_300:
175 			return TPS65910_OP_REG_SEL_1_1_3;
176 		}
177 	}
178 
179 	/* Default to PG1.0/PG2.0 values. */
180 	return TPS65910_OP_REG_SEL_1_1_3;
181 }
182 #endif
183