1// SPDX-License-Identifier: GPL-2.0+
2/*
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
9 * Copyright (C) 2011, Texas Instruments, Incorporated - https://www.ti.com/
10 */
11
12#include <command.h>
13#include <serial.h>
14#include <watchdog.h>
15#include <asm/arch/clock.h>
16#include <asm/arch/sys_proto.h>
17#include <asm/gpio.h>
18#include <asm/mach-types.h>
19#include "board_am335x.h"
20#include "eeprom.h"
21#include "factoryset.h"
22
23DECLARE_GLOBAL_DATA_PTR;
24
25
26#ifdef CONFIG_SPL_BUILD
27void set_uart_mux_conf(void)
28{
29	enable_uart0_pin_mux();
30}
31
32void set_mux_conf_regs(void)
33{
34	/* Initalize the board header */
35	enable_i2c0_pin_mux();
36
37	/* enable early the console */
38	gd->baudrate = CONFIG_BAUDRATE;
39	serial_init();
40	gd->have_console = 1;
41
42	siemens_ee_setup();
43	if (draco_read_eeprom() < 0)
44		puts("Could not get board ID.\n");
45
46	enable_board_pin_mux();
47}
48
49void sdram_init(void)
50{
51	spl_draco_board_init();
52	draco_init_ddr();
53
54	return;
55}
56#endif /* #ifdef CONFIG_SPL_BUILD */
57
58#ifndef CONFIG_SPL_BUILD
59/*
60 * Basic board specific setup.  Pinmux has been handled already.
61 */
62int board_init(void)
63{
64#if defined(CONFIG_HW_WATCHDOG)
65	hw_watchdog_init();
66#endif /* defined(CONFIG_HW_WATCHDOG) */
67	if (siemens_ee_setup() < 0)
68		puts("Could not get board ID.\n");
69#ifdef CONFIG_MACH_TYPE
70	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
71#endif
72	gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
73
74#ifdef CONFIG_FACTORYSET
75	factoryset_read_eeprom(SIEMENS_EE_I2C_ADDR);
76#endif
77
78	gpmc_init();
79
80	return 0;
81}
82#endif /* #ifndef CONFIG_SPL_BUILD */
83
84#define OSC	(V_OSCK/1000000)
85const struct dpll_params dpll_ddr = {
86		DDR_PLL_FREQ, OSC-1, 1, -1, -1, -1, -1};
87
88const struct dpll_params *get_dpll_ddr_params(void)
89{
90	return &dpll_ddr;
91}
92
93#ifndef CONFIG_SPL_BUILD
94
95#define MAX_NR_LEDS	10
96#define MAX_PIN_NUMBER	128
97#define STARTUP	0
98
99#if defined(BOARD_DFU_BUTTON_GPIO)
100unsigned char get_button_state(char * const envname, unsigned char def)
101{
102	int button = 0;
103	int gpio;
104	char *ptr_env;
105
106	/* If button is not found we take default */
107	ptr_env = env_get(envname);
108	if (NULL == ptr_env) {
109		gpio = def;
110	} else {
111		gpio = (unsigned char)simple_strtoul(ptr_env, NULL, 0);
112		if (gpio > MAX_PIN_NUMBER)
113			gpio = def;
114	}
115
116	gpio_request(gpio, "");
117	gpio_direction_input(gpio);
118	if (gpio_get_value(gpio))
119		button = 1;
120	else
121		button = 0;
122
123	gpio_free(gpio);
124
125	return button;
126}
127/**
128 * This command returns the status of the user button on
129 * Input - none
130 * Returns -	1 if button is held down
131 *		0 if button is not held down
132 */
133static int
134do_userbutton(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
135{
136	int button = 0;
137	button = get_button_state("button_dfu0", BOARD_DFU_BUTTON_GPIO);
138	button |= get_button_state("button_dfu1", BOARD_DFU_BUTTON_GPIO);
139	return button;
140}
141
142U_BOOT_CMD(
143	dfubutton, CONFIG_SYS_MAXARGS, 1, do_userbutton,
144	"Return the status of the DFU button",
145	""
146);
147#endif
148
149static int
150do_usertestwdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
151{
152	printf("\n\n\n Go into infinite loop\n\n\n");
153	while (1)
154		;
155	return 0;
156};
157
158U_BOOT_CMD(
159	testwdt, CONFIG_SYS_MAXARGS, 1,	do_usertestwdt,
160	"Sends U-Boot into infinite loop",
161	""
162);
163
164/**
165 * Get led gpios from env and set them.
166 * The led define in environment need to need to be of the form ledN=NN,S0,S1
167 * where N is an unsigned integer from 0 to 9 and S0 and S1 is 0 or 1. S0
168 * defines the startup state of the led, S1 the special state of the led when
169 * it enters e.g. dfu mode.
170 */
171void set_env_gpios(unsigned char state)
172{
173	char *ptr_env;
174	char str_tmp[5];	/* must contain "ledX"*/
175	unsigned char i, idx, pos1, pos2, ccount;
176	unsigned char gpio_n, gpio_s0, gpio_s1;
177
178	for (i = 0; i < MAX_NR_LEDS; i++) {
179		sprintf(str_tmp, "led%d", i);
180
181		/* If env var is not found we stop */
182		ptr_env = env_get(str_tmp);
183		if (NULL == ptr_env)
184			break;
185
186		/* Find sperators position */
187		pos1 = 0;
188		pos2 = 0;
189		ccount = 0;
190		for (idx = 0; ptr_env[idx] != '\0'; idx++) {
191			if (ptr_env[idx] == ',') {
192				if (ccount++ < 1)
193					pos1 = idx;
194				else
195					pos2 = idx;
196			}
197		}
198		/* Bad led description skip this definition */
199		if (pos2 <= pos1 || ccount > 2)
200			continue;
201
202		/* Get pin number and request gpio */
203		memset(str_tmp, 0, sizeof(str_tmp));
204		strncpy(str_tmp, ptr_env, pos1*sizeof(char));
205		gpio_n = (unsigned char)simple_strtoul(str_tmp, NULL, 0);
206
207		/* Invalid gpio number skip definition */
208		if (gpio_n > MAX_PIN_NUMBER)
209			continue;
210
211		gpio_request(gpio_n, "");
212
213		if (state == STARTUP) {
214			/* get pin state 0 and set */
215			memset(str_tmp, 0, sizeof(str_tmp));
216			strncpy(str_tmp, ptr_env+pos1+1,
217				(pos2-pos1-1)*sizeof(char));
218			gpio_s0 = (unsigned char)simple_strtoul(str_tmp, NULL,
219								0);
220
221			gpio_direction_output(gpio_n, gpio_s0);
222
223		} else {
224			/* get pin state 1 and set */
225			memset(str_tmp, 0, sizeof(str_tmp));
226			strcpy(str_tmp, ptr_env+pos2+1);
227			gpio_s1 = (unsigned char)simple_strtoul(str_tmp, NULL,
228								0);
229			gpio_direction_output(gpio_n, gpio_s1);
230		}
231	} /* loop through defined led in environment */
232}
233
234static int do_board_led(struct cmd_tbl *cmdtp, int flag, int argc,
235			char *const argv[])
236{
237	if (argc != 2)
238		return CMD_RET_USAGE;
239	if ((unsigned char)simple_strtoul(argv[1], NULL, 0) == STARTUP)
240		set_env_gpios(0);
241	else
242		set_env_gpios(1);
243	return 0;
244};
245
246U_BOOT_CMD(
247	draco_led, CONFIG_SYS_MAXARGS, 2,	do_board_led,
248	"Set LEDs defined in environment",
249	"<0|1>"
250);
251#endif /* !CONFIG_SPL_BUILD */
252