blob: c8cc73ab1417167499c7be1f4ece82e618efbe72 [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
Hannes Schmelzer7a56c932019-05-10 11:22:00 +020067 resetc.is_psoc = 1;
Hannes Schmelzerf4b9f0b2019-04-10 14:13:14 +020068 rc = dm_i2c_probe(i2cbus,
69 RSTCTRL_ADDR_PSOC, 0, &resetc.i2cdev);
70 if (rc) {
71 resetc.is_psoc = 0;
72 rc = dm_i2c_probe(i2cbus,
73 RSTCTRL_ADDR_STM32, 0, &resetc.i2cdev);
74 }
75
76 if (rc)
77 printf("Warning: cannot probe BuR resetcontroller!\n");
78
79 return rc;
80}
81
82int br_resetc_regget(u8 reg, u8 *dst)
83{
84 int rc = 0;
85
86 if (!resetc.i2cdev)
87 rc = resetc_init();
88
89 if (rc != 0)
90 return rc;
91
92 return dm_i2c_read(resetc.i2cdev, reg, dst, 1);
93}
94
95int br_resetc_regset(u8 reg, u8 val)
96{
97 int rc = 0;
98 u16 regw = (val << 8) | val;
99
100 if (!resetc.i2cdev)
101 rc = resetc_init();
102
103 if (rc != 0)
104 return rc;
105
106 if (resetc.is_psoc)
107 return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 2);
108
109 return dm_i2c_write(resetc.i2cdev, reg, (u8 *)&regw, 1);
110}
111
112int br_resetc_bmode(void)
113{
114 int rc = 0;
115 u16 regw;
116 u8 regb, scr;
117 int cnt;
118 unsigned int bmode = 0;
119
120 if (!resetc.i2cdev)
121 rc = resetc_init();
122
123 if (rc != 0)
124 return rc;
125
126 rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_ENHSTATUS, &regb, 1);
127 if (rc != 0) {
128 printf("WARN: cannot read ENHSTATUS from resetcontroller!\n");
129 return -1;
130 }
131
132 rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_SCRATCHREG0, &scr, 1);
133 if (rc != 0) {
134 printf("WARN: cannot read SCRATCHREG from resetcontroller!\n");
135 return -1;
136 }
137
138 board_boot_led(1);
139
140 /* special bootmode from resetcontroller */
141 if (regb & 0x4) {
142 bmode = BMODE_DIAG;
143 } else if (regb & 0x8) {
144 bmode = BMODE_DEFAULTAR;
145 } else if (board_boot_key() != 0) {
146 cnt = 4;
147 do {
148 LCD_SETCURSOR(1, 8);
149 switch (cnt) {
150 case 4:
151 LCD_PUTS
152 ("release KEY to enter SERVICE-mode. ");
153 break;
154 case 3:
155 LCD_PUTS
156 ("release KEY to enter DIAGNOSE-mode. ");
157 break;
158 case 2:
159 LCD_PUTS
160 ("release KEY to enter BOOT-mode. ");
161 break;
162 }
163 mdelay(1000);
164 cnt--;
165 if (board_boot_key() == 0)
166 break;
167 } while (cnt);
168
169 switch (cnt) {
170 case 0:
171 bmode = BMODE_PME;
172 break;
173 case 1:
174 bmode = BMODE_DEFAULTAR;
175 break;
176 case 2:
177 bmode = BMODE_DIAG;
178 break;
179 case 3:
180 bmode = BMODE_SERVICE;
181 break;
182 }
183 } else if ((regb & 0x1) || scr == 0xCC) {
184 bmode = BMODE_PME;
185 } else {
186 bmode = BMODE_RUN;
187 }
188
189 LCD_SETCURSOR(1, 8);
190
191 switch (bmode) {
192 case BMODE_PME:
193 LCD_PUTS("entering PME-Mode (netscript). ");
194 regw = 0x0C0C;
195 break;
196 case BMODE_DEFAULTAR:
197 LCD_PUTS("entering BOOT-mode. ");
198 regw = 0x0000;
199 break;
200 case BMODE_DIAG:
201 LCD_PUTS("entering DIAGNOSE-mode. ");
202 regw = 0x0F0F;
203 break;
204 case BMODE_SERVICE:
205 LCD_PUTS("entering SERVICE mode. ");
206 regw = 0xB4B4;
207 break;
208 case BMODE_RUN:
209 LCD_PUTS("loading OS... ");
210 regw = 0x0404;
211 break;
212 }
213
214 board_boot_led(0);
215
216 if (resetc.is_psoc)
217 rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
218 (u8 *)&regw, 2);
219 else
220 rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
221 (u8 *)&regw, 1);
222
223 if (rc != 0)
224 printf("WARN: cannot write into resetcontroller!\n");
225
226 if (resetc.is_psoc)
227 printf("Reset: PSOC controller\n");
228 else
229 printf("Reset: STM32 controller\n");
230
231 printf("Mode: %s\n", bootmodeascii[regw & 0x0F]);
232 env_set_ulong("b_mode", regw & 0x0F);
233
234 return rc;
235}