uboot/board/Marvell/mvebu_armada-8k/board.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <i2c.h>
  10#include <asm/io.h>
  11#include <asm/arch/cpu.h>
  12#include <asm/arch/soc.h>
  13
  14DECLARE_GLOBAL_DATA_PTR;
  15
  16/*
  17 * Information specific to the DB-88F7040 eval board. We strive to use
  18 * DT for such platform specfic configurations. At some point, this
  19 * might be removed here and implemented via DT.
  20 */
  21/* IO expander I2C device */
  22#define I2C_IO_EXP_ADDR         0x21
  23#define I2C_IO_CFG_REG_0        0x6
  24#define I2C_IO_DATA_OUT_REG_0   0x2
  25/* VBus enable */
  26#define I2C_IO_REG_0_USB_H0_OFF 0
  27#define I2C_IO_REG_0_USB_H1_OFF 1
  28#define I2C_IO_REG_VBUS         ((1 << I2C_IO_REG_0_USB_H0_OFF) | \
  29                                 (1 << I2C_IO_REG_0_USB_H1_OFF))
  30/* Current limit */
  31#define I2C_IO_REG_0_USB_H0_CL  4
  32#define I2C_IO_REG_0_USB_H1_CL  5
  33#define I2C_IO_REG_CL           ((1 << I2C_IO_REG_0_USB_H0_CL) | \
  34                                 (1 << I2C_IO_REG_0_USB_H1_CL))
  35
  36static int usb_enabled = 0;
  37
  38/* Board specific xHCI dis-/enable code */
  39
  40/*
  41 * Set USB VBUS signals (via I2C IO expander/GPIO) as output and set
  42 * output value as disabled
  43 *
  44 * Set USB Current Limit signals (via I2C IO expander/GPIO) as output
  45 * and set output value as enabled
  46 */
  47int board_xhci_config(void)
  48{
  49        struct udevice *dev;
  50        int ret;
  51        u8 buf[8];
  52
  53        if (of_machine_is_compatible("marvell,armada7040-db")) {
  54                /* Configure IO exander PCA9555: 7bit address 0x21 */
  55                ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
  56                if (ret) {
  57                        printf("Cannot find PCA9555: %d\n", ret);
  58                        return 0;
  59                }
  60
  61                /*
  62                 * Read configuration (direction) and set VBUS pin as output
  63                 * (reset pin = output)
  64                 */
  65                ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
  66                if (ret) {
  67                        printf("Failed to read IO expander value via I2C\n");
  68                        return -EIO;
  69                }
  70                buf[0] &= ~I2C_IO_REG_VBUS;
  71                buf[0] &= ~I2C_IO_REG_CL;
  72                ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
  73                if (ret) {
  74                        printf("Failed to set IO expander via I2C\n");
  75                        return -EIO;
  76                }
  77
  78                /* Read output value and configure it */
  79                ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
  80                if (ret) {
  81                        printf("Failed to read IO expander value via I2C\n");
  82                        return -EIO;
  83                }
  84                buf[0] &= ~I2C_IO_REG_VBUS;
  85                buf[0] |= I2C_IO_REG_CL;
  86                ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
  87                if (ret) {
  88                        printf("Failed to set IO expander via I2C\n");
  89                        return -EIO;
  90                }
  91
  92                mdelay(500); /* required delay to let output value settle */
  93        }
  94
  95        return 0;
  96}
  97
  98int board_xhci_enable(void)
  99{
 100        struct udevice *dev;
 101        int ret;
 102        u8 buf[8];
 103
 104        if (of_machine_is_compatible("marvell,armada7040-db")) {
 105                /*
 106                 * This function enables all USB ports simultaniously,
 107                 * it only needs to get called once
 108                 */
 109                if (usb_enabled)
 110                        return 0;
 111
 112                /* Configure IO exander PCA9555: 7bit address 0x21 */
 113                ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
 114                if (ret) {
 115                        printf("Cannot find PCA9555: %d\n", ret);
 116                        return 0;
 117                }
 118
 119                /* Read VBUS output value */
 120                ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
 121                if (ret) {
 122                        printf("Failed to read IO expander value via I2C\n");
 123                        return -EIO;
 124                }
 125
 126                /* Enable VBUS power: Set output value of VBUS pin as enabled */
 127                buf[0] |= I2C_IO_REG_VBUS;
 128                ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
 129                if (ret) {
 130                        printf("Failed to set IO expander via I2C\n");
 131                        return -EIO;
 132                }
 133
 134                mdelay(500); /* required delay to let output value settle */
 135                usb_enabled = 1;
 136        }
 137
 138        return 0;
 139}
 140
 141int board_early_init_f(void)
 142{
 143        /* Nothing to do (yet), perhaps later some pin-muxing etc */
 144
 145        return 0;
 146}
 147
 148int board_init(void)
 149{
 150        /* adress of boot parameters */
 151        gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 152
 153        return 0;
 154}
 155
 156int board_late_init(void)
 157{
 158        /* Pre-configure the USB ports (overcurrent, VBus) */
 159        board_xhci_config();
 160
 161        return 0;
 162}
 163