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