uboot/board/dhelectronics/dh_stm32mp1/board.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#include <common.h>
   7#include <adc.h>
   8#include <log.h>
   9#include <net.h>
  10#include <asm/arch/stm32.h>
  11#include <asm/arch/sys_proto.h>
  12#include <asm/gpio.h>
  13#include <asm/io.h>
  14#include <bootm.h>
  15#include <clk.h>
  16#include <config.h>
  17#include <dm.h>
  18#include <dm/device.h>
  19#include <dm/uclass.h>
  20#include <env.h>
  21#include <env_internal.h>
  22#include <g_dnl.h>
  23#include <generic-phy.h>
  24#include <hang.h>
  25#include <i2c.h>
  26#include <i2c_eeprom.h>
  27#include <init.h>
  28#include <led.h>
  29#include <memalign.h>
  30#include <misc.h>
  31#include <mtd.h>
  32#include <mtd_node.h>
  33#include <netdev.h>
  34#include <phy.h>
  35#include <linux/bitops.h>
  36#include <linux/delay.h>
  37#include <power/regulator.h>
  38#include <remoteproc.h>
  39#include <reset.h>
  40#include <syscon.h>
  41#include <usb.h>
  42#include <usb/dwc2_udc.h>
  43#include <watchdog.h>
  44#include <dm/ofnode.h>
  45#include "../common/dh_common.h"
  46#include "../../st/common/stpmic1.h"
  47
  48/* SYSCFG registers */
  49#define SYSCFG_BOOTR            0x00
  50#define SYSCFG_PMCSETR          0x04
  51#define SYSCFG_IOCTRLSETR       0x18
  52#define SYSCFG_ICNR             0x1C
  53#define SYSCFG_CMPCR            0x20
  54#define SYSCFG_CMPENSETR        0x24
  55#define SYSCFG_PMCCLRR          0x44
  56
  57#define SYSCFG_BOOTR_BOOT_MASK          GENMASK(2, 0)
  58#define SYSCFG_BOOTR_BOOTPD_SHIFT       4
  59
  60#define SYSCFG_IOCTRLSETR_HSLVEN_TRACE          BIT(0)
  61#define SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI        BIT(1)
  62#define SYSCFG_IOCTRLSETR_HSLVEN_ETH            BIT(2)
  63#define SYSCFG_IOCTRLSETR_HSLVEN_SDMMC          BIT(3)
  64#define SYSCFG_IOCTRLSETR_HSLVEN_SPI            BIT(4)
  65
  66#define SYSCFG_CMPCR_SW_CTRL            BIT(1)
  67#define SYSCFG_CMPCR_READY              BIT(8)
  68
  69#define SYSCFG_CMPENSETR_MPU_EN         BIT(0)
  70
  71#define SYSCFG_PMCSETR_ETH_CLK_SEL      BIT(16)
  72#define SYSCFG_PMCSETR_ETH_REF_CLK_SEL  BIT(17)
  73
  74#define SYSCFG_PMCSETR_ETH_SELMII       BIT(20)
  75
  76#define SYSCFG_PMCSETR_ETH_SEL_MASK     GENMASK(23, 21)
  77#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII 0
  78#define SYSCFG_PMCSETR_ETH_SEL_RGMII    BIT(21)
  79#define SYSCFG_PMCSETR_ETH_SEL_RMII     BIT(23)
  80
  81#define KS_CCR          0x08
  82#define KS_CCR_EEPROM   BIT(9)
  83#define KS_BE0          BIT(12)
  84#define KS_BE1          BIT(13)
  85#define KS_CIDER        0xC0
  86#define CIDER_ID        0x8870
  87
  88static bool dh_stm32_mac_is_in_ks8851(void)
  89{
  90        ofnode node;
  91        u32 reg, cider, ccr;
  92
  93        node = ofnode_path("ethernet1");
  94        if (!ofnode_valid(node))
  95                return false;
  96
  97        if (ofnode_device_is_compatible(node, "micrel,ks8851-mll"))
  98                return false;
  99
 100        /*
 101         * KS8851 with EEPROM may use custom MAC from EEPROM, read
 102         * out the KS8851 CCR register to determine whether EEPROM
 103         * is present. If EEPROM is present, it must contain valid
 104         * MAC address.
 105         */
 106        reg = ofnode_get_addr(node);
 107        if (!reg)
 108                return false;
 109
 110        writew(KS_BE0 | KS_BE1 | KS_CIDER, reg + 2);
 111        cider = readw(reg);
 112        if ((cider & 0xfff0) != CIDER_ID)
 113                return true;
 114
 115        writew(KS_BE0 | KS_BE1 | KS_CCR, reg + 2);
 116        ccr = readw(reg);
 117        if (ccr & KS_CCR_EEPROM)
 118                return true;
 119
 120        return false;
 121}
 122
 123static int dh_stm32_setup_ethaddr(void)
 124{
 125        unsigned char enetaddr[6];
 126
 127        if (dh_mac_is_in_env("ethaddr"))
 128                return 0;
 129
 130        if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0"))
 131                return eth_env_set_enetaddr("ethaddr", enetaddr);
 132
 133        return -ENXIO;
 134}
 135
 136static int dh_stm32_setup_eth1addr(void)
 137{
 138        unsigned char enetaddr[6];
 139
 140        if (dh_mac_is_in_env("eth1addr"))
 141                return 0;
 142
 143        if (dh_stm32_mac_is_in_ks8851())
 144                return 0;
 145
 146        if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) {
 147                enetaddr[5]++;
 148                return eth_env_set_enetaddr("eth1addr", enetaddr);
 149        }
 150
 151        return -ENXIO;
 152}
 153
 154int setup_mac_address(void)
 155{
 156        if (dh_stm32_setup_ethaddr())
 157                log_err("%s: Unable to setup ethaddr!\n", __func__);
 158
 159        if (dh_stm32_setup_eth1addr())
 160                log_err("%s: Unable to setup eth1addr!\n", __func__);
 161
 162        return 0;
 163}
 164
 165int checkboard(void)
 166{
 167        char *mode;
 168        const char *fdt_compat;
 169        int fdt_compat_len;
 170
 171        if (IS_ENABLED(CONFIG_TFABOOT))
 172                mode = "trusted";
 173        else
 174                mode = "basic";
 175
 176        printf("Board: stm32mp1 in %s mode", mode);
 177        fdt_compat = ofnode_get_property(ofnode_root(), "compatible",
 178                                         &fdt_compat_len);
 179        if (fdt_compat && fdt_compat_len)
 180                printf(" (%s)", fdt_compat);
 181        puts("\n");
 182
 183        return 0;
 184}
 185
 186#ifdef CONFIG_BOARD_EARLY_INIT_F
 187static u8 brdcode __section("data");
 188static u8 ddr3code __section("data");
 189static u8 somcode __section("data");
 190static u32 opp_voltage_mv __section(".data");
 191
 192static void board_get_coding_straps(void)
 193{
 194        struct gpio_desc gpio[4];
 195        ofnode node;
 196        int i, ret;
 197
 198        brdcode = 0;
 199        ddr3code = 0;
 200        somcode = 0;
 201
 202        node = ofnode_path("/config");
 203        if (!ofnode_valid(node)) {
 204                printf("%s: no /config node?\n", __func__);
 205                return;
 206        }
 207
 208        ret = gpio_request_list_by_name_nodev(node, "dh,som-coding-gpios",
 209                                              gpio, ARRAY_SIZE(gpio),
 210                                              GPIOD_IS_IN);
 211        for (i = 0; i < ret; i++)
 212                somcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 213
 214        gpio_free_list_nodev(gpio, ret);
 215
 216        ret = gpio_request_list_by_name_nodev(node, "dh,ddr3-coding-gpios",
 217                                              gpio, ARRAY_SIZE(gpio),
 218                                              GPIOD_IS_IN);
 219        for (i = 0; i < ret; i++)
 220                ddr3code |= !!dm_gpio_get_value(&(gpio[i])) << i;
 221
 222        gpio_free_list_nodev(gpio, ret);
 223
 224        ret = gpio_request_list_by_name_nodev(node, "dh,board-coding-gpios",
 225                                              gpio, ARRAY_SIZE(gpio),
 226                                              GPIOD_IS_IN);
 227        for (i = 0; i < ret; i++)
 228                brdcode |= !!dm_gpio_get_value(&(gpio[i])) << i;
 229
 230        gpio_free_list_nodev(gpio, ret);
 231
 232        printf("Code:  SoM:rev=%d,ddr3=%d Board:rev=%d\n",
 233                somcode, ddr3code, brdcode);
 234}
 235
 236int board_stm32mp1_ddr_config_name_match(struct udevice *dev,
 237                                         const char *name)
 238{
 239        if (ddr3code == 1 &&
 240            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x1gb-533mhz"))
 241                return 0;
 242
 243        if (ddr3code == 2 &&
 244            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x2gb-533mhz"))
 245                return 0;
 246
 247        if (ddr3code == 3 &&
 248            !strcmp(name, "st,ddr3l-dhsom-1066-888-bin-g-2x4gb-533mhz"))
 249                return 0;
 250
 251        return -EINVAL;
 252}
 253
 254void board_vddcore_init(u32 voltage_mv)
 255{
 256        if (IS_ENABLED(CONFIG_SPL_BUILD))
 257                opp_voltage_mv = voltage_mv;
 258}
 259
 260int board_early_init_f(void)
 261{
 262        if (IS_ENABLED(CONFIG_SPL_BUILD))
 263                stpmic1_init(opp_voltage_mv);
 264        board_get_coding_straps();
 265
 266        return 0;
 267}
 268
 269#ifdef CONFIG_SPL_LOAD_FIT
 270int board_fit_config_name_match(const char *name)
 271{
 272        const char *compat;
 273        char test[128];
 274
 275        compat = ofnode_get_property(ofnode_root(), "compatible", NULL);
 276
 277        snprintf(test, sizeof(test), "%s_somrev%d_boardrev%d",
 278                compat, somcode, brdcode);
 279
 280        if (!strcmp(name, test))
 281                return 0;
 282
 283        return -EINVAL;
 284}
 285#endif
 286#endif
 287
 288static void board_key_check(void)
 289{
 290#if defined(CONFIG_FASTBOOT) || defined(CONFIG_CMD_STM32PROG)
 291        ofnode node;
 292        struct gpio_desc gpio;
 293        enum forced_boot_mode boot_mode = BOOT_NORMAL;
 294
 295        node = ofnode_path("/config");
 296        if (!ofnode_valid(node)) {
 297                debug("%s: no /config node?\n", __func__);
 298                return;
 299        }
 300#ifdef CONFIG_FASTBOOT
 301        if (gpio_request_by_name_nodev(node, "st,fastboot-gpios", 0,
 302                                       &gpio, GPIOD_IS_IN)) {
 303                debug("%s: could not find a /config/st,fastboot-gpios\n",
 304                      __func__);
 305        } else {
 306                if (dm_gpio_get_value(&gpio)) {
 307                        puts("Fastboot key pressed, ");
 308                        boot_mode = BOOT_FASTBOOT;
 309                }
 310
 311                dm_gpio_free(NULL, &gpio);
 312        }
 313#endif
 314#ifdef CONFIG_CMD_STM32PROG
 315        if (gpio_request_by_name_nodev(node, "st,stm32prog-gpios", 0,
 316                                       &gpio, GPIOD_IS_IN)) {
 317                debug("%s: could not find a /config/st,stm32prog-gpios\n",
 318                      __func__);
 319        } else {
 320                if (dm_gpio_get_value(&gpio)) {
 321                        puts("STM32Programmer key pressed, ");
 322                        boot_mode = BOOT_STM32PROG;
 323                }
 324                dm_gpio_free(NULL, &gpio);
 325        }
 326#endif
 327
 328        if (boot_mode != BOOT_NORMAL) {
 329                puts("entering download mode...\n");
 330                clrsetbits_le32(TAMP_BOOT_CONTEXT,
 331                                TAMP_BOOT_FORCED_MASK,
 332                                boot_mode);
 333        }
 334#endif
 335}
 336
 337#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
 338
 339#include <usb/dwc2_udc.h>
 340int g_dnl_board_usb_cable_connected(void)
 341{
 342        struct udevice *dwc2_udc_otg;
 343        int ret;
 344
 345        ret = uclass_get_device_by_driver(UCLASS_USB_GADGET_GENERIC,
 346                                          DM_DRIVER_GET(dwc2_udc_otg),
 347                                          &dwc2_udc_otg);
 348        if (!ret)
 349                debug("dwc2_udc_otg init failed\n");
 350
 351        return dwc2_udc_B_session_valid(dwc2_udc_otg);
 352}
 353
 354#define STM32MP1_G_DNL_DFU_PRODUCT_NUM 0xdf11
 355#define STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM 0x0afb
 356
 357int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
 358{
 359        if (!strcmp(name, "usb_dnl_dfu"))
 360                put_unaligned(STM32MP1_G_DNL_DFU_PRODUCT_NUM, &dev->idProduct);
 361        else if (!strcmp(name, "usb_dnl_fastboot"))
 362                put_unaligned(STM32MP1_G_DNL_FASTBOOT_PRODUCT_NUM,
 363                              &dev->idProduct);
 364        else
 365                put_unaligned(CONFIG_USB_GADGET_PRODUCT_NUM, &dev->idProduct);
 366
 367        return 0;
 368}
 369
 370#endif /* CONFIG_USB_GADGET */
 371
 372#ifdef CONFIG_LED
 373static int get_led(struct udevice **dev, char *led_string)
 374{
 375        const char *led_name;
 376        int ret;
 377
 378        led_name = ofnode_conf_read_str(led_string);
 379        if (!led_name) {
 380                pr_debug("%s: could not find %s config string\n",
 381                         __func__, led_string);
 382                return -ENOENT;
 383        }
 384        ret = led_get_by_label(led_name, dev);
 385        if (ret) {
 386                debug("%s: get=%d\n", __func__, ret);
 387                return ret;
 388        }
 389
 390        return 0;
 391}
 392
 393static int setup_led(enum led_state_t cmd)
 394{
 395        struct udevice *dev;
 396        int ret;
 397
 398        ret = get_led(&dev, "u-boot,boot-led");
 399        if (ret)
 400                return ret;
 401
 402        ret = led_set_state(dev, cmd);
 403        return ret;
 404}
 405#endif
 406
 407static void __maybe_unused led_error_blink(u32 nb_blink)
 408{
 409#ifdef CONFIG_LED
 410        int ret;
 411        struct udevice *led;
 412        u32 i;
 413#endif
 414
 415        if (!nb_blink)
 416                return;
 417
 418#ifdef CONFIG_LED
 419        ret = get_led(&led, "u-boot,error-led");
 420        if (!ret) {
 421                /* make u-boot,error-led blinking */
 422                /* if U32_MAX and 125ms interval, for 17.02 years */
 423                for (i = 0; i < 2 * nb_blink; i++) {
 424                        led_set_state(led, LEDST_TOGGLE);
 425                        mdelay(125);
 426                        schedule();
 427                }
 428        }
 429#endif
 430
 431        /* infinite: the boot process must be stopped */
 432        if (nb_blink == U32_MAX)
 433                hang();
 434}
 435
 436static void sysconf_init(void)
 437{
 438#ifndef CONFIG_TFABOOT
 439        u8 *syscfg;
 440#ifdef CONFIG_DM_REGULATOR
 441        struct udevice *pwr_dev;
 442        struct udevice *pwr_reg;
 443        struct udevice *dev;
 444        int ret;
 445        u32 otp = 0;
 446#endif
 447        u32 bootr;
 448
 449        syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
 450
 451        /* interconnect update : select master using the port 1 */
 452        /* LTDC = AXI_M9 */
 453        /* GPU  = AXI_M8 */
 454        /* today information is hardcoded in U-Boot */
 455        writel(BIT(9), syscfg + SYSCFG_ICNR);
 456
 457        /* disable Pull-Down for boot pin connected to VDD */
 458        bootr = readl(syscfg + SYSCFG_BOOTR);
 459        bootr &= ~(SYSCFG_BOOTR_BOOT_MASK << SYSCFG_BOOTR_BOOTPD_SHIFT);
 460        bootr |= (bootr & SYSCFG_BOOTR_BOOT_MASK) << SYSCFG_BOOTR_BOOTPD_SHIFT;
 461        writel(bootr, syscfg + SYSCFG_BOOTR);
 462
 463#ifdef CONFIG_DM_REGULATOR
 464        /* High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
 465         * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
 466         * The customer will have to disable this for low frequencies
 467         * or if AFMUX is selected but the function not used, typically for
 468         * TRACE. Otherwise, impact on power consumption.
 469         *
 470         * WARNING:
 471         *   enabling High Speed mode while VDD>2.7V
 472         *   with the OTP product_below_2v5 (OTP 18, BIT 13)
 473         *   erroneously set to 1 can damage the IC!
 474         *   => U-Boot set the register only if VDD < 2.7V (in DT)
 475         *      but this value need to be consistent with board design
 476         */
 477        ret = uclass_get_device_by_driver(UCLASS_PMIC,
 478                                          DM_DRIVER_GET(stm32mp_pwr_pmic),
 479                                          &pwr_dev);
 480        if (!ret) {
 481                ret = uclass_get_device_by_driver(UCLASS_MISC,
 482                                                  DM_DRIVER_GET(stm32mp_bsec),
 483                                                  &dev);
 484                if (ret) {
 485                        pr_err("Can't find stm32mp_bsec driver\n");
 486                        return;
 487                }
 488
 489                ret = misc_read(dev, STM32_BSEC_SHADOW(18), &otp, 4);
 490                if (ret > 0)
 491                        otp = otp & BIT(13);
 492
 493                /* get VDD = vdd-supply */
 494                ret = device_get_supply_regulator(pwr_dev, "vdd-supply",
 495                                                  &pwr_reg);
 496
 497                /* check if VDD is Low Voltage */
 498                if (!ret) {
 499                        if (regulator_get_value(pwr_reg) < 2700000) {
 500                                writel(SYSCFG_IOCTRLSETR_HSLVEN_TRACE |
 501                                       SYSCFG_IOCTRLSETR_HSLVEN_QUADSPI |
 502                                       SYSCFG_IOCTRLSETR_HSLVEN_ETH |
 503                                       SYSCFG_IOCTRLSETR_HSLVEN_SDMMC |
 504                                       SYSCFG_IOCTRLSETR_HSLVEN_SPI,
 505                                       syscfg + SYSCFG_IOCTRLSETR);
 506
 507                                if (!otp)
 508                                        pr_err("product_below_2v5=0: HSLVEN protected by HW\n");
 509                        } else {
 510                                if (otp)
 511                                        pr_err("product_below_2v5=1: HSLVEN update is destructive, no update as VDD>2.7V\n");
 512                        }
 513                } else {
 514                        debug("VDD unknown");
 515                }
 516        }
 517#endif
 518
 519        /* activate automatic I/O compensation
 520         * warning: need to ensure CSI enabled and ready in clock driver
 521         */
 522        writel(SYSCFG_CMPENSETR_MPU_EN, syscfg + SYSCFG_CMPENSETR);
 523
 524        while (!(readl(syscfg + SYSCFG_CMPCR) & SYSCFG_CMPCR_READY))
 525                ;
 526        clrbits_le32(syscfg + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
 527#endif
 528}
 529
 530#ifdef CONFIG_DM_REGULATOR
 531#define STPMIC_NVM_BUCKS_VOUT_SHR                       0xfc
 532#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V2              0
 533#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V8              1
 534#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V0              2
 535#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3              3
 536#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_MASK             GENMASK(1, 0)
 537#define STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_OFFSET(n)        ((((n) - 1) & 3) * 2)
 538static int board_get_regulator_buck3_nvm_uv_av96(int *uv)
 539{
 540        struct udevice *dev;
 541        u8 bucks_vout = 0;
 542        const char *prop;
 543        int len, ret;
 544
 545        /* Check whether this is Avenger96 board. */
 546        prop = ofnode_get_property(ofnode_root(), "compatible", &len);
 547        if (!prop || !len)
 548                return -ENODEV;
 549
 550        if (!strstr(prop, "avenger96") && !strstr(prop, "dhcor-testbench"))
 551                return -EINVAL;
 552
 553        /* Read out STPMIC1 NVM and determine default Buck3 voltage. */
 554        ret = uclass_get_device_by_driver(UCLASS_MISC,
 555                                          DM_DRIVER_GET(stpmic1_nvm),
 556                                          &dev);
 557        if (ret)
 558                return ret;
 559
 560        ret = misc_read(dev, STPMIC_NVM_BUCKS_VOUT_SHR, &bucks_vout, 1);
 561        if (ret != 1)
 562                return -EINVAL;
 563
 564        bucks_vout >>= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_OFFSET(3);
 565        bucks_vout &= STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_MASK;
 566
 567        if (strstr(prop, "avenger96")) {
 568                /*
 569                 * Avenger96 board comes in multiple regulator configurations:
 570                 * - rev.100 or rev.200 have Buck3 preconfigured to
 571                 *   3V3 operation on boot and contains extra Enpirion
 572                 *   EP53A8LQI DCDC converter which supplies the IO.
 573                 *   Reduce Buck3 voltage to 2V9 to not waste power.
 574                 * - rev.200L have Buck3 preconfigured to 1V8 operation
 575                 *   and have no Enpirion EP53A8LQI DCDC anymore, the
 576                 *   IO is supplied from Buck3.
 577                 */
 578                if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
 579                        *uv = 2900000;
 580                else
 581                        *uv = 1800000;
 582        } else {
 583                /* Testbench always respects Buck3 NVM settings */
 584                if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V3)
 585                        *uv = 3300000;
 586                else if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_3V0)
 587                        *uv = 3000000;
 588                else if (bucks_vout == STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V8)
 589                        *uv = 1800000;
 590                else    /* STPMIC_NVM_BUCKS_VOUT_SHR_BUCK_1V2 */
 591                        *uv = 1200000;
 592        }
 593
 594        return 0;
 595}
 596
 597static void board_init_regulator_av96(void)
 598{
 599        struct udevice *rdev;
 600        int ret, uv;
 601
 602        ret = board_get_regulator_buck3_nvm_uv_av96(&uv);
 603        if (ret)        /* Not Avenger96 board. */
 604                return;
 605
 606        ret = regulator_get_by_devname("buck3", &rdev);
 607        if (ret)
 608                return;
 609
 610        /* Adjust Buck3 per preconfigured PMIC voltage from NVM. */
 611        regulator_set_value(rdev, uv);
 612        regulator_set_enable(rdev, true);
 613}
 614
 615static void board_init_regulator(void)
 616{
 617        board_init_regulator_av96();
 618
 619        regulators_enable_boot_on(_DEBUG);
 620}
 621#else
 622static inline int board_get_regulator_buck3_nvm_uv_av96(int *uv)
 623{
 624        return -EINVAL;
 625}
 626
 627static inline void board_init_regulator(void) {}
 628#endif
 629
 630/* board dependent setup after realloc */
 631int board_init(void)
 632{
 633        board_key_check();
 634
 635        board_init_regulator();
 636
 637        sysconf_init();
 638
 639        return 0;
 640}
 641
 642int board_late_init(void)
 643{
 644        char *boot_device;
 645#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
 646        const void *fdt_compat;
 647        int fdt_compat_len;
 648
 649        fdt_compat = ofnode_get_property(ofnode_root(), "compatible",
 650                                         &fdt_compat_len);
 651        if (fdt_compat && fdt_compat_len) {
 652                if (strncmp(fdt_compat, "st,", 3) != 0)
 653                        env_set("board_name", fdt_compat);
 654                else
 655                        env_set("board_name", fdt_compat + 3);
 656        }
 657#endif
 658
 659        /* Check the boot-source to disable bootdelay */
 660        boot_device = env_get("boot_device");
 661        if (!strcmp(boot_device, "serial") || !strcmp(boot_device, "usb"))
 662                env_set("bootdelay", "0");
 663
 664#ifdef CONFIG_BOARD_EARLY_INIT_F
 665        env_set_ulong("dh_som_rev", somcode);
 666        env_set_ulong("dh_board_rev", brdcode);
 667        env_set_ulong("dh_ddr3_code", ddr3code);
 668#endif
 669
 670        return 0;
 671}
 672
 673void board_quiesce_devices(void)
 674{
 675#ifdef CONFIG_LED
 676        setup_led(LEDST_OFF);
 677#endif
 678}
 679
 680/* eth init function : weak called in eqos driver */
 681int board_interface_eth_init(struct udevice *dev,
 682                             phy_interface_t interface_type)
 683{
 684        u8 *syscfg;
 685        u32 value;
 686        bool eth_clk_sel_reg = false;
 687        bool eth_ref_clk_sel_reg = false;
 688
 689        /* Gigabit Ethernet 125MHz clock selection. */
 690        eth_clk_sel_reg = dev_read_bool(dev, "st,eth-clk-sel");
 691
 692        /* Ethernet 50Mhz RMII clock selection */
 693        eth_ref_clk_sel_reg =
 694                dev_read_bool(dev, "st,eth-ref-clk-sel");
 695
 696        syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
 697
 698        if (!syscfg)
 699                return -ENODEV;
 700
 701        switch (interface_type) {
 702        case PHY_INTERFACE_MODE_MII:
 703                value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
 704                        SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
 705                debug("%s: PHY_INTERFACE_MODE_MII\n", __func__);
 706                break;
 707        case PHY_INTERFACE_MODE_GMII:
 708                if (eth_clk_sel_reg)
 709                        value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
 710                                SYSCFG_PMCSETR_ETH_CLK_SEL;
 711                else
 712                        value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
 713                debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__);
 714                break;
 715        case PHY_INTERFACE_MODE_RMII:
 716                if (eth_ref_clk_sel_reg)
 717                        value = SYSCFG_PMCSETR_ETH_SEL_RMII |
 718                                SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
 719                else
 720                        value = SYSCFG_PMCSETR_ETH_SEL_RMII;
 721                debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__);
 722                break;
 723        case PHY_INTERFACE_MODE_RGMII:
 724        case PHY_INTERFACE_MODE_RGMII_ID:
 725        case PHY_INTERFACE_MODE_RGMII_RXID:
 726        case PHY_INTERFACE_MODE_RGMII_TXID:
 727                if (eth_clk_sel_reg)
 728                        value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
 729                                SYSCFG_PMCSETR_ETH_CLK_SEL;
 730                else
 731                        value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
 732                debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__);
 733                break;
 734        default:
 735                debug("%s: Do not manage %d interface\n",
 736                      __func__, interface_type);
 737                /* Do not manage others interfaces */
 738                return -EINVAL;
 739        }
 740
 741        /* clear and set ETH configuration bits */
 742        writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
 743               SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
 744               syscfg + SYSCFG_PMCCLRR);
 745        writel(value, syscfg + SYSCFG_PMCSETR);
 746
 747        return 0;
 748}
 749
 750#if defined(CONFIG_OF_BOARD_SETUP)
 751int ft_board_setup(void *blob, struct bd_info *bd)
 752{
 753        const char *buck3path = "/soc/i2c@5c002000/stpmic@33/regulators/buck3";
 754        int buck3off, ret, uv;
 755
 756        ret = board_get_regulator_buck3_nvm_uv_av96(&uv);
 757        if (ret)        /* Not Avenger96 board, do not patch Buck3 in DT. */
 758                return 0;
 759
 760        buck3off = fdt_path_offset(blob, buck3path);
 761        if (buck3off < 0)       /* No Buck3 regulator found. */
 762                return 0;
 763
 764        ret = fdt_setprop_u32(blob, buck3off, "regulator-min-microvolt", uv);
 765        if (ret < 0)
 766                return ret;
 767
 768        ret = fdt_setprop_u32(blob, buck3off, "regulator-max-microvolt", uv);
 769        if (ret < 0)
 770                return ret;
 771
 772        return 0;
 773}
 774#endif
 775
 776static void board_copro_image_process(ulong fw_image, size_t fw_size)
 777{
 778        int ret, id = 0; /* Copro id fixed to 0 as only one coproc on mp1 */
 779
 780        if (!rproc_is_initialized())
 781                if (rproc_init()) {
 782                        printf("Remote Processor %d initialization failed\n",
 783                               id);
 784                        return;
 785                }
 786
 787        ret = rproc_load(id, fw_image, fw_size);
 788        printf("Load Remote Processor %d with data@addr=0x%08lx %u bytes:%s\n",
 789               id, fw_image, fw_size, ret ? " Failed!" : " Success!");
 790
 791        if (!ret) {
 792                rproc_start(id);
 793                env_set("copro_state", "booted");
 794        }
 795}
 796
 797U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_COPRO, board_copro_image_process);
 798