blob: 5c92ac7f30da9d2c3a6822df65a4333b1da27588 [file] [log] [blame]
Lokesh Vutlafbf27282013-07-30 11:36:27 +05301/*
2 * board.c
3 *
4 * Board functions for TI AM43XX based boards
5 *
6 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11#include <common.h>
Sekhar Nori9f1a8cd2013-12-10 15:02:15 +053012#include <i2c.h>
13#include <asm/errno.h>
Lokesh Vutlafbf27282013-07-30 11:36:27 +053014#include <spl.h>
Lokesh Vutla3b34ac12013-07-30 11:36:29 +053015#include <asm/arch/clock.h>
Lokesh Vutlafbf27282013-07-30 11:36:27 +053016#include <asm/arch/sys_proto.h>
17#include <asm/arch/mux.h>
18#include "board.h"
19
20DECLARE_GLOBAL_DATA_PTR;
21
Sekhar Nori9f1a8cd2013-12-10 15:02:15 +053022/*
23 * Read header information from EEPROM into global structure.
24 */
25static int read_eeprom(struct am43xx_board_id *header)
26{
27 /* Check if baseboard eeprom is available */
28 if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
29 printf("Could not probe the EEPROM at 0x%x\n",
30 CONFIG_SYS_I2C_EEPROM_ADDR);
31 return -ENODEV;
32 }
33
34 /* read the eeprom using i2c */
35 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
36 sizeof(struct am43xx_board_id))) {
37 printf("Could not read the EEPROM\n");
38 return -EIO;
39 }
40
41 if (header->magic != 0xEE3355AA) {
42 /*
43 * read the eeprom using i2c again,
44 * but use only a 1 byte address
45 */
46 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
47 sizeof(struct am43xx_board_id))) {
48 printf("Could not read the EEPROM at 0x%x\n",
49 CONFIG_SYS_I2C_EEPROM_ADDR);
50 return -EIO;
51 }
52
53 if (header->magic != 0xEE3355AA) {
54 printf("Incorrect magic number (0x%x) in EEPROM\n",
55 header->magic);
56 return -EINVAL;
57 }
58 }
59
60 strncpy(am43xx_board_name, (char *)header->name, sizeof(header->name));
61 am43xx_board_name[sizeof(header->name)] = 0;
62
63 return 0;
64}
65
Lokesh Vutlafbf27282013-07-30 11:36:27 +053066#ifdef CONFIG_SPL_BUILD
67
Lokesh Vutlacf04d032013-12-10 15:02:20 +053068#define NUM_OPPS 6
69
70const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
71 { /* 19.2 MHz */
72 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 50 */
73 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
74 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 100 */
75 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 120 */
76 {-1, -1, -1, -1, -1, -1, -1}, /* OPP TB */
77 {-1, -1, -1, -1, -1, -1, -1} /* OPP NT */
78 },
79 { /* 24 MHz */
80 {300, 23, 1, -1, -1, -1, -1}, /* OPP 50 */
81 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
82 {600, 23, 1, -1, -1, -1, -1}, /* OPP 100 */
83 {720, 23, 1, -1, -1, -1, -1}, /* OPP 120 */
84 {800, 23, 1, -1, -1, -1, -1}, /* OPP TB */
85 {1000, 23, 1, -1, -1, -1, -1} /* OPP NT */
86 },
87 { /* 25 MHz */
88 {300, 24, 1, -1, -1, -1, -1}, /* OPP 50 */
89 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
90 {600, 24, 1, -1, -1, -1, -1}, /* OPP 100 */
91 {720, 24, 1, -1, -1, -1, -1}, /* OPP 120 */
92 {800, 24, 1, -1, -1, -1, -1}, /* OPP TB */
93 {1000, 24, 1, -1, -1, -1, -1} /* OPP NT */
94 },
95 { /* 26 MHz */
96 {300, 25, 1, -1, -1, -1, -1}, /* OPP 50 */
97 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
98 {600, 25, 1, -1, -1, -1, -1}, /* OPP 100 */
99 {720, 25, 1, -1, -1, -1, -1}, /* OPP 120 */
100 {800, 25, 1, -1, -1, -1, -1}, /* OPP TB */
101 {1000, 25, 1, -1, -1, -1, -1} /* OPP NT */
102 },
103};
104
105const struct dpll_params dpll_core[NUM_CRYSTAL_FREQ] = {
106 {-1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
107 {1000, 23, -1, -1, 10, 8, 4}, /* 24 MHz */
108 {1000, 24, -1, -1, 10, 8, 4}, /* 25 MHz */
109 {1000, 25, -1, -1, 10, 8, 4} /* 26 MHz */
110};
111
112const struct dpll_params dpll_per[NUM_CRYSTAL_FREQ] = {
113 {-1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
114 {960, 23, 5, -1, -1, -1, -1}, /* 24 MHz */
115 {960, 24, 5, -1, -1, -1, -1}, /* 25 MHz */
116 {960, 25, 5, -1, -1, -1, -1} /* 26 MHz */
117};
118
119const struct dpll_params epos_evm_dpll_ddr = {
120 266, 24, 1, -1, 1, -1, -1};
121
122const struct dpll_params gp_evm_dpll_ddr = {
123 400, 23, 1, -1, 1, -1, -1};
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530124
125const struct dpll_params *get_dpll_ddr_params(void)
126{
Lokesh Vutlacf04d032013-12-10 15:02:20 +0530127 struct am43xx_board_id header;
128
129 enable_i2c0_pin_mux();
130 i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
131 if (read_eeprom(&header) < 0)
132 puts("Could not get board ID.\n");
133
134 if (board_is_eposevm())
135 return &epos_evm_dpll_ddr;
136 else if (board_is_gpevm())
137 return &gp_evm_dpll_ddr;
138
139 puts(" Board not supported\n");
140 return NULL;
141}
142
143/*
144 * get_sys_clk_index : returns the index of the sys_clk read from
145 * ctrl status register. This value is either
146 * read from efuse or sysboot pins.
147 */
148static u32 get_sys_clk_index(void)
149{
150 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
151 u32 ind = readl(&ctrl->statusreg), src;
152
153 src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
154 if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
155 return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
156 CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
157 else /* Value read from SYS BOOT pins */
158 return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
159 CTRL_SYSBOOT_15_14_SHIFT);
160}
161
162/*
163 * get_opp_offset:
164 * Returns the index for safest OPP of the device to boot.
165 * max_off: Index of the MAX OPP in DEV ATTRIBUTE register.
166 * min_off: Index of the MIN OPP in DEV ATTRIBUTE register.
167 * This data is read from dev_attribute register which is e-fused.
168 * A'1' in bit indicates OPP disabled and not available, a '0' indicates
169 * OPP available. Lowest OPP starts with min_off. So returning the
170 * bit with rightmost '0'.
171 */
172static int get_opp_offset(int max_off, int min_off)
173{
174 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
175 int opp = readl(&ctrl->dev_attr), offset, i;
176
177 for (i = max_off; i >= min_off; i--) {
178 offset = opp & (1 << i);
179 if (!offset)
180 return i;
181 }
182
183 return min_off;
184}
185
186const struct dpll_params *get_dpll_mpu_params(void)
187{
188 int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
189 u32 ind = get_sys_clk_index();
190
191 return &dpll_mpu[ind][opp];
192}
193
194const struct dpll_params *get_dpll_core_params(void)
195{
196 int ind = get_sys_clk_index();
197
198 return &dpll_core[ind];
199}
200
201const struct dpll_params *get_dpll_per_params(void)
202{
203 int ind = get_sys_clk_index();
204
205 return &dpll_per[ind];
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530206}
207
208void set_uart_mux_conf(void)
209{
210 enable_uart0_pin_mux();
211}
212
213void set_mux_conf_regs(void)
214{
215 enable_board_pin_mux();
216}
217
218void sdram_init(void)
219{
220}
221#endif
222
223int board_init(void)
224{
Lokesh Vutla369cbe12013-12-10 15:02:12 +0530225 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530226
227 return 0;
228}
229
230#ifdef CONFIG_BOARD_LATE_INIT
231int board_late_init(void)
232{
Sekhar Norif4af1632013-12-10 15:02:16 +0530233#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
234 char safe_string[HDR_NAME_LEN + 1];
235 struct am43xx_board_id header;
236
237 if (read_eeprom(&header) < 0)
238 puts("Could not get board ID.\n");
239
240 /* Now set variables based on the header. */
241 strncpy(safe_string, (char *)header.name, sizeof(header.name));
242 safe_string[sizeof(header.name)] = 0;
243 setenv("board_name", safe_string);
244
245 strncpy(safe_string, (char *)header.version, sizeof(header.version));
246 safe_string[sizeof(header.version)] = 0;
247 setenv("board_rev", safe_string);
248#endif
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530249 return 0;
250}
251#endif