1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * board.c 4 * 5 * Board functions for B&R BRPPT1 6 * 7 * Copyright (C) 2013 Hannes Schmelzer <oe5hpm@oevsv.at> 8 * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com 9 * 10 */ 11 12#include <common.h> 13#include <bootcount.h> 14#include <env.h> 15#include <errno.h> 16#include <init.h> 17#include <spl.h> 18#include <asm/arch/cpu.h> 19#include <asm/arch/hardware.h> 20#include <asm/arch/omap.h> 21#include <asm/arch/ddr_defs.h> 22#include <asm/arch/clock.h> 23#include <asm/arch/gpio.h> 24#include <asm/arch/sys_proto.h> 25#include <asm/arch/mem.h> 26#include <asm/global_data.h> 27#include <asm/io.h> 28#include <asm/emif.h> 29#include <asm/gpio.h> 30#include <i2c.h> 31#include <power/tps65217.h> 32#include "../common/bur_common.h" 33#include <watchdog.h> 34 35DECLARE_GLOBAL_DATA_PTR; 36 37/* --------------------------------------------------------------------------*/ 38/* -- defines for GPIO -- */ 39#define REPSWITCH (0+20) /* GPIO0_20 */ 40 41#if defined(CONFIG_SPL_BUILD) 42/* TODO: check ram-timing ! */ 43static const struct ddr_data ddr3_data = { 44 .datardsratio0 = MT41K256M16HA125E_RD_DQS, 45 .datawdsratio0 = MT41K256M16HA125E_WR_DQS, 46 .datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE, 47 .datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA, 48}; 49 50static const struct cmd_control ddr3_cmd_ctrl_data = { 51 .cmd0csratio = MT41K256M16HA125E_RATIO, 52 .cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 53 54 .cmd1csratio = MT41K256M16HA125E_RATIO, 55 .cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 56 57 .cmd2csratio = MT41K256M16HA125E_RATIO, 58 .cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT, 59}; 60 61static struct emif_regs ddr3_emif_reg_data = { 62 .sdram_config = MT41K256M16HA125E_EMIF_SDCFG, 63 .ref_ctrl = MT41K256M16HA125E_EMIF_SDREF, 64 .sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1, 65 .sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2, 66 .sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3, 67 .zq_config = MT41K256M16HA125E_ZQ_CFG, 68 .emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY, 69}; 70 71static const struct ctrl_ioregs ddr3_ioregs = { 72 .cm0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 73 .cm1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 74 .cm2ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 75 .dt0ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 76 .dt1ioctl = MT41K256M16HA125E_IOCTRL_VALUE, 77}; 78 79#define OSC (V_OSCK/1000000) 80static const struct dpll_params dpll_ddr3 = { 400, OSC-1, 1, -1, -1, -1, -1}; 81 82void am33xx_spl_board_init(void) 83{ 84 int rc; 85 86 struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; 87 /*struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;*/ 88 struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; 89 90 /* 91 * in TRM they write a reset value of 1 (=CLK_M_OSC) for the 92 * CLKSEL_TIMER6_CLK Register, in fact reset value is 0, so we need set 93 * the source of timer6 clk to CLK_M_OSC 94 */ 95 writel(0x01, &cmdpll->clktimer6clk); 96 97 /* enable additional clocks of modules which are accessed later */ 98 u32 *const clk_domains[] = { 99 &cmper->lcdcclkstctrl, 100 0 101 }; 102 103 u32 *const clk_modules_tsspecific[] = { 104 &cmper->lcdclkctrl, 105 &cmper->timer5clkctrl, 106 &cmper->timer6clkctrl, 107 0 108 }; 109 do_enable_clocks(clk_domains, clk_modules_tsspecific, 1); 110 111 /* setup I2C */ 112 enable_i2c_pin_mux(); 113 114 pmicsetup(0, 0); 115 116 /* peripheral reset */ 117 rc = gpio_request(64 + 29, "GPMC_WAIT1"); 118 if (rc != 0) 119 printf("cannot request GPMC_WAIT1 GPIO!\n"); 120 rc = gpio_direction_output(64 + 29, 1); 121 if (rc != 0) 122 printf("cannot set GPMC_WAIT1 GPIO!\n"); 123 124 rc = gpio_request(64 + 28, "GPMC_WAIT0"); 125 if (rc != 0) 126 printf("cannot request GPMC_WAIT0 GPIO!\n"); 127 rc = gpio_direction_output(64 + 28, 1); 128 if (rc != 0) 129 printf("cannot set GPMC_WAIT0 GPIO!\n"); 130 131} 132 133const struct dpll_params *get_dpll_ddr_params(void) 134{ 135 return &dpll_ddr3; 136} 137 138void sdram_init(void) 139{ 140 config_ddr(400, &ddr3_ioregs, 141 &ddr3_data, 142 &ddr3_cmd_ctrl_data, 143 &ddr3_emif_reg_data, 0); 144} 145#endif /* CONFIG_SPL_BUILD */ 146 147/* Basic board specific setup. Pinmux has been handled already. */ 148int board_init(void) 149{ 150#if defined(CONFIG_HW_WATCHDOG) 151 hw_watchdog_init(); 152#endif 153 gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; 154 155 return 0; 156} 157 158#ifdef CONFIG_BOARD_LATE_INIT 159static char *bootmodeascii[16] = { 160 "BOOT", "reserved", "reserved", "reserved", 161 "RUN", "reserved", "reserved", "reserved", 162 "reserved", "reserved", "reserved", "reserved", 163 "PME", "reserved", "reserved", "DIAG", 164}; 165 166int board_late_init(void) 167{ 168 unsigned char bmode = 0; 169 ulong bootcount = 0; 170 int rc; 171 172 bootcount = bootcount_load() & 0xF; 173 174 rc = gpio_request(REPSWITCH, "REPSWITCH"); 175 176 if (rc != 0 || gpio_get_value(REPSWITCH) == 0 || bootcount == 12) 177 bmode = 12; 178 else if (bootcount > 0) 179 bmode = 0; 180 else 181 bmode = 4; 182 183 printf("Mode: %s\n", bootmodeascii[bmode & 0x0F]); 184 env_set_ulong("b_mode", bmode); 185 186 /* get sure that bootcmd isn't affected by any bootcount value */ 187 env_set_ulong("bootlimit", 0); 188 189 return 0; 190} 191#endif /* CONFIG_BOARD_LATE_INIT */ 192