1 /* 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> 12 #include <i2c.h> 13 #include <asm/errno.h> 14 #include <spl.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/sys_proto.h> 17 #include <asm/arch/mux.h> 18 #include "board.h" 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 /* 23 * Read header information from EEPROM into global structure. 24 */ 25 static 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 66 #ifdef CONFIG_SPL_BUILD 67 68 #define NUM_OPPS 6 69 70 const 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 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 */ 110 }; 111 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 */ 117 }; 118 119 const struct dpll_params epos_evm_dpll_ddr = { 120 266, 24, 1, -1, 1, -1, -1}; 121 122 const struct dpll_params gp_evm_dpll_ddr = { 123 400, 23, 1, -1, 1, -1, -1}; 124 125 const struct dpll_params *get_dpll_ddr_params(void) 126 { 127 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 */ 148 static 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 */ 172 static 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 186 const 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 194 const struct dpll_params *get_dpll_core_params(void) 195 { 196 int ind = get_sys_clk_index(); 197 198 return &dpll_core[ind]; 199 } 200 201 const struct dpll_params *get_dpll_per_params(void) 202 { 203 int ind = get_sys_clk_index(); 204 205 return &dpll_per[ind]; 206 } 207 208 void set_uart_mux_conf(void) 209 { 210 enable_uart0_pin_mux(); 211 } 212 213 void set_mux_conf_regs(void) 214 { 215 enable_board_pin_mux(); 216 } 217 218 void sdram_init(void) 219 { 220 } 221 #endif 222 223 int board_init(void) 224 { 225 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; 226 227 return 0; 228 } 229 230 #ifdef CONFIG_BOARD_LATE_INIT 231 int board_late_init(void) 232 { 233 #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 249 return 0; 250 } 251 #endif 252