]> git.karo-electronics.de Git - karo-tx-uboot.git/blob - board/Marvell/mvebu_db-88f3720/board.c
arm64: mvebu: Add Armada 3700 db-88f3720 development board support
[karo-tx-uboot.git] / board / Marvell / mvebu_db-88f3720 / board.c
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 <i2c.h>
9 #include <asm/io.h>
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
12
13 DECLARE_GLOBAL_DATA_PTR;
14
15 /* IO expander I2C device */
16 #define I2C_IO_EXP_ADDR         0x22
17 #define I2C_IO_CFG_REG_0        0x6
18 #define I2C_IO_DATA_OUT_REG_0   0x2
19 #define I2C_IO_REG_0_SATA_OFF   2
20 #define I2C_IO_REG_0_USB_H_OFF  1
21
22 int board_early_init_f(void)
23 {
24         /* Nothing to do (yet), perhaps later some pin-muxing etc */
25
26         return 0;
27 }
28
29 int board_init(void)
30 {
31         /* adress of boot parameters */
32         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
33
34         return 0;
35 }
36
37 /* Board specific AHCI / SATA enable code */
38 int board_ahci_enable(void)
39 {
40         struct udevice *dev;
41         int ret;
42         u8 buf[8];
43
44         /* Configure IO exander PCA9555: 7bit address 0x22 */
45         ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
46         if (ret) {
47                 printf("Cannot find PCA9555: %d\n", ret);
48                 return 0;
49         }
50
51         ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
52         if (ret) {
53                 printf("Failed to read IO expander value via I2C\n");
54                 return -EIO;
55         }
56
57         /*
58          * Enable SATA power via IO expander connected via I2C by setting
59          * the corresponding bit to output mode to enable power for SATA
60          */
61         buf[0] &= ~(1 << I2C_IO_REG_0_SATA_OFF);
62         ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
63         if (ret) {
64                 printf("Failed to set IO expander via I2C\n");
65                 return -EIO;
66         }
67
68         return 0;
69 }
70
71 /* Board specific xHCI enable code */
72 int board_xhci_enable(void)
73 {
74         struct udevice *dev;
75         int ret;
76         u8 buf[8];
77
78         /* Configure IO exander PCA9555: 7bit address 0x22 */
79         ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev);
80         if (ret) {
81                 printf("Cannot find PCA9555: %d\n", ret);
82                 return 0;
83         }
84
85         printf("Enable USB VBUS\n");
86
87         /*
88          * Read configuration (direction) and set VBUS pin as output
89          * (reset pin = output)
90          */
91         ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1);
92         if (ret) {
93                 printf("Failed to read IO expander value via I2C\n");
94                 return -EIO;
95         }
96         buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
97         ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1);
98         if (ret) {
99                 printf("Failed to set IO expander via I2C\n");
100                 return -EIO;
101         }
102
103         /* Read VBUS output value and disable it */
104         ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
105         if (ret) {
106                 printf("Failed to read IO expander value via I2C\n");
107                 return -EIO;
108         }
109         buf[0] &= ~(1 << I2C_IO_REG_0_USB_H_OFF);
110         ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
111         if (ret) {
112                 printf("Failed to set IO expander via I2C\n");
113                 return -EIO;
114         }
115
116         /*
117          * Required delay for configuration to settle - must wait for
118          * power on port is disabled in case VBUS signal was high,
119          * required 3 seconds delay to let VBUS signal fully settle down
120          */
121         mdelay(3000);
122
123         /* Enable VBUS power: Set output value of VBUS pin as enabled */
124         buf[0] |= (1 << I2C_IO_REG_0_USB_H_OFF);
125         ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1);
126         if (ret) {
127                 printf("Failed to set IO expander via I2C\n");
128                 return -EIO;
129         }
130
131         mdelay(500); /* required delay to let output value settle */
132
133         return 0;
134 }