190f141091f2369dcb6ccca1efd0dd781dcd1916
[platform/kernel/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 <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
33 static 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
40 struct br_reset_t {
41         struct udevice *i2cdev;
42         u8 is_psoc;
43 };
44
45 static 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
56 static 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
81 int 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
94 int 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
111 int 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 }