4 * Board functions for TI AM43XX based boards
6 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
8 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/errno.h>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/sys_proto.h>
17 #include <asm/arch/mux.h>
20 DECLARE_GLOBAL_DATA_PTR;
23 * Read header information from EEPROM into global structure.
25 static int read_eeprom(struct am43xx_board_id *header)
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);
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");
41 if (header->magic != 0xEE3355AA) {
43 * read the eeprom using i2c again,
44 * but use only a 1 byte address
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);
53 if (header->magic != 0xEE3355AA) {
54 printf("Incorrect magic number (0x%x) in EEPROM\n",
60 strncpy(am43xx_board_name, (char *)header->name, sizeof(header->name));
61 am43xx_board_name[sizeof(header->name)] = 0;
66 #ifdef CONFIG_SPL_BUILD
70 const struct dpll_params dpll_mpu[NUM_CRYSTAL_FREQ][NUM_OPPS] = {
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 */
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 */
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 */
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 */
105 const 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 */
112 const 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 */
119 const struct dpll_params epos_evm_dpll_ddr = {
120 266, 24, 1, -1, 1, -1, -1};
122 const struct dpll_params gp_evm_dpll_ddr = {
123 400, 23, 1, -1, 1, -1, -1};
125 const struct dpll_params *get_dpll_ddr_params(void)
127 struct am43xx_board_id header;
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");
134 if (board_is_eposevm())
135 return &epos_evm_dpll_ddr;
136 else if (board_is_gpevm())
137 return &gp_evm_dpll_ddr;
139 puts(" Board not supported\n");
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.
148 static u32 get_sys_clk_index(void)
150 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
151 u32 ind = readl(&ctrl->statusreg), src;
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);
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'.
172 static int get_opp_offset(int max_off, int min_off)
174 struct ctrl_stat *ctrl = (struct ctrl_stat *)CTRL_BASE;
175 int opp = readl(&ctrl->dev_attr), offset, i;
177 for (i = max_off; i >= min_off; i--) {
178 offset = opp & (1 << i);
186 const struct dpll_params *get_dpll_mpu_params(void)
188 int opp = get_opp_offset(DEV_ATTR_MAX_OFFSET, DEV_ATTR_MIN_OFFSET);
189 u32 ind = get_sys_clk_index();
191 return &dpll_mpu[ind][opp];
194 const struct dpll_params *get_dpll_core_params(void)
196 int ind = get_sys_clk_index();
198 return &dpll_core[ind];
201 const struct dpll_params *get_dpll_per_params(void)
203 int ind = get_sys_clk_index();
205 return &dpll_per[ind];
208 void set_uart_mux_conf(void)
210 enable_uart0_pin_mux();
213 void set_mux_conf_regs(void)
215 enable_board_pin_mux();
218 void sdram_init(void)
225 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
230 #ifdef CONFIG_BOARD_LATE_INIT
231 int board_late_init(void)
233 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
234 char safe_string[HDR_NAME_LEN + 1];
235 struct am43xx_board_id header;
237 if (read_eeprom(&header) < 0)
238 puts("Could not get board ID.\n");
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);
245 strncpy(safe_string, (char *)header.version, sizeof(header.version));
246 safe_string[sizeof(header.version)] = 0;
247 setenv("board_rev", safe_string);