blob: daf0bb930ec0814a142dc35c3216245aae16f6fc [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Heiko Schocher499c4982013-08-19 16:39:01 +02002/*
3 * Common board functions for siemens AM335X based boards
4 * (C) Copyright 2013 Siemens Schweiz AG
5 * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
6 *
7 * Based on:
8 * U-Boot file:/board/ti/am335x/board.c
Nishanth Menoneaa39c62023-11-01 15:56:03 -05009 * Copyright (C) 2011, Texas Instruments, Incorporated - https://www.ti.com/
Heiko Schocher499c4982013-08-19 16:39:01 +020010 */
11
Simon Glassed38aef2020-05-10 11:40:03 -060012#include <command.h>
Simon Glass36736182019-11-14 12:57:24 -070013#include <serial.h>
Enrico Letofce91792024-01-24 15:43:54 +010014#include <watchdog.h>
Heiko Schocher499c4982013-08-19 16:39:01 +020015#include <asm/arch/clock.h>
Heiko Schocher499c4982013-08-19 16:39:01 +020016#include <asm/arch/sys_proto.h>
Heiko Schocher499c4982013-08-19 16:39:01 +020017#include <asm/gpio.h>
Simon Glass0ffb9d62017-05-31 19:47:48 -060018#include <asm/mach-types.h>
Enrico Leto2e740502024-01-24 15:43:53 +010019#include "board_am335x.h"
Enrico Leto096bfdc2024-01-24 15:43:49 +010020#include "eeprom.h"
21#include "factoryset.h"
Heiko Schocher499c4982013-08-19 16:39:01 +020022
23DECLARE_GLOBAL_DATA_PTR;
24
Simon Glass49c24a82024-09-29 19:49:47 -060025#ifdef CONFIG_XPL_BUILD
Heiko Schocher499c4982013-08-19 16:39:01 +020026void set_uart_mux_conf(void)
27{
28 enable_uart0_pin_mux();
29}
30
31void set_mux_conf_regs(void)
32{
33 /* Initalize the board header */
34 enable_i2c0_pin_mux();
Heiko Schocherb5e7d372015-05-28 07:27:36 +020035
36 /* enable early the console */
37 gd->baudrate = CONFIG_BAUDRATE;
38 serial_init();
Simon Glassd4b0fdb2024-08-21 10:19:04 -060039 gd->flags |= GD_FLG_HAVE_CONSOLE;
Enrico Leto32f433f2024-01-24 15:43:50 +010040
41 siemens_ee_setup();
Enrico Leto2e740502024-01-24 15:43:53 +010042 if (draco_read_eeprom() < 0)
Heiko Schocher499c4982013-08-19 16:39:01 +020043 puts("Could not get board ID.\n");
44
45 enable_board_pin_mux();
46}
47
48void sdram_init(void)
49{
Enrico Leto2e740502024-01-24 15:43:53 +010050 spl_draco_board_init();
51 draco_init_ddr();
Heiko Schocher499c4982013-08-19 16:39:01 +020052
53 return;
54}
Simon Glass49c24a82024-09-29 19:49:47 -060055#endif /* #ifdef CONFIG_XPL_BUILD */
Heiko Schocher499c4982013-08-19 16:39:01 +020056
Simon Glass49c24a82024-09-29 19:49:47 -060057#ifndef CONFIG_XPL_BUILD
Heiko Schocher499c4982013-08-19 16:39:01 +020058/*
59 * Basic board specific setup. Pinmux has been handled already.
60 */
61int board_init(void)
62{
63#if defined(CONFIG_HW_WATCHDOG)
64 hw_watchdog_init();
65#endif /* defined(CONFIG_HW_WATCHDOG) */
Enrico Leto32f433f2024-01-24 15:43:50 +010066 if (siemens_ee_setup() < 0)
Heiko Schocher499c4982013-08-19 16:39:01 +020067 puts("Could not get board ID.\n");
Heiko Schocherd17c3fc2015-06-16 14:59:34 +020068#ifdef CONFIG_MACH_TYPE
Heiko Schocher499c4982013-08-19 16:39:01 +020069 gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
Heiko Schocherd17c3fc2015-06-16 14:59:34 +020070#endif
Tom Rinibb4dd962022-11-16 13:10:37 -050071 gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
Heiko Schocher499c4982013-08-19 16:39:01 +020072
73#ifdef CONFIG_FACTORYSET
Enrico Leto096bfdc2024-01-24 15:43:49 +010074 factoryset_read_eeprom(SIEMENS_EE_I2C_ADDR);
Heiko Schocher499c4982013-08-19 16:39:01 +020075#endif
Heiko Schochercbec11a2016-06-07 08:55:45 +020076
Heiko Schocher499c4982013-08-19 16:39:01 +020077 gpmc_init();
78
Heiko Schocher499c4982013-08-19 16:39:01 +020079 return 0;
80}
Simon Glass49c24a82024-09-29 19:49:47 -060081#endif /* #ifndef CONFIG_XPL_BUILD */
Heiko Schocher499c4982013-08-19 16:39:01 +020082
83#define OSC (V_OSCK/1000000)
84const struct dpll_params dpll_ddr = {
85 DDR_PLL_FREQ, OSC-1, 1, -1, -1, -1, -1};
86
87const struct dpll_params *get_dpll_ddr_params(void)
88{
89 return &dpll_ddr;
90}
91
Simon Glass49c24a82024-09-29 19:49:47 -060092#ifndef CONFIG_XPL_BUILD
Heiko Schocherd17c3fc2015-06-16 14:59:34 +020093
94#define MAX_NR_LEDS 10
95#define MAX_PIN_NUMBER 128
96#define STARTUP 0
97
Heiko Schocher499c4982013-08-19 16:39:01 +020098#if defined(BOARD_DFU_BUTTON_GPIO)
Heiko Schocherd17c3fc2015-06-16 14:59:34 +020099unsigned char get_button_state(char * const envname, unsigned char def)
Heiko Schocher499c4982013-08-19 16:39:01 +0200100{
101 int button = 0;
102 int gpio;
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200103 char *ptr_env;
Heiko Schocher499c4982013-08-19 16:39:01 +0200104
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200105 /* If button is not found we take default */
Simon Glass64b723f2017-08-03 12:22:12 -0600106 ptr_env = env_get(envname);
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200107 if (NULL == ptr_env) {
108 gpio = def;
109 } else {
110 gpio = (unsigned char)simple_strtoul(ptr_env, NULL, 0);
111 if (gpio > MAX_PIN_NUMBER)
112 gpio = def;
113 }
114
115 gpio_request(gpio, "");
Heiko Schocher499c4982013-08-19 16:39:01 +0200116 gpio_direction_input(gpio);
117 if (gpio_get_value(gpio))
118 button = 1;
119 else
120 button = 0;
121
122 gpio_free(gpio);
Heiko Schocher499c4982013-08-19 16:39:01 +0200123
124 return button;
125}
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200126/**
127 * This command returns the status of the user button on
128 * Input - none
129 * Returns - 1 if button is held down
130 * 0 if button is not held down
Egli, Samuelfdb5e262014-04-24 17:57:54 +0200131 */
132static int
Simon Glassed38aef2020-05-10 11:40:03 -0600133do_userbutton(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Egli, Samuelfdb5e262014-04-24 17:57:54 +0200134{
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200135 int button = 0;
136 button = get_button_state("button_dfu0", BOARD_DFU_BUTTON_GPIO);
137 button |= get_button_state("button_dfu1", BOARD_DFU_BUTTON_GPIO);
138 return button;
Egli, Samuelfdb5e262014-04-24 17:57:54 +0200139}
140
141U_BOOT_CMD(
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200142 dfubutton, CONFIG_SYS_MAXARGS, 1, do_userbutton,
143 "Return the status of the DFU button",
144 ""
Egli, Samuelfdb5e262014-04-24 17:57:54 +0200145);
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200146#endif
Heiko Schocher499c4982013-08-19 16:39:01 +0200147
148static int
Simon Glassed38aef2020-05-10 11:40:03 -0600149do_usertestwdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Heiko Schocher499c4982013-08-19 16:39:01 +0200150{
151 printf("\n\n\n Go into infinite loop\n\n\n");
152 while (1)
153 ;
154 return 0;
155};
156
157U_BOOT_CMD(
158 testwdt, CONFIG_SYS_MAXARGS, 1, do_usertestwdt,
159 "Sends U-Boot into infinite loop",
160 ""
161);
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200162
163/**
164 * Get led gpios from env and set them.
165 * The led define in environment need to need to be of the form ledN=NN,S0,S1
166 * where N is an unsigned integer from 0 to 9 and S0 and S1 is 0 or 1. S0
167 * defines the startup state of the led, S1 the special state of the led when
168 * it enters e.g. dfu mode.
169 */
170void set_env_gpios(unsigned char state)
171{
172 char *ptr_env;
173 char str_tmp[5]; /* must contain "ledX"*/
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200174 unsigned char i, idx, pos1, pos2, ccount;
175 unsigned char gpio_n, gpio_s0, gpio_s1;
176
177 for (i = 0; i < MAX_NR_LEDS; i++) {
Heinrich Schuchardt32c63b62019-08-22 21:58:26 +0200178 sprintf(str_tmp, "led%d", i);
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200179
180 /* If env var is not found we stop */
Simon Glass64b723f2017-08-03 12:22:12 -0600181 ptr_env = env_get(str_tmp);
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200182 if (NULL == ptr_env)
183 break;
184
185 /* Find sperators position */
186 pos1 = 0;
187 pos2 = 0;
188 ccount = 0;
189 for (idx = 0; ptr_env[idx] != '\0'; idx++) {
190 if (ptr_env[idx] == ',') {
191 if (ccount++ < 1)
192 pos1 = idx;
193 else
194 pos2 = idx;
195 }
196 }
197 /* Bad led description skip this definition */
198 if (pos2 <= pos1 || ccount > 2)
199 continue;
200
201 /* Get pin number and request gpio */
202 memset(str_tmp, 0, sizeof(str_tmp));
203 strncpy(str_tmp, ptr_env, pos1*sizeof(char));
204 gpio_n = (unsigned char)simple_strtoul(str_tmp, NULL, 0);
205
206 /* Invalid gpio number skip definition */
207 if (gpio_n > MAX_PIN_NUMBER)
208 continue;
209
210 gpio_request(gpio_n, "");
211
212 if (state == STARTUP) {
213 /* get pin state 0 and set */
214 memset(str_tmp, 0, sizeof(str_tmp));
215 strncpy(str_tmp, ptr_env+pos1+1,
216 (pos2-pos1-1)*sizeof(char));
217 gpio_s0 = (unsigned char)simple_strtoul(str_tmp, NULL,
218 0);
219
220 gpio_direction_output(gpio_n, gpio_s0);
221
222 } else {
223 /* get pin state 1 and set */
224 memset(str_tmp, 0, sizeof(str_tmp));
225 strcpy(str_tmp, ptr_env+pos2+1);
226 gpio_s1 = (unsigned char)simple_strtoul(str_tmp, NULL,
227 0);
228 gpio_direction_output(gpio_n, gpio_s1);
229 }
230 } /* loop through defined led in environment */
231}
232
Simon Glassed38aef2020-05-10 11:40:03 -0600233static int do_board_led(struct cmd_tbl *cmdtp, int flag, int argc,
234 char *const argv[])
Heiko Schocherd17c3fc2015-06-16 14:59:34 +0200235{
236 if (argc != 2)
237 return CMD_RET_USAGE;
238 if ((unsigned char)simple_strtoul(argv[1], NULL, 0) == STARTUP)
239 set_env_gpios(0);
240 else
241 set_env_gpios(1);
242 return 0;
243};
244
245U_BOOT_CMD(
246 draco_led, CONFIG_SYS_MAXARGS, 2, do_board_led,
247 "Set LEDs defined in environment",
248 "<0|1>"
249);
Simon Glass49c24a82024-09-29 19:49:47 -0600250#endif /* !CONFIG_XPL_BUILD */