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