blob: 5a013e3384598d1b4e28fdb7f75b0ac8848ba855 [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>
Lokesh Vutlad3daba12013-12-10 15:02:22 +053018#include <asm/arch/ddr_defs.h>
19#include <asm/emif.h>
Lokesh Vutlafbf27282013-07-30 11:36:27 +053020#include "board.h"
21
22DECLARE_GLOBAL_DATA_PTR;
23
Sekhar Nori9f1a8cd2013-12-10 15:02:15 +053024/*
25 * Read header information from EEPROM into global structure.
26 */
27static int read_eeprom(struct am43xx_board_id *header)
28{
29 /* Check if baseboard eeprom is available */
30 if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
31 printf("Could not probe the EEPROM at 0x%x\n",
32 CONFIG_SYS_I2C_EEPROM_ADDR);
33 return -ENODEV;
34 }
35
36 /* read the eeprom using i2c */
37 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
38 sizeof(struct am43xx_board_id))) {
39 printf("Could not read the EEPROM\n");
40 return -EIO;
41 }
42
43 if (header->magic != 0xEE3355AA) {
44 /*
45 * read the eeprom using i2c again,
46 * but use only a 1 byte address
47 */
48 if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
49 sizeof(struct am43xx_board_id))) {
50 printf("Could not read the EEPROM at 0x%x\n",
51 CONFIG_SYS_I2C_EEPROM_ADDR);
52 return -EIO;
53 }
54
55 if (header->magic != 0xEE3355AA) {
56 printf("Incorrect magic number (0x%x) in EEPROM\n",
57 header->magic);
58 return -EINVAL;
59 }
60 }
61
62 strncpy(am43xx_board_name, (char *)header->name, sizeof(header->name));
63 am43xx_board_name[sizeof(header->name)] = 0;
64
65 return 0;
66}
67
Lokesh Vutlafbf27282013-07-30 11:36:27 +053068#ifdef CONFIG_SPL_BUILD
69
Lokesh Vutlacf04d032013-12-10 15:02:20 +053070#define NUM_OPPS 6
71
72const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
73 { /* 19.2 MHz */
74 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 50 */
75 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
76 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 100 */
77 {-1, -1, -1, -1, -1, -1, -1}, /* OPP 120 */
78 {-1, -1, -1, -1, -1, -1, -1}, /* OPP TB */
79 {-1, -1, -1, -1, -1, -1, -1} /* OPP NT */
80 },
81 { /* 24 MHz */
82 {300, 23, 1, -1, -1, -1, -1}, /* OPP 50 */
83 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
84 {600, 23, 1, -1, -1, -1, -1}, /* OPP 100 */
85 {720, 23, 1, -1, -1, -1, -1}, /* OPP 120 */
86 {800, 23, 1, -1, -1, -1, -1}, /* OPP TB */
87 {1000, 23, 1, -1, -1, -1, -1} /* OPP NT */
88 },
89 { /* 25 MHz */
90 {300, 24, 1, -1, -1, -1, -1}, /* OPP 50 */
91 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
92 {600, 24, 1, -1, -1, -1, -1}, /* OPP 100 */
93 {720, 24, 1, -1, -1, -1, -1}, /* OPP 120 */
94 {800, 24, 1, -1, -1, -1, -1}, /* OPP TB */
95 {1000, 24, 1, -1, -1, -1, -1} /* OPP NT */
96 },
97 { /* 26 MHz */
98 {300, 25, 1, -1, -1, -1, -1}, /* OPP 50 */
99 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */
100 {600, 25, 1, -1, -1, -1, -1}, /* OPP 100 */
101 {720, 25, 1, -1, -1, -1, -1}, /* OPP 120 */
102 {800, 25, 1, -1, -1, -1, -1}, /* OPP TB */
103 {1000, 25, 1, -1, -1, -1, -1} /* OPP NT */
104 },
105};
106
107const struct dpll_params dpll_core[NUM_CRYSTAL_FREQ] = {
108 {-1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
109 {1000, 23, -1, -1, 10, 8, 4}, /* 24 MHz */
110 {1000, 24, -1, -1, 10, 8, 4}, /* 25 MHz */
111 {1000, 25, -1, -1, 10, 8, 4} /* 26 MHz */
112};
113
114const struct dpll_params dpll_per[NUM_CRYSTAL_FREQ] = {
115 {-1, -1, -1, -1, -1, -1, -1}, /* 19.2 MHz */
116 {960, 23, 5, -1, -1, -1, -1}, /* 24 MHz */
117 {960, 24, 5, -1, -1, -1, -1}, /* 25 MHz */
118 {960, 25, 5, -1, -1, -1, -1} /* 26 MHz */
119};
120
121const struct dpll_params epos_evm_dpll_ddr = {
122 266, 24, 1, -1, 1, -1, -1};
123
124const struct dpll_params gp_evm_dpll_ddr = {
125 400, 23, 1, -1, 1, -1, -1};
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530126
Lokesh Vutlad3daba12013-12-10 15:02:22 +0530127const struct ctrl_ioregs ioregs_lpddr2 = {
128 .cm0ioctl = LPDDR2_ADDRCTRL_IOCTRL_VALUE,
129 .cm1ioctl = LPDDR2_ADDRCTRL_WD0_IOCTRL_VALUE,
130 .cm2ioctl = LPDDR2_ADDRCTRL_WD1_IOCTRL_VALUE,
131 .dt0ioctl = LPDDR2_DATA0_IOCTRL_VALUE,
132 .dt1ioctl = LPDDR2_DATA0_IOCTRL_VALUE,
133 .dt2ioctrl = LPDDR2_DATA0_IOCTRL_VALUE,
134 .dt3ioctrl = LPDDR2_DATA0_IOCTRL_VALUE,
135 .emif_sdram_config_ext = 0x1,
136};
137
138const struct emif_regs emif_regs_lpddr2 = {
139 .sdram_config = 0x808012BA,
140 .ref_ctrl = 0x0000040D,
141 .sdram_tim1 = 0xEA86B411,
142 .sdram_tim2 = 0x103A094A,
143 .sdram_tim3 = 0x0F6BA37F,
144 .read_idle_ctrl = 0x00050000,
145 .zq_config = 0x50074BE4,
146 .temp_alert_config = 0x0,
147 .emif_rd_wr_lvl_rmp_win = 0x0,
148 .emif_rd_wr_lvl_rmp_ctl = 0x0,
149 .emif_rd_wr_lvl_ctl = 0x0,
150 .emif_ddr_phy_ctlr_1 = 0x0E084006,
151 .emif_rd_wr_exec_thresh = 0x00000405,
152 .emif_ddr_ext_phy_ctrl_1 = 0x04010040,
153 .emif_ddr_ext_phy_ctrl_2 = 0x00500050,
154 .emif_ddr_ext_phy_ctrl_3 = 0x00500050,
155 .emif_ddr_ext_phy_ctrl_4 = 0x00500050,
156 .emif_ddr_ext_phy_ctrl_5 = 0x00500050
157};
158
159const u32 ext_phy_ctrl_const_base_lpddr2[] = {
160 0x00500050,
161 0x00350035,
162 0x00350035,
163 0x00350035,
164 0x00350035,
165 0x00350035,
166 0x00000000,
167 0x00000000,
168 0x00000000,
169 0x00000000,
170 0x00000000,
171 0x00000000,
172 0x00000000,
173 0x00000000,
174 0x00000000,
175 0x00000000,
176 0x00000000,
177 0x00000000,
178 0x40001000,
179 0x08102040
180};
181
182void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
183{
184 *regs = ext_phy_ctrl_const_base_lpddr2;
185 *size = ARRAY_SIZE(ext_phy_ctrl_const_base_lpddr2);
186
187 return;
188}
189
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530190const struct dpll_params *get_dpll_ddr_params(void)
191{
Lokesh Vutlacf04d032013-12-10 15:02:20 +0530192 struct am43xx_board_id header;
193
194 enable_i2c0_pin_mux();
195 i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
196 if (read_eeprom(&header) < 0)
197 puts("Could not get board ID.\n");
198
199 if (board_is_eposevm())
200 return &epos_evm_dpll_ddr;
201 else if (board_is_gpevm())
202 return &gp_evm_dpll_ddr;
203
204 puts(" Board not supported\n");
205 return NULL;
206}
207
208/*
209 * get_sys_clk_index : returns the index of the sys_clk read from
210 * ctrl status register. This value is either
211 * read from efuse or sysboot pins.
212 */
213static u32 get_sys_clk_index(void)
214{
215 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
216 u32 ind = readl(&ctrl->statusreg), src;
217
218 src = (ind & CTRL_CRYSTAL_FREQ_SRC_MASK) >> CTRL_CRYSTAL_FREQ_SRC_SHIFT;
219 if (src == CTRL_CRYSTAL_FREQ_SRC_EFUSE) /* Value read from EFUSE */
220 return ((ind & CTRL_CRYSTAL_FREQ_SELECTION_MASK) >>
221 CTRL_CRYSTAL_FREQ_SELECTION_SHIFT);
222 else /* Value read from SYS BOOT pins */
223 return ((ind & CTRL_SYSBOOT_15_14_MASK) >>
224 CTRL_SYSBOOT_15_14_SHIFT);
225}
226
227/*
228 * get_opp_offset:
229 * Returns the index for safest OPP of the device to boot.
230 * max_off: Index of the MAX OPP in DEV ATTRIBUTE register.
231 * min_off: Index of the MIN OPP in DEV ATTRIBUTE register.
232 * This data is read from dev_attribute register which is e-fused.
233 * A'1' in bit indicates OPP disabled and not available, a '0' indicates
234 * OPP available. Lowest OPP starts with min_off. So returning the
235 * bit with rightmost '0'.
236 */
237static int get_opp_offset(int max_off, int min_off)
238{
239 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
240 int opp = readl(&ctrl->dev_attr), offset, i;
241
242 for (i = max_off; i >= min_off; i--) {
243 offset = opp & (1 << i);
244 if (!offset)
245 return i;
246 }
247
248 return min_off;
249}
250
251const struct dpll_params *get_dpll_mpu_params(void)
252{
253 int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
254 u32 ind = get_sys_clk_index();
255
256 return &dpll_mpu[ind][opp];
257}
258
259const struct dpll_params *get_dpll_core_params(void)
260{
261 int ind = get_sys_clk_index();
262
263 return &dpll_core[ind];
264}
265
266const struct dpll_params *get_dpll_per_params(void)
267{
268 int ind = get_sys_clk_index();
269
270 return &dpll_per[ind];
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530271}
272
273void set_uart_mux_conf(void)
274{
275 enable_uart0_pin_mux();
276}
277
278void set_mux_conf_regs(void)
279{
280 enable_board_pin_mux();
281}
282
283void sdram_init(void)
284{
Lokesh Vutlad3daba12013-12-10 15:02:22 +0530285 config_ddr(0, &ioregs_lpddr2, NULL, NULL, &emif_regs_lpddr2, 0);
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530286}
287#endif
288
289int board_init(void)
290{
Lokesh Vutla369cbe12013-12-10 15:02:12 +0530291 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530292
293 return 0;
294}
295
296#ifdef CONFIG_BOARD_LATE_INIT
297int board_late_init(void)
298{
Sekhar Norif4af1632013-12-10 15:02:16 +0530299#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
300 char safe_string[HDR_NAME_LEN + 1];
301 struct am43xx_board_id header;
302
303 if (read_eeprom(&header) < 0)
304 puts("Could not get board ID.\n");
305
306 /* Now set variables based on the header. */
307 strncpy(safe_string, (char *)header.name, sizeof(header.name));
308 safe_string[sizeof(header.name)] = 0;
309 setenv("board_name", safe_string);
310
311 strncpy(safe_string, (char *)header.version, sizeof(header.version));
312 safe_string[sizeof(header.version)] = 0;
313 setenv("board_rev", safe_string);
314#endif
Lokesh Vutlafbf27282013-07-30 11:36:27 +0530315 return 0;
316}
317#endif