board/BuR/common: add br resetcontoller implementation
On many B&R boards we have a reset-controller, responsible for very early board-bringup (voltages, clocks, ...) and bootmode selection. To be ready for adding more B&R boards to source tree while avoiding duplicate code, we add the resetcontroller implementation to the common part of B&R boards. Signed-off-by: Hannes Schmelzer <hannes.schmelzer@br-automation.com>
This commit is contained in:
parent
2fac7a8294
commit
f4b9f0bdba
234
board/BuR/common/br_resetc.c
Normal file
234
board/BuR/common/br_resetc.c
Normal file
@ -0,0 +1,234 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* common reset-controller functions for B&R boards
|
||||
*
|
||||
* Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at>
|
||||
* B&R Industrial Automation GmbH - http://www.br-automation.com/ *
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <dm/uclass.h>
|
||||
#include "br_resetc.h"
|
||||
|
||||
/* I2C Address of controller */
|
||||
#define RSTCTRL_ADDR_PSOC 0x75
|
||||
#define RSTCTRL_ADDR_STM32 0x60
|
||||
|
||||
#define BMODE_DEFAULTAR 0
|
||||
#define BMODE_SERVICE 2
|
||||
#define BMODE_RUN 4
|
||||
#define BMODE_PME 12
|
||||
#define BMODE_DIAG 15
|
||||
|
||||
#ifdef CONFIG_LCD
|
||||
#include <lcd.h>
|
||||
#define LCD_SETCURSOR(x, y) lcd_position_cursor(x, y)
|
||||
#define LCD_PUTS(x) lcd_puts(x)
|
||||
#else
|
||||
#define LCD_SETCURSOR(x, y)
|
||||
#define LCD_PUTS(x)
|
||||
#endif /* CONFIG_LCD */
|
||||
|
||||
static const char *bootmodeascii[16] = {
|
||||
"BOOT", "reserved", "reserved", "reserved",
|
||||
"RUN", "reserved", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"PME", "reserved", "reserved", "DIAG",
|
||||
};
|
||||
|
||||
struct br_reset_t {
|
||||
struct udevice *i2cdev;
|
||||
u8 is_psoc;
|
||||
};
|
||||
|
||||
static struct br_reset_t resetc;
|
||||
|
||||
__weak int board_boot_key(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__weak void board_boot_led(unsigned int on)
|
||||
{
|
||||
}
|
||||
|
||||
static int resetc_init(void)
|
||||
{
|
||||
struct udevice *i2cbus;
|
||||
int rc;
|
||||
|
||||
rc = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
|
||||
if (rc) {
|
||||
printf("Cannot find I2C bus #0!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = dm_i2c_probe(i2cbus,
|
||||
RSTCTRL_ADDR_PSOC, 0, &resetc.i2cdev);
|
||||
if (rc) {
|
||||
resetc.is_psoc = 0;
|
||||
rc = dm_i2c_probe(i2cbus,
|
||||
RSTCTRL_ADDR_STM32, 0, &resetc.i2cdev);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
printf("Warning: cannot probe BuR resetcontroller!\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int br_resetc_regget(u8 reg, u8 *dst)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!resetc.i2cdev)
|
||||
rc = resetc_init();
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
return dm_i2c_read(resetc.i2cdev, reg, dst, 1);
|
||||
}
|
||||
|
||||
int br_resetc_regset(u8 reg, u8 val)
|
||||
{
|
||||
int rc = 0;
|
||||
u16 regw = (val << 8) | val;
|
||||
|
||||
if (!resetc.i2cdev)
|
||||
rc = resetc_init();
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
if (resetc.is_psoc)
|
||||
return dm_i2c_write(resetc.i2cdev, reg, (u8 *)®w, 2);
|
||||
|
||||
return dm_i2c_write(resetc.i2cdev, reg, (u8 *)®w, 1);
|
||||
}
|
||||
|
||||
int br_resetc_bmode(void)
|
||||
{
|
||||
int rc = 0;
|
||||
u16 regw;
|
||||
u8 regb, scr;
|
||||
int cnt;
|
||||
unsigned int bmode = 0;
|
||||
|
||||
if (!resetc.i2cdev)
|
||||
rc = resetc_init();
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_ENHSTATUS, ®b, 1);
|
||||
if (rc != 0) {
|
||||
printf("WARN: cannot read ENHSTATUS from resetcontroller!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = dm_i2c_read(resetc.i2cdev, RSTCTRL_SCRATCHREG0, &scr, 1);
|
||||
if (rc != 0) {
|
||||
printf("WARN: cannot read SCRATCHREG from resetcontroller!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
board_boot_led(1);
|
||||
|
||||
/* special bootmode from resetcontroller */
|
||||
if (regb & 0x4) {
|
||||
bmode = BMODE_DIAG;
|
||||
} else if (regb & 0x8) {
|
||||
bmode = BMODE_DEFAULTAR;
|
||||
} else if (board_boot_key() != 0) {
|
||||
cnt = 4;
|
||||
do {
|
||||
LCD_SETCURSOR(1, 8);
|
||||
switch (cnt) {
|
||||
case 4:
|
||||
LCD_PUTS
|
||||
("release KEY to enter SERVICE-mode. ");
|
||||
break;
|
||||
case 3:
|
||||
LCD_PUTS
|
||||
("release KEY to enter DIAGNOSE-mode. ");
|
||||
break;
|
||||
case 2:
|
||||
LCD_PUTS
|
||||
("release KEY to enter BOOT-mode. ");
|
||||
break;
|
||||
}
|
||||
mdelay(1000);
|
||||
cnt--;
|
||||
if (board_boot_key() == 0)
|
||||
break;
|
||||
} while (cnt);
|
||||
|
||||
switch (cnt) {
|
||||
case 0:
|
||||
bmode = BMODE_PME;
|
||||
break;
|
||||
case 1:
|
||||
bmode = BMODE_DEFAULTAR;
|
||||
break;
|
||||
case 2:
|
||||
bmode = BMODE_DIAG;
|
||||
break;
|
||||
case 3:
|
||||
bmode = BMODE_SERVICE;
|
||||
break;
|
||||
}
|
||||
} else if ((regb & 0x1) || scr == 0xCC) {
|
||||
bmode = BMODE_PME;
|
||||
} else {
|
||||
bmode = BMODE_RUN;
|
||||
}
|
||||
|
||||
LCD_SETCURSOR(1, 8);
|
||||
|
||||
switch (bmode) {
|
||||
case BMODE_PME:
|
||||
LCD_PUTS("entering PME-Mode (netscript). ");
|
||||
regw = 0x0C0C;
|
||||
break;
|
||||
case BMODE_DEFAULTAR:
|
||||
LCD_PUTS("entering BOOT-mode. ");
|
||||
regw = 0x0000;
|
||||
break;
|
||||
case BMODE_DIAG:
|
||||
LCD_PUTS("entering DIAGNOSE-mode. ");
|
||||
regw = 0x0F0F;
|
||||
break;
|
||||
case BMODE_SERVICE:
|
||||
LCD_PUTS("entering SERVICE mode. ");
|
||||
regw = 0xB4B4;
|
||||
break;
|
||||
case BMODE_RUN:
|
||||
LCD_PUTS("loading OS... ");
|
||||
regw = 0x0404;
|
||||
break;
|
||||
}
|
||||
|
||||
board_boot_led(0);
|
||||
|
||||
if (resetc.is_psoc)
|
||||
rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
|
||||
(u8 *)®w, 2);
|
||||
else
|
||||
rc = dm_i2c_write(resetc.i2cdev, RSTCTRL_SCRATCHREG0,
|
||||
(u8 *)®w, 1);
|
||||
|
||||
if (rc != 0)
|
||||
printf("WARN: cannot write into resetcontroller!\n");
|
||||
|
||||
if (resetc.is_psoc)
|
||||
printf("Reset: PSOC controller\n");
|
||||
else
|
||||
printf("Reset: STM32 controller\n");
|
||||
|
||||
printf("Mode: %s\n", bootmodeascii[regw & 0x0F]);
|
||||
env_set_ulong("b_mode", regw & 0x0F);
|
||||
|
||||
return rc;
|
||||
}
|
26
board/BuR/common/br_resetc.h
Normal file
26
board/BuR/common/br_resetc.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* common reset-controller functions for B&R boards
|
||||
*
|
||||
* Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at>
|
||||
* B&R Industrial Automation GmbH - http://www.br-automation.com/ *
|
||||
*/
|
||||
#ifndef __CONFIG_BRRESETC_H__
|
||||
#define __CONFIG_BRRESETC_H__
|
||||
#include <common.h>
|
||||
|
||||
int br_resetc_regget(u8 reg, u8 *dst);
|
||||
int br_resetc_regset(u8 reg, u8 val);
|
||||
int br_resetc_bmode(void);
|
||||
|
||||
/* reset controller register defines */
|
||||
#define RSTCTRL_CTRLREG 0x01
|
||||
#define RSTCTRL_SCRATCHREG0 0x04
|
||||
#define RSTCTRL_ENHSTATUS 0x07
|
||||
#define RSTCTRL_SCRATCHREG1 0x08
|
||||
#define RSTCTRL_RSTCAUSE 0x00
|
||||
#define RSTCTRL_ERSTCAUSE 0x09
|
||||
#define RSTCTRL_SPECGPIO_I 0x0A
|
||||
#define RSTCTRL_SPECGPIO_O 0x0B
|
||||
|
||||
#endif /* __CONFIG_BRRESETC_H__ */
|
Loading…
Reference in New Issue
Block a user