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