aboutsummaryrefslogtreecommitdiff
path: root/board/st/stm32mp1/stm32mp1.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/st/stm32mp1/stm32mp1.c')
-rw-r--r--board/st/stm32mp1/stm32mp1.c190
1 files changed, 167 insertions, 23 deletions
diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 279c7b7797..fc14ad375c 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -5,8 +5,8 @@
#include <common.h>
#include <adc.h>
#include <bootm.h>
-#include <config.h>
#include <clk.h>
+#include <config.h>
#include <dm.h>
#include <env.h>
#include <env_internal.h>
@@ -18,9 +18,11 @@
#include <mtd.h>
#include <mtd_node.h>
#include <phy.h>
+#include <remoteproc.h>
#include <reset.h>
#include <syscon.h>
#include <usb.h>
+#include <watchdog.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/stm32.h>
@@ -102,7 +104,7 @@ int checkboard(void)
if (!ret)
ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
&otp, sizeof(otp));
- if (!ret && otp) {
+ if (ret > 0 && otp) {
printf("Board: MB%04x Var%d Rev.%c-%02d\n",
otp >> 16,
(otp >> 12) & 0xF,
@@ -232,6 +234,7 @@ int g_dnl_board_usb_cable_connected(void)
}
#endif /* CONFIG_USB_GADGET */
+#ifdef CONFIG_LED
static int get_led(struct udevice **dev, char *led_string)
{
char *led_name;
@@ -264,12 +267,42 @@ static int setup_led(enum led_state_t cmd)
ret = led_set_state(dev, cmd);
return ret;
}
+#endif
+
+static void __maybe_unused led_error_blink(u32 nb_blink)
+{
+#ifdef CONFIG_LED
+ int ret;
+ struct udevice *led;
+ u32 i;
+#endif
+
+ if (!nb_blink)
+ return;
+
+#ifdef CONFIG_LED
+ ret = get_led(&led, "u-boot,error-led");
+ if (!ret) {
+ /* make u-boot,error-led blinking */
+ /* if U32_MAX and 125ms interval, for 17.02 years */
+ for (i = 0; i < 2 * nb_blink; i++) {
+ led_set_state(led, LEDST_TOGGLE);
+ mdelay(125);
+ WATCHDOG_RESET();
+ }
+ }
+#endif
+
+ /* infinite: the boot process must be stopped */
+ if (nb_blink == U32_MAX)
+ hang();
+}
+#ifdef CONFIG_ADC
static int board_check_usb_power(void)
{
struct ofnode_phandle_args adc_args;
struct udevice *adc;
- struct udevice *led;
ofnode node;
unsigned int raw;
int max_uV = 0;
@@ -395,23 +428,11 @@ static int board_check_usb_power(void)
pr_err("****************************************************\n\n");
}
- ret = get_led(&led, "u-boot,error-led");
- if (ret) {
- /* in unattached case, the boot process must be stopped */
- if (nb_blink == U32_MAX)
- hang();
- return ret;
- }
-
- /* make u-boot,error-led blinking */
- for (i = 0; i < nb_blink * 2; i++) {
- led_set_state(led, LEDST_TOGGLE);
- mdelay(125);
- }
- led_set_state(led, LEDST_ON);
+ led_error_blink(nb_blink);
return 0;
}
+#endif /* CONFIG_ADC */
static void sysconf_init(void)
{
@@ -454,7 +475,9 @@ static void sysconf_init(void)
* => U-Boot set the register only if VDD < 2.7V (in DT)
* but this value need to be consistent with board design
*/
- ret = syscon_get_by_driver_data(STM32MP_SYSCON_PWR, &pwr_dev);
+ ret = uclass_get_device_by_driver(UCLASS_PMIC,
+ DM_GET_DRIVER(stm32mp_pwr_pmic),
+ &pwr_dev);
if (!ret) {
ret = uclass_get_device_by_driver(UCLASS_MISC,
DM_GET_DRIVER(stm32mp_bsec),
@@ -465,11 +488,11 @@ static void sysconf_init(void)
}
ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
- if (!ret)
+ if (ret > 0)
otp = otp & BIT(13);
- /* get VDD = pwr-supply */
- ret = device_get_supply_regulator(pwr_dev, "pwr-supply",
+ /* get VDD = vdd-supply */
+ ret = device_get_supply_regulator(pwr_dev, "vdd-supply",
&pwr_reg);
/* check if VDD is Low Voltage */
@@ -505,6 +528,73 @@ static void sysconf_init(void)
#endif
}
+#ifdef CONFIG_DM_REGULATOR
+/* Fix to make I2C1 usable on DK2 for touchscreen usage in kernel */
+static int dk2_i2c1_fix(void)
+{
+ ofnode node;
+ struct gpio_desc hdmi, audio;
+ int ret = 0;
+
+ node = ofnode_path("/soc/i2c@40012000/hdmi-transmitter@39");
+ if (!ofnode_valid(node)) {
+ pr_debug("%s: no hdmi-transmitter@39 ?\n", __func__);
+ return -ENOENT;
+ }
+
+ if (gpio_request_by_name_nodev(node, "reset-gpios", 0,
+ &hdmi, GPIOD_IS_OUT)) {
+ pr_debug("%s: could not find reset-gpios\n",
+ __func__);
+ return -ENOENT;
+ }
+
+ node = ofnode_path("/soc/i2c@40012000/cs42l51@4a");
+ if (!ofnode_valid(node)) {
+ pr_debug("%s: no cs42l51@4a ?\n", __func__);
+ return -ENOENT;
+ }
+
+ if (gpio_request_by_name_nodev(node, "reset-gpios", 0,
+ &audio, GPIOD_IS_OUT)) {
+ pr_debug("%s: could not find reset-gpios\n",
+ __func__);
+ return -ENOENT;
+ }
+
+ /* before power up, insure that HDMI and AUDIO IC is under reset */
+ ret = dm_gpio_set_value(&hdmi, 1);
+ if (ret) {
+ pr_err("%s: can't set_value for hdmi_nrst gpio", __func__);
+ goto error;
+ }
+ ret = dm_gpio_set_value(&audio, 1);
+ if (ret) {
+ pr_err("%s: can't set_value for audio_nrst gpio", __func__);
+ goto error;
+ }
+
+ /* power-up audio IC */
+ regulator_autoset_by_name("v1v8_audio", NULL);
+
+ /* power-up HDMI IC */
+ regulator_autoset_by_name("v1v2_hdmi", NULL);
+ regulator_autoset_by_name("v3v3_hdmi", NULL);
+
+error:
+ return ret;
+}
+
+static bool board_is_dk2(void)
+{
+ if (CONFIG_IS_ENABLED(TARGET_STM32MP157C_DK2) &&
+ of_machine_is_compatible("st,stm32mp157c-dk2"))
+ return true;
+
+ return false;
+}
+#endif
+
/* board dependent setup after realloc */
int board_init(void)
{
@@ -523,12 +613,15 @@ int board_init(void)
board_key_check();
#ifdef CONFIG_DM_REGULATOR
+ if (board_is_dk2())
+ dk2_i2c1_fix();
+
regulators_enable_boot_on(_DEBUG);
#endif
sysconf_init();
- if (IS_ENABLED(CONFIG_LED))
+ if (CONFIG_IS_ENABLED(CONFIG_LED))
led_default_state();
return 0;
@@ -536,9 +629,14 @@ int board_init(void)
int board_late_init(void)
{
+ char *boot_device;
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
const void *fdt_compat;
int fdt_compat_len;
+ int ret;
+ u32 otp;
+ struct udevice *dev;
+ char buf[10];
fdt_compat = fdt_getprop(gd->fdt_blob, 0, "compatible",
&fdt_compat_len);
@@ -548,21 +646,44 @@ int board_late_init(void)
else
env_set("board_name", fdt_compat + 3);
}
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_GET_DRIVER(stm32mp_bsec),
+ &dev);
+
+ if (!ret)
+ ret = misc_read(dev, STM32_BSEC_SHADOW(BSEC_OTP_BOARD),
+ &otp, sizeof(otp));
+ if (!ret && otp) {
+ snprintf(buf, sizeof(buf), "0x%04x", otp >> 16);
+ env_set("board_id", buf);
+
+ snprintf(buf, sizeof(buf), "0x%04x",
+ ((otp >> 8) & 0xF) - 1 + 0xA);
+ env_set("board_rev", buf);
+ }
#endif
+#ifdef CONFIG_ADC
/* for DK1/DK2 boards */
board_check_usb_power();
+#endif /* CONFIG_ADC */
+
+ /* Check the boot-source to disable bootdelay */
+ boot_device = env_get("boot_device");
+ if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb"))
+ env_set("bootdelay", "0");
return 0;
}
void board_quiesce_devices(void)
{
+#ifdef CONFIG_LED
setup_led(LEDST_OFF);
+#endif
}
/* board interface eth init */
-/* this is a weak define that we are overriding */
int board_interface_eth_init(phy_interface_t interface_type,
bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg)
{
@@ -771,3 +892,26 @@ int ft_board_setup(void *blob, bd_t *bd)
return 0;
}
#endif
+
+static void board_copro_image_process(ulong fw_image, size_t fw_size)
+{
+ int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */
+
+ if (!rproc_is_initialized())
+ if (rproc_init()) {
+ printf("Remote Processor %d initialization failed\n",
+ id);
+ return;
+ }
+
+ ret = rproc_load(id, fw_image, fw_size);
+ printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
+ id, fw_image, fw_size, ret ? " Failed!" : " Success!");
+
+ if (!ret) {
+ rproc_start(id);
+ env_set("copro_state", "booted");
+ }
+}
+
+U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);