1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2983e3700STom Rini /*
3983e3700STom Rini  * sys_info.c
4983e3700STom Rini  *
5983e3700STom Rini  * System information functions
6983e3700STom Rini  *
7983e3700STom Rini  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
8983e3700STom Rini  *
9983e3700STom Rini  * Derived from Beagle Board and 3430 SDP code by
10983e3700STom Rini  *      Richard Woodruff <r-woodruff2@ti.com>
11983e3700STom Rini  *      Syed Mohammed Khasim <khasim@ti.com>
12983e3700STom Rini  */
13983e3700STom Rini 
14983e3700STom Rini #include <common.h>
15983e3700STom Rini #include <asm/io.h>
16983e3700STom Rini #include <asm/arch/sys_proto.h>
17983e3700STom Rini #include <asm/arch/cpu.h>
18983e3700STom Rini #include <asm/arch/clock.h>
19983e3700STom Rini #include <power/tps65910.h>
20983e3700STom Rini #include <linux/compiler.h>
21983e3700STom Rini 
22983e3700STom Rini struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
23983e3700STom Rini 
24983e3700STom Rini /**
25983e3700STom Rini  * get_cpu_rev(void) - extract rev info
26983e3700STom Rini  */
get_cpu_rev(void)27983e3700STom Rini u32 get_cpu_rev(void)
28983e3700STom Rini {
29983e3700STom Rini 	u32 id;
30983e3700STom Rini 	u32 rev;
31983e3700STom Rini 
32983e3700STom Rini 	id = readl(DEVICE_ID);
33983e3700STom Rini 	rev = (id >> 28) & 0xff;
34983e3700STom Rini 
35983e3700STom Rini 	return rev;
36983e3700STom Rini }
37983e3700STom Rini 
38983e3700STom Rini /**
39983e3700STom Rini  * get_cpu_type(void) - extract cpu info
40983e3700STom Rini  */
get_cpu_type(void)41983e3700STom Rini u32 get_cpu_type(void)
42983e3700STom Rini {
43983e3700STom Rini 	u32 id = 0;
44983e3700STom Rini 	u32 partnum;
45983e3700STom Rini 
46983e3700STom Rini 	id = readl(DEVICE_ID);
47983e3700STom Rini 	partnum = (id >> 12) & 0xffff;
48983e3700STom Rini 
49983e3700STom Rini 	return partnum;
50983e3700STom Rini }
51983e3700STom Rini 
52983e3700STom Rini /**
53983e3700STom Rini  * get_sysboot_value(void) - return SYS_BOOT[4:0]
54983e3700STom Rini  */
get_sysboot_value(void)55983e3700STom Rini u32 get_sysboot_value(void)
56983e3700STom Rini {
57983e3700STom Rini 	return readl(&cstat->statusreg) & SYSBOOT_MASK;
58983e3700STom Rini }
59983e3700STom Rini 
get_sys_clk_index(void)60fbd6295dSLokesh Vutla u32 get_sys_clk_index(void)
61fbd6295dSLokesh Vutla {
62fbd6295dSLokesh Vutla 	struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
63fbd6295dSLokesh Vutla 	u32 ind = readl(&ctrl->statusreg);
64fbd6295dSLokesh Vutla 
65fbd6295dSLokesh Vutla #ifdef CONFIG_AM43XX
66fbd6295dSLokesh Vutla 	u32 src;
67fbd6295dSLokesh Vutla 	src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
68fbd6295dSLokesh Vutla 	if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
69fbd6295dSLokesh Vutla 		return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
70fbd6295dSLokesh Vutla 			CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
71fbd6295dSLokesh Vutla 	else /* Value read from SYS BOOT pins */
72fbd6295dSLokesh Vutla #endif
73fbd6295dSLokesh Vutla 		return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
74fbd6295dSLokesh Vutla 			CTRL_SYSBOOT_15_14_SHIFT);
75fbd6295dSLokesh Vutla }
76fbd6295dSLokesh Vutla 
77fbd6295dSLokesh Vutla 
78983e3700STom Rini #ifdef CONFIG_DISPLAY_CPUINFO
79983e3700STom Rini static char *cpu_revs[] = {
80983e3700STom Rini 		"1.0",
81983e3700STom Rini 		"2.0",
82983e3700STom Rini 		"2.1"};
83983e3700STom Rini 
84a051a99fSTero Kristo static char *cpu_revs_am43xx[] = {
85a051a99fSTero Kristo 		"1.0",
86a051a99fSTero Kristo 		"1.1",
87a051a99fSTero Kristo 		"1.2"};
88983e3700STom Rini 
89983e3700STom Rini static char *dev_types[] = {
90983e3700STom Rini 		"TST",
91983e3700STom Rini 		"EMU",
92983e3700STom Rini 		"HS",
93983e3700STom Rini 		"GP"};
94983e3700STom Rini 
95983e3700STom Rini /**
96983e3700STom Rini  * Print CPU information
97983e3700STom Rini  */
print_cpuinfo(void)98983e3700STom Rini int print_cpuinfo(void)
99983e3700STom Rini {
100983e3700STom Rini 	char *cpu_s, *sec_s, *rev_s;
101a051a99fSTero Kristo 	char **cpu_rev_arr = cpu_revs;
102983e3700STom Rini 
103983e3700STom Rini 	switch (get_cpu_type()) {
104983e3700STom Rini 	case AM335X:
105983e3700STom Rini 		cpu_s = "AM335X";
106983e3700STom Rini 		break;
107983e3700STom Rini 	case TI81XX:
108983e3700STom Rini 		cpu_s = "TI81XX";
109983e3700STom Rini 		break;
110983e3700STom Rini 	case AM437X:
111983e3700STom Rini 		cpu_s = "AM437X";
112a051a99fSTero Kristo 		cpu_rev_arr = cpu_revs_am43xx;
113983e3700STom Rini 		break;
114983e3700STom Rini 	default:
115983e3700STom Rini 		cpu_s = "Unknown CPU type";
116983e3700STom Rini 		break;
117983e3700STom Rini 	}
118983e3700STom Rini 
119983e3700STom Rini 	if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
120a051a99fSTero Kristo 		rev_s = cpu_rev_arr[get_cpu_rev()];
121983e3700STom Rini 	else
122983e3700STom Rini 		rev_s = "?";
123983e3700STom Rini 
124983e3700STom Rini 	if (get_device_type() < ARRAY_SIZE(dev_types))
125983e3700STom Rini 		sec_s = dev_types[get_device_type()];
126983e3700STom Rini 	else
127983e3700STom Rini 		sec_s = "?";
128983e3700STom Rini 
129983e3700STom Rini 	printf("CPU  : %s-%s rev %s\n", cpu_s, sec_s, rev_s);
130983e3700STom Rini 
131983e3700STom Rini 	return 0;
132983e3700STom Rini }
133983e3700STom Rini #endif	/* CONFIG_DISPLAY_CPUINFO */
134983e3700STom Rini 
135983e3700STom Rini #ifdef CONFIG_AM33XX
am335x_get_efuse_mpu_max_freq(struct ctrl_dev * cdev)136983e3700STom Rini int am335x_get_efuse_mpu_max_freq(struct ctrl_dev *cdev)
137983e3700STom Rini {
138983e3700STom Rini 	int sil_rev;
139983e3700STom Rini 
140983e3700STom Rini 	sil_rev = readl(&cdev->deviceid) >> 28;
141983e3700STom Rini 
14259041a50SLokesh Vutla 	if (sil_rev == 0) {
14359041a50SLokesh Vutla 		/* No efuse in PG 1.0. Use max speed */
14459041a50SLokesh Vutla 		return MPUPLL_M_720;
14559041a50SLokesh Vutla 	} else if (sil_rev >= 1) {
146983e3700STom Rini 		/* Check what the efuse says our max speed is. */
14759041a50SLokesh Vutla 		int efuse_arm_mpu_max_freq, package_type;
148983e3700STom Rini 		efuse_arm_mpu_max_freq = readl(&cdev->efuse_sma);
14959041a50SLokesh Vutla 		package_type = (efuse_arm_mpu_max_freq & PACKAGE_TYPE_MASK) >>
15059041a50SLokesh Vutla 				PACKAGE_TYPE_SHIFT;
15159041a50SLokesh Vutla 
15259041a50SLokesh Vutla 		/* PG 2.0, efuse may not be set. */
15359041a50SLokesh Vutla 		if (package_type == PACKAGE_TYPE_UNDEFINED || package_type ==
15459041a50SLokesh Vutla 		    PACKAGE_TYPE_RESERVED)
15559041a50SLokesh Vutla 			return MPUPLL_M_800;
15659041a50SLokesh Vutla 
157983e3700STom Rini 		switch ((efuse_arm_mpu_max_freq & DEVICE_ID_MASK)) {
158983e3700STom Rini 		case AM335X_ZCZ_1000:
159983e3700STom Rini 			return MPUPLL_M_1000;
160983e3700STom Rini 		case AM335X_ZCZ_800:
161983e3700STom Rini 			return MPUPLL_M_800;
162983e3700STom Rini 		case AM335X_ZCZ_720:
163983e3700STom Rini 			return MPUPLL_M_720;
164983e3700STom Rini 		case AM335X_ZCZ_600:
165983e3700STom Rini 		case AM335X_ZCE_600:
166983e3700STom Rini 			return MPUPLL_M_600;
167983e3700STom Rini 		case AM335X_ZCZ_300:
168983e3700STom Rini 		case AM335X_ZCE_300:
169983e3700STom Rini 			return MPUPLL_M_300;
170983e3700STom Rini 		}
171983e3700STom Rini 	}
172983e3700STom Rini 
17359041a50SLokesh Vutla 	/* unknown, use the PG1.0 max */
174983e3700STom Rini 	return MPUPLL_M_720;
175983e3700STom Rini }
176983e3700STom Rini 
am335x_get_mpu_vdd(int sil_rev,int frequency)177c07bf9beSFelix Brack int am335x_get_mpu_vdd(int sil_rev, int frequency)
178c07bf9beSFelix Brack {
179c07bf9beSFelix Brack 	int sel_mask = am335x_get_tps65910_mpu_vdd(sil_rev, frequency);
180c07bf9beSFelix Brack 
181c07bf9beSFelix Brack 	switch (sel_mask) {
182c07bf9beSFelix Brack 	case TPS65910_OP_REG_SEL_1_3_2_5:
183c07bf9beSFelix Brack 		return 1325000;
184c07bf9beSFelix Brack 	case TPS65910_OP_REG_SEL_1_2_0:
185c07bf9beSFelix Brack 		return 1200000;
186c07bf9beSFelix Brack 	case TPS65910_OP_REG_SEL_1_1_0:
187c07bf9beSFelix Brack 		return 1100000;
188c07bf9beSFelix Brack 	default:
189c07bf9beSFelix Brack 		return 1262500;
190c07bf9beSFelix Brack 	}
191c07bf9beSFelix Brack }
192c07bf9beSFelix Brack 
am335x_get_tps65910_mpu_vdd(int sil_rev,int frequency)193983e3700STom Rini int am335x_get_tps65910_mpu_vdd(int sil_rev, int frequency)
194983e3700STom Rini {
19559041a50SLokesh Vutla 	/* For PG2.0 and later, we have one set of values. */
19659041a50SLokesh Vutla 	if (sil_rev >= 1) {
197983e3700STom Rini 		switch (frequency) {
198983e3700STom Rini 		case MPUPLL_M_1000:
199983e3700STom Rini 			return TPS65910_OP_REG_SEL_1_3_2_5;
200983e3700STom Rini 		case MPUPLL_M_800:
201983e3700STom Rini 			return TPS65910_OP_REG_SEL_1_2_6;
202983e3700STom Rini 		case MPUPLL_M_720:
203983e3700STom Rini 			return TPS65910_OP_REG_SEL_1_2_0;
204983e3700STom Rini 		case MPUPLL_M_600:
20559041a50SLokesh Vutla 		case MPUPLL_M_500:
206983e3700STom Rini 		case MPUPLL_M_300:
20759041a50SLokesh Vutla 			return TPS65910_OP_REG_SEL_1_1_0;
208983e3700STom Rini 		}
209983e3700STom Rini 	}
210983e3700STom Rini 
21159041a50SLokesh Vutla 	/* Default to PG1.0 values. */
21259041a50SLokesh Vutla 	return TPS65910_OP_REG_SEL_1_2_6;
213983e3700STom Rini }
214983e3700STom Rini #endif
215