1/* 2 * (C) Copyright 2005-2007 3 * Samsung Electronics, 4 * Kyungmin Park <kyungmin.park@samsung.com> 5 * 6 * Derived from omap2420 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24#include <common.h> 25#include <asm/arch/omap2420.h> 26#include <asm/io.h> 27#include <asm/arch/bits.h> 28#include <asm/arch/mem.h> /* get mem tables */ 29#include <asm/arch/sys_proto.h> 30#include <asm/arch/sys_info.h> 31#include <i2c.h> 32 33/************************************************************************** 34 * get_prod_id() - get id info from chips 35 ***************************************************************************/ 36static u32 get_prod_id(void) 37{ 38 u32 p; 39 p = __raw_readl(PRODUCTION_ID); /* get production ID */ 40 return ((p & CPU_242X_PID_MASK) >> 16); 41} 42 43/************************************************************************** 44 * get_cpu_type() - low level get cpu type 45 * - no C globals yet. 46 * - just looking to say if this is a 2422 or 2420 or ... 47 * - to start with we will look at switch settings.. 48 * - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics 49 * (mux for 2420, non-mux for 2422). 50 ***************************************************************************/ 51u32 get_cpu_type(void) 52{ 53 u32 v; 54 55 switch (get_prod_id()) { 56 case 1:; /* 2420 */ 57 case 2: 58 return (CPU_2420); 59 break; /* 2420 pop */ 60 case 4: 61 return (CPU_2422); 62 break; 63 case 8: 64 return (CPU_2423); 65 break; 66 default: 67 break; /* early 2420/2422's unmarked */ 68 } 69 70 v = __raw_readl(TAP_IDCODE_REG); 71 v &= CPU_24XX_ID_MASK; 72 /* currently 2420 and 2422 have same id */ 73 if (v == CPU_2420_CHIPID) { 74 if (is_gpmc_muxed() == GPMC_MUXED) /* if mux'ed */ 75 return (CPU_2420); 76 else 77 return (CPU_2422); 78 } else 79 return (CPU_2420); /* don't know, say 2420 */ 80} 81 82/****************************************** 83 * get_cpu_rev(void) - extract version info 84 ******************************************/ 85u32 get_cpu_rev(void) 86{ 87 u32 v; 88 v = __raw_readl(TAP_IDCODE_REG); 89 v = v >> 28; 90 return (v + 1); /* currently 2422 and 2420 match up */ 91} 92 93/**************************************************** 94 * is_mem_sdr() - return 1 if mem type in use is SDR 95 ****************************************************/ 96u32 is_mem_sdr(void) 97{ 98 volatile u32 *burst = (volatile u32 *)(SDRC_MR_0 + SDRC_CS0_OSET); 99 if (*burst == H4_2420_SDRC_MR_0_SDR) 100 return (1); 101 return (0); 102} 103 104/*********************************************************** 105 * get_mem_type() - identify type of mDDR part used. 106 * 2422 uses stacked DDR, 2 parts CS0/CS1. 107 * 2420 may have 1 or 2, no good way to know...only init 1... 108 * when eeprom data is up we can select 1 more. 109 *************************************************************/ 110u32 get_mem_type(void) 111{ 112 u32 cpu, sdr = is_mem_sdr(); 113 114 cpu = get_cpu_type(); 115 if (cpu == CPU_2422 || cpu == CPU_2423) 116 return (DDR_STACKED); 117 118 if (get_prod_id() == 0x2) 119 return (XDR_POP); 120 121 if (get_board_type() == BOARD_H4_MENELAUS) 122 if (sdr) 123 return (SDR_DISCRETE); 124 else 125 return (DDR_COMBO); 126 else if (sdr) /* SDP + SDR kit */ 127 return (SDR_DISCRETE); 128 else 129 return (DDR_DISCRETE); /* origional SDP */ 130} 131 132/*********************************************************************** 133 * get_cs0_size() - get size of chip select 0/1 134 ************************************************************************/ 135u32 get_sdr_cs_size(u32 offset) 136{ 137 u32 size; 138 size = __raw_readl(SDRC_MCFG_0 + offset) >> 8; /* get ram size field */ 139 size &= 0x2FF; /* remove unwanted bits */ 140 size *= SZ_2M; /* find size in MB */ 141 return (size); 142} 143 144/*********************************************************************** 145 * get_board_type() - get board type based on current production stats. 146 * --- NOTE: 2 I2C EEPROMs will someday be populated with proper info. 147 * when they are available we can get info from there. This should 148 * be correct of all known boards up until today. 149 ************************************************************************/ 150u32 get_board_type(void) 151{ 152 return (BOARD_H4_SDP); 153} 154 155/****************************************************************** 156 * get_sysboot_value() - get init word settings (dip switch on h4) 157 ******************************************************************/ 158inline u32 get_sysboot_value(void) 159{ 160 return (0x00000FFF & __raw_readl(CONTROL_STATUS)); 161} 162 163/*************************************************************************** 164 * get_gpmc0_base() - Return current address hardware will be 165 * fetching from. The below effectively gives what is correct, its a bit 166 * mis-leading compared to the TRM. For the most general case the mask 167 * needs to be also taken into account this does work in practice. 168 * - for u-boot we currently map: 169 * -- 0 to nothing, 170 * -- 4 to flash 171 * -- 8 to enent 172 * -- c to wifi 173 ****************************************************************************/ 174u32 get_gpmc0_base(void) 175{ 176 u32 b; 177 178 b = __raw_readl(GPMC_CONFIG7_0); 179 b &= 0x1F; /* keep base [5:0] */ 180 b = b << 24; /* ret 0x0b000000 */ 181 return (b); 182} 183 184/***************************************************************** 185 * is_gpmc_muxed() - tells if address/data lines are multiplexed 186 *****************************************************************/ 187u32 is_gpmc_muxed(void) 188{ 189 u32 mux; 190 mux = get_sysboot_value(); 191 if ((mux & (BIT0 | BIT1 | BIT2 | BIT3)) == (BIT0 | BIT2 | BIT3)) 192 return (GPMC_MUXED); /* NAND Boot mode */ 193 if (mux & BIT1) /* if mux'ed */ 194 return (GPMC_MUXED); 195 else 196 return (GPMC_NONMUXED); 197} 198 199/************************************************************************ 200 * get_gpmc0_type() - read sysboot lines to see type of memory attached 201 ************************************************************************/ 202u32 get_gpmc0_type(void) 203{ 204 u32 type; 205 type = get_sysboot_value(); 206 if ((type & (BIT3 | BIT2)) == (BIT3 | BIT2)) 207 return (TYPE_NAND); 208 else 209 return (TYPE_NOR); 210} 211 212/******************************************************************* 213 * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) 214 *******************************************************************/ 215u32 get_gpmc0_width(void) 216{ 217 u32 width; 218 width = get_sysboot_value(); 219 if ((width & 0xF) == (BIT3 | BIT2)) 220 return (WIDTH_8BIT); 221 else 222 return (WIDTH_16BIT); 223} 224 225/********************************************************************* 226 * wait_on_value() - common routine to allow waiting for changes in 227 * volatile regs. 228 *********************************************************************/ 229u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) 230{ 231 u32 i = 0, val; 232 do { 233 ++i; 234 val = __raw_readl(read_addr) & read_bit_mask; 235 if (val == match_value) 236 return (1); 237 if (i == bound) 238 return (0); 239 } while (1); 240} 241 242/********************************************************************* 243 * display_board_info() - print banner with board info. 244 *********************************************************************/ 245void display_board_info(u32 btype) 246{ 247 char cpu_2420[] = "2420"; /* cpu type */ 248 char cpu_2422[] = "2422"; 249 char cpu_2423[] = "2423"; 250 char mem_sdr[] = "mSDR"; /* memory type */ 251 char mem_ddr[] = "mDDR"; 252 char t_tst[] = "TST"; /* security level */ 253 char t_emu[] = "EMU"; 254 char t_hs[] = "HS"; 255 char t_gp[] = "GP"; 256 char unk[] = "?"; 257 258 char *cpu_s, *mem_s, *sec_s; 259 u32 cpu, rev, sec; 260 261 rev = get_cpu_rev(); 262 cpu = get_cpu_type(); 263 sec = get_device_type(); 264 265 if (is_mem_sdr()) 266 mem_s = mem_sdr; 267 else 268 mem_s = mem_ddr; 269 270 if (cpu == CPU_2423) 271 cpu_s = cpu_2423; 272 else if (cpu == CPU_2422) 273 cpu_s = cpu_2422; 274 else 275 cpu_s = cpu_2420; 276 277 switch (sec) { 278 case TST_DEVICE: 279 sec_s = t_tst; 280 break; 281 case EMU_DEVICE: 282 sec_s = t_emu; 283 break; 284 case HS_DEVICE: 285 sec_s = t_hs; 286 break; 287 case GP_DEVICE: 288 sec_s = t_gp; 289 break; 290 default: 291 sec_s = unk; 292 } 293 294 printf("OMAP%s-%s revision %d\n", cpu_s, sec_s, rev - 1); 295 printf("Samsung Apollon SDP Base Board + %s \n", mem_s); 296} 297 298/************************************************************************* 299 * get_board_rev() - setup to pass kernel board revision information 300 * 0 = 242x IP platform (first 2xx boards) 301 * 1 = 242x Menelaus platfrom. 302 *************************************************************************/ 303u32 get_board_rev(void) 304{ 305 u32 rev = 0; 306 u32 btype = get_board_type(); 307 308 if (btype == BOARD_H4_MENELAUS) 309 rev = 1; 310 return (rev); 311} 312 313/******************************************************** 314 * get_base(); get upper addr of current execution 315 *******************************************************/ 316u32 get_base(void) 317{ 318 u32 val; 319 __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); 320 val &= 0xF0000000; 321 val >>= 28; 322 return (val); 323} 324 325/******************************************************** 326 * get_base2(); get 2upper addr of current execution 327 *******************************************************/ 328u32 get_base2(void) 329{ 330 u32 val; 331 __asm__ __volatile__("mov %0, pc \n":"=r"(val)::"memory"); 332 val &= 0xFF000000; 333 val >>= 24; 334 return (val); 335} 336 337/******************************************************** 338 * running_in_flash() - tell if currently running in 339 * flash. 340 *******************************************************/ 341u32 running_in_flash(void) 342{ 343 if (get_base() < 4) 344 return (1); /* in flash */ 345 return (0); /* running in SRAM or SDRAM */ 346} 347 348/******************************************************** 349 * running_in_sram() - tell if currently running in 350 * sram. 351 *******************************************************/ 352u32 running_in_sram(void) 353{ 354 if (get_base() == 4) 355 return (1); /* in SRAM */ 356 return (0); /* running in FLASH or SDRAM */ 357} 358 359/******************************************************** 360 * running_in_sdram() - tell if currently running in 361 * flash. 362 *******************************************************/ 363u32 running_in_sdram(void) 364{ 365 if (get_base() > 4) 366 return (1); /* in sdram */ 367 return (0); /* running in SRAM or FLASH */ 368} 369 370/************************************************************* 371 * running_from_internal_boot() - am I a signed NOR image. 372 *************************************************************/ 373u32 running_from_internal_boot(void) 374{ 375 u32 v, base; 376 377 v = get_sysboot_value() & BIT3; 378 base = get_base2(); 379 /* if running at mask rom flash address and 380 * sysboot3 says this was an internal boot 381 */ 382 if ((base == 0x08) && v) 383 return (1); 384 else 385 return (0); 386} 387 388/************************************************************* 389 * get_device_type(): tell if GP/HS/EMU/TST 390 *************************************************************/ 391u32 get_device_type(void) 392{ 393 int mode; 394 mode = __raw_readl(CONTROL_STATUS) & (BIT10 | BIT9 | BIT8); 395 return (mode >>= 8); 396} 397