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