18167af14SThomas Weber /* 28167af14SThomas Weber * (C) Copyright 2012 38167af14SThomas Weber * Corscience GmbH & Co. KG, <www.corscience.de> 48167af14SThomas Weber * Thomas Weber <weber@corscience.de> 58167af14SThomas Weber * Sunil Kumar <sunilsaini05@gmail.com> 68167af14SThomas Weber * Shashi Ranjan <shashiranjanmca05@gmail.com> 78167af14SThomas Weber * 88167af14SThomas Weber * Derived from Devkit8000 code by 98167af14SThomas Weber * Frederik Kriewitz <frederik@kriewitz.eu> 108167af14SThomas Weber * 111a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 128167af14SThomas Weber */ 138167af14SThomas Weber #include <common.h> 148167af14SThomas Weber #include <twl4030.h> 158167af14SThomas Weber #include <asm/io.h> 1689088058SAndreas Bießmann #include <asm/gpio.h> 178167af14SThomas Weber #include <asm/arch/mmc_host_def.h> 188167af14SThomas Weber #include <asm/arch/mux.h> 198167af14SThomas Weber #include <asm/arch/sys_proto.h> 208167af14SThomas Weber #include <asm/arch/mem.h> 218167af14SThomas Weber #include "tricorder.h" 2289088058SAndreas Bießmann #include "tricorder-eeprom.h" 238167af14SThomas Weber 248167af14SThomas Weber DECLARE_GLOBAL_DATA_PTR; 258167af14SThomas Weber 268167af14SThomas Weber /* 278167af14SThomas Weber * Routine: board_init 288167af14SThomas Weber * Description: Early hardware init. 298167af14SThomas Weber */ 308167af14SThomas Weber int board_init(void) 318167af14SThomas Weber { 328167af14SThomas Weber gpmc_init(); /* in SRAM or SDRAM, finish GPMC */ 338167af14SThomas Weber /* boot param addr */ 348167af14SThomas Weber gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100); 358167af14SThomas Weber 368167af14SThomas Weber return 0; 378167af14SThomas Weber } 388167af14SThomas Weber 3989088058SAndreas Bießmann /** 4089088058SAndreas Bießmann * get_eeprom - read the eeprom 4189088058SAndreas Bießmann * 4289088058SAndreas Bießmann * @eeprom - pointer to a eeprom struct to fill 4389088058SAndreas Bießmann * 4489088058SAndreas Bießmann * This function will panic() on wrong EEPROM content 4589088058SAndreas Bießmann */ 4689088058SAndreas Bießmann static void get_eeprom(struct tricorder_eeprom *eeprom) 4789088058SAndreas Bießmann { 4889088058SAndreas Bießmann int ret; 4989088058SAndreas Bießmann 5089088058SAndreas Bießmann if (!eeprom) 5189088058SAndreas Bießmann panic("No eeprom given!\n"); 5289088058SAndreas Bießmann 5389088058SAndreas Bießmann ret = gpio_request(7, "BMS"); 5489088058SAndreas Bießmann if (ret) 5589088058SAndreas Bießmann panic("gpio: requesting BMS pin failed\n"); 5689088058SAndreas Bießmann 5789088058SAndreas Bießmann ret = gpio_direction_input(7); 5889088058SAndreas Bießmann if (ret) 5989088058SAndreas Bießmann panic("gpio: set BMS as input failed\n"); 6089088058SAndreas Bießmann 6189088058SAndreas Bießmann ret = gpio_get_value(7); 6289088058SAndreas Bießmann if (ret < 0) 6389088058SAndreas Bießmann panic("gpio: get BMS pin state failed\n"); 6489088058SAndreas Bießmann 6589088058SAndreas Bießmann gpio_free(7); 6689088058SAndreas Bießmann 6789088058SAndreas Bießmann if (ret == 0) { 6889088058SAndreas Bießmann /* BMS is _not_ set, do the EEPROM check */ 6989088058SAndreas Bießmann ret = tricorder_get_eeprom(0x51, eeprom); 7089088058SAndreas Bießmann if (!ret) { 7189088058SAndreas Bießmann if (strncmp(eeprom->board_name, "CS10411", 7) != 0) 7289088058SAndreas Bießmann panic("Wrong board name '%.*s'\n", 7389088058SAndreas Bießmann sizeof(eeprom->board_name), 7489088058SAndreas Bießmann eeprom->board_name); 7589088058SAndreas Bießmann if (eeprom->board_version[0] < 'D') 7689088058SAndreas Bießmann panic("Wrong board version '%.*s'\n", 7789088058SAndreas Bießmann sizeof(eeprom->board_version), 7889088058SAndreas Bießmann eeprom->board_version); 7989088058SAndreas Bießmann } else { 8089088058SAndreas Bießmann panic("Could not get board revision\n"); 8189088058SAndreas Bießmann } 82*1ea2301fSAndreas Bießmann } else { 83*1ea2301fSAndreas Bießmann memset(eeprom, 0, TRICORDER_EEPROM_SIZE); 8489088058SAndreas Bießmann } 8589088058SAndreas Bießmann } 8689088058SAndreas Bießmann 8789088058SAndreas Bießmann /** 8889088058SAndreas Bießmann * print_hwversion - print out a HW version string 8989088058SAndreas Bießmann * 9089088058SAndreas Bießmann * @eeprom - pointer to the eeprom 9189088058SAndreas Bießmann */ 9289088058SAndreas Bießmann static void print_hwversion(struct tricorder_eeprom *eeprom) 9389088058SAndreas Bießmann { 9489088058SAndreas Bießmann size_t len; 9589088058SAndreas Bießmann if (!eeprom) 9689088058SAndreas Bießmann panic("No eeprom given!"); 9789088058SAndreas Bießmann 9889088058SAndreas Bießmann printf("Board %.*s:%.*s serial %.*s", 9989088058SAndreas Bießmann sizeof(eeprom->board_name), eeprom->board_name, 10089088058SAndreas Bießmann sizeof(eeprom->board_version), eeprom->board_version, 10189088058SAndreas Bießmann sizeof(eeprom->board_serial), eeprom->board_serial); 10289088058SAndreas Bießmann 10389088058SAndreas Bießmann len = strnlen(eeprom->interface_version, 10489088058SAndreas Bießmann sizeof(eeprom->interface_version)); 10589088058SAndreas Bießmann if (len > 0) 10689088058SAndreas Bießmann printf(" HW interface version %.*s", 10789088058SAndreas Bießmann sizeof(eeprom->interface_version), 10889088058SAndreas Bießmann eeprom->interface_version); 10989088058SAndreas Bießmann puts("\n"); 11089088058SAndreas Bießmann } 11189088058SAndreas Bießmann 1128167af14SThomas Weber /* 1138167af14SThomas Weber * Routine: misc_init_r 1148167af14SThomas Weber * Description: Configure board specific parts 1158167af14SThomas Weber */ 1168167af14SThomas Weber int misc_init_r(void) 1178167af14SThomas Weber { 11889088058SAndreas Bießmann struct tricorder_eeprom eeprom; 11989088058SAndreas Bießmann get_eeprom(&eeprom); 12089088058SAndreas Bießmann print_hwversion(&eeprom); 12189088058SAndreas Bießmann 1228167af14SThomas Weber twl4030_power_init(); 123ad9f072cSAndreas Bießmann status_led_set(0, STATUS_LED_ON); 124ad9f072cSAndreas Bießmann status_led_set(1, STATUS_LED_ON); 125ad9f072cSAndreas Bießmann status_led_set(2, STATUS_LED_ON); 1268167af14SThomas Weber 1278167af14SThomas Weber dieid_num_r(); 1288167af14SThomas Weber 1298167af14SThomas Weber return 0; 1308167af14SThomas Weber } 1318167af14SThomas Weber 1328167af14SThomas Weber /* 1338167af14SThomas Weber * Routine: set_muxconf_regs 1348167af14SThomas Weber * Description: Setting up the configuration Mux registers specific to the 1358167af14SThomas Weber * hardware. Many pins need to be moved from protect to primary 1368167af14SThomas Weber * mode. 1378167af14SThomas Weber */ 1388167af14SThomas Weber void set_muxconf_regs(void) 1398167af14SThomas Weber { 1408167af14SThomas Weber MUX_TRICORDER(); 1418167af14SThomas Weber } 1428167af14SThomas Weber 1438167af14SThomas Weber #if defined(CONFIG_GENERIC_MMC) && !(defined(CONFIG_SPL_BUILD)) 1448167af14SThomas Weber int board_mmc_init(bd_t *bis) 1458167af14SThomas Weber { 146e3913f56SNikita Kiryanov return omap_mmc_init(0, 0, 0, -1, -1); 1478167af14SThomas Weber } 1488167af14SThomas Weber #endif 1498167af14SThomas Weber 1508167af14SThomas Weber /* 1518167af14SThomas Weber * Routine: get_board_mem_timings 1528167af14SThomas Weber * Description: If we use SPL then there is no x-loader nor config header 1538167af14SThomas Weber * so we have to setup the DDR timings ourself on the first bank. This 1548167af14SThomas Weber * provides the timing values back to the function that configures 1558167af14SThomas Weber * the memory. We have either one or two banks of 128MB DDR. 1568167af14SThomas Weber */ 1578c4445d2SPeter Barada void get_board_mem_timings(struct board_sdrc_timings *timings) 1588167af14SThomas Weber { 15901782965SAndreas Bießmann struct tricorder_eeprom eeprom; 16001782965SAndreas Bießmann get_eeprom(&eeprom); 1618167af14SThomas Weber 16201782965SAndreas Bießmann /* General SDRC config */ 16301782965SAndreas Bießmann if (eeprom.board_version[0] > 'D') { 16401782965SAndreas Bießmann /* use optimized timings for our SDRAM device */ 16501782965SAndreas Bießmann timings->mcfg = MCFG((256 << 20), 14); 16601782965SAndreas Bießmann #define MT46H64M32_TDAL 6 /* Twr/Tck + Trp/tck */ 16701782965SAndreas Bießmann /* 15/6 + 18/6 = 5.5 -> 6 */ 16801782965SAndreas Bießmann #define MT46H64M32_TDPL 3 /* 15/6 = 2.5 -> 3 (Twr) */ 16901782965SAndreas Bießmann #define MT46H64M32_TRRD 2 /* 12/6 = 2 */ 17001782965SAndreas Bießmann #define MT46H64M32_TRCD 3 /* 18/6 = 3 */ 17101782965SAndreas Bießmann #define MT46H64M32_TRP 3 /* 18/6 = 3 */ 17201782965SAndreas Bießmann #define MT46H64M32_TRAS 7 /* 42/6 = 7 */ 17301782965SAndreas Bießmann #define MT46H64M32_TRC 10 /* 60/6 = 10 */ 17401782965SAndreas Bießmann #define MT46H64M32_TRFC 12 /* 72/6 = 12 */ 17501782965SAndreas Bießmann timings->ctrla = ACTIM_CTRLA(MT46H64M32_TRFC, MT46H64M32_TRC, 17601782965SAndreas Bießmann MT46H64M32_TRAS, MT46H64M32_TRP, 17701782965SAndreas Bießmann MT46H64M32_TRCD, MT46H64M32_TRRD, 17801782965SAndreas Bießmann MT46H64M32_TDPL, 17901782965SAndreas Bießmann MT46H64M32_TDAL); 18001782965SAndreas Bießmann 18101782965SAndreas Bießmann #define MT46H64M32_TWTR 1 18201782965SAndreas Bießmann #define MT46H64M32_TCKE 1 18301782965SAndreas Bießmann #define MT46H64M32_XSR 19 /* 112.5/6 = 18.75 => ~19 */ 18401782965SAndreas Bießmann #define MT46H64M32_TXP 1 18501782965SAndreas Bießmann timings->ctrlb = ACTIM_CTRLB(MT46H64M32_TWTR, MT46H64M32_TCKE, 18601782965SAndreas Bießmann MT46H64M32_TXP, MT46H64M32_XSR); 18701782965SAndreas Bießmann 18801782965SAndreas Bießmann timings->mr = MICRON_V_MR_165; 18901782965SAndreas Bießmann timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 19001782965SAndreas Bießmann } else { 19101782965SAndreas Bießmann /* use conservative beagleboard timings as default */ 19201782965SAndreas Bießmann timings->mcfg = MICRON_V_MCFG_165(128 << 20); 1938c4445d2SPeter Barada timings->ctrla = MICRON_V_ACTIMA_165; 1948c4445d2SPeter Barada timings->ctrlb = MICRON_V_ACTIMB_165; 1958c4445d2SPeter Barada timings->mr = MICRON_V_MR_165; 19601782965SAndreas Bießmann timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz; 19701782965SAndreas Bießmann } 1988167af14SThomas Weber } 199