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