blob: 190f141091f2369dcb6ccca1efd0dd781dcd1916 [file] [log] [blame]
Hannes Schmelzerf4b9f0b2019-04-10 14:13:14 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * common reset-controller functions for B&R boards
4 *
5 * Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at>
6 * B&R Industrial Automation GmbH - http://www.br-automation.com/ *
7 */
8#include <common.h>
9#include <errno.h>
10#include <i2c.h>
11#include <dm/uclass.h>
12#include "br_resetc.h"
13
14/* I2C Address of controller */
15#define RSTCTRL_ADDR_PSOC 0x75
16#define RSTCTRL_ADDR_STM32 0x60
17
18#define BMODE_DEFAULTAR 0
19#define BMODE_SERVICE 2
20#define BMODE_RUN 4
21#define BMODE_PME 12
22#define BMODE_DIAG 15
23
24#ifdef CONFIG_LCD
25#include <lcd.h>
26#define LCD_SETCURSOR(x, y) lcd_position_cursor(x, y)
27#define LCD_PUTS(x) lcd_puts(x)
28#else
29#define LCD_SETCURSOR(x, y)
30#define LCD_PUTS(x)
31#endif /* CONFIG_LCD */
32
33static const char *bootmodeascii[16] = {
34 "BOOT", "reserved", "reserved", "reserved",
35 "RUN", "reserved", "reserved", "reserved",
36 "reserved", "reserved", "reserved", "reserved",
37 "PME", "reserved", "reserved", "DIAG",
38};
39
40struct br_reset_t {
41 struct udevice *i2cdev;
42 u8 is_psoc;
43};
44
45static struct br_reset_t resetc;
46
47__weak int board_boot_key(void)
48{
49 return 0;
50}
51
52__weak void board_boot_led(unsigned int on)
53{
54}
55
56static int resetc_init(void)
57{
58 struct udevice *i2cbus;
59 int rc;
60
61 rc = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
62 if (rc) {
63 printf("Cannot find I2C bus #0!\n");
64 return -1;
65 }
66
67 rc = dm_i2c_probe(i2cbus,
68 RSTCTRL_ADDR_PSOC, 0, &resetc.i2cdev);
69 if (rc) {
70 resetc.is_psoc = 0;
71 rc = dm_i2c_probe(i2cbus,
72 RSTCTRL_ADDR_STM32, 0, &resetc.i2cdev);
73 }
74
75 if (rc)
76 printf("Warning: cannot probe BuR resetcontroller!\n");
77
78 return rc;
79}
80
81int br_resetc_regget(u8 reg, u8 *dst)
82{
83 int rc = 0;
84
85 if (!resetc.i2cdev)
86 rc = resetc_init();
87
88 if (rc != 0)
89 return rc;
90
91 return dm_i2c_read(resetc.i2cdev, reg, dst, 1);
92}
93
94int br_resetc_regset(u8 reg, u8 val)
95{
96 int rc = 0;
97 u16 regw = (val << 8) | val;
98
99 if (!resetc.i2cdev)
100 rc = resetc_init();
101
102 if (rc != 0)
103 return rc;
104
105 if (resetc.is_psoc)
106 return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 2);
107
108 return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 1);
109}
110
111int br_resetc_bmode(void)
112{
113 int rc = 0;
114 u16 regw;
115 u8 regb, scr;
116 int cnt;
117 unsigned int bmode = 0;
118
119 if (!resetc.i2cdev)
120 rc = resetc_init();
121
122 if (rc != 0)
123 return rc;
124
125 rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_ENHSTATUS, &regb, 1);
126 if (rc != 0) {
127 printf("WARN: cannot read ENHSTATUS from resetcontroller!\n");
128 return -1;
129 }
130
131 rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_SCRATCHREG0, &scr, 1);
132 if (rc != 0) {
133 printf("WARN: cannot read SCRATCHREG from resetcontroller!\n");
134 return -1;
135 }
136
137 board_boot_led(1);
138
139 /* special bootmode from resetcontroller */
140 if (regb & 0x4) {
141 bmode = BMODE_DIAG;
142 } else if (regb & 0x8) {
143 bmode = BMODE_DEFAULTAR;
144 } else if (board_boot_key() != 0) {
145 cnt = 4;
146 do {
147 LCD_SETCURSOR(1, 8);
148 switch (cnt) {
149 case 4:
150 LCD_PUTS
151 ("release KEY to enter SERVICE-mode. ");
152 break;
153 case 3:
154 LCD_PUTS
155 ("release KEY to enter DIAGNOSE-mode. ");
156 break;
157 case 2:
158 LCD_PUTS
159 ("release KEY to enter BOOT-mode. ");
160 break;
161 }
162 mdelay(1000);
163 cnt--;
164 if (board_boot_key() == 0)
165 break;
166 } while (cnt);
167
168 switch (cnt) {
169 case 0:
170 bmode = BMODE_PME;
171 break;
172 case 1:
173 bmode = BMODE_DEFAULTAR;
174 break;
175 case 2:
176 bmode = BMODE_DIAG;
177 break;
178 case 3:
179 bmode = BMODE_SERVICE;
180 break;
181 }
182 } else if ((regb & 0x1) || scr == 0xCC) {
183 bmode = BMODE_PME;
184 } else {
185 bmode = BMODE_RUN;
186 }
187
188 LCD_SETCURSOR(1, 8);
189
190 switch (bmode) {
191 case BMODE_PME:
192 LCD_PUTS("entering PME-Mode (netscript). ");
193 regw = 0x0C0C;
194 break;
195 case BMODE_DEFAULTAR:
196 LCD_PUTS("entering BOOT-mode. ");
197 regw = 0x0000;
198 break;
199 case BMODE_DIAG:
200 LCD_PUTS("entering DIAGNOSE-mode. ");
201 regw = 0x0F0F;
202 break;
203 case BMODE_SERVICE:
204 LCD_PUTS("entering SERVICE mode. ");
205 regw = 0xB4B4;
206 break;
207 case BMODE_RUN:
208 LCD_PUTS("loading OS... ");
209 regw = 0x0404;
210 break;
211 }
212
213 board_boot_led(0);
214
215 if (resetc.is_psoc)
216 rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
217 (u8 *)&regw, 2);
218 else
219 rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
220 (u8 *)&regw, 1);
221
222 if (rc != 0)
223 printf("WARN: cannot write into resetcontroller!\n");
224
225 if (resetc.is_psoc)
226 printf("Reset: PSOC controller\n");
227 else
228 printf("Reset: STM32 controller\n");
229
230 printf("Mode: %s\n", bootmodeascii[regw & 0x0F]);
231 env_set_ulong("b_mode", regw & 0x0F);
232
233 return rc;
234}