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