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