mxs_gpio: correctly use the GPIO API
[karo-tx-uboot.git] / board / denx / m28evk / m28evk.c
1 /*
2  * DENX M28 module
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  * on behalf of DENX Software Engineering GmbH
6  *
7  * SPDX-License-Identifier:     GPL-2.0+
8  */
9
10 #include <common.h>
11 #include <asm/gpio.h>
12 #include <asm/io.h>
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/iomux-mx28.h>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/sys_proto.h>
17 #include <linux/mii.h>
18 #include <miiphy.h>
19 #include <netdev.h>
20 #include <errno.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23
24 /*
25  * Functions
26  */
27 int board_early_init_f(void)
28 {
29         /* IO0 clock at 480MHz */
30         mxs_set_ioclk(MXC_IOCLK0, 480000);
31         /* IO1 clock at 480MHz */
32         mxs_set_ioclk(MXC_IOCLK1, 480000);
33
34         /* SSP0 clock at 96MHz */
35         mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
36         /* SSP2 clock at 160MHz */
37         mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
38
39 #ifdef  CONFIG_CMD_USB
40         mxs_iomux_setup_pad(MX28_PAD_SSP2_SS1__USB1_OVERCURRENT);
41         mxs_iomux_setup_pad(MX28_PAD_AUART3_TX__GPIO_3_13 |
42                         MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
43         gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_TX__GPIO_3_13), 0);
44
45         mxs_iomux_setup_pad(MX28_PAD_AUART3_RX__GPIO_3_12 |
46                         MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
47         gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART3_RX__GPIO_3_12), 0);
48 #endif
49
50         return 0;
51 }
52
53 int board_init(void)
54 {
55         /* Adress of boot parameters */
56         gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
57
58         return 0;
59 }
60
61 int dram_init(void)
62 {
63         return mxs_dram_init();
64 }
65
66 #ifdef  CONFIG_CMD_MMC
67 static int m28_mmc_wp(int id)
68 {
69         if (id != 0) {
70                 printf("MXS MMC: Invalid card selected (card id = %d)\n", id);
71                 return 1;
72         }
73
74         return gpio_get_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
75 }
76
77 int board_mmc_init(bd_t *bis)
78 {
79         /* Configure WP as input. */
80         gpio_direction_input(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_CTS__GPIO_3_10));
81         /* Turn on the power to the card. */
82         gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_PWM3__GPIO_3_28), 0);
83
84         return mxsmmc_initialize(bis, 0, m28_mmc_wp, NULL);
85 }
86 #endif
87
88 #ifdef  CONFIG_CMD_NET
89
90 #define MII_OPMODE_STRAP_OVERRIDE       0x16
91 #define MII_PHY_CTRL1                   0x1e
92 #define MII_PHY_CTRL2                   0x1f
93
94 int fecmxc_mii_postcall(int phy)
95 {
96 #if     defined(CONFIG_DENX_M28_V11) || defined(CONFIG_DENX_M28_V10)
97         /* KZ8031 PHY on old boards. */
98         const uint32_t freq = 0x0080;
99 #else
100         /* KZ8021 PHY on new boards. */
101         const uint32_t freq = 0x0000;
102 #endif
103
104         miiphy_write("FEC1", phy, MII_BMCR, 0x9000);
105         miiphy_write("FEC1", phy, MII_OPMODE_STRAP_OVERRIDE, 0x0202);
106         if (phy == 3)
107                 miiphy_write("FEC1", 3, MII_PHY_CTRL2, 0x8100 | freq);
108         return 0;
109 }
110
111 int board_eth_init(bd_t *bis)
112 {
113         struct mxs_clkctrl_regs *clkctrl_regs =
114                 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
115         struct eth_device *dev;
116         int ret;
117
118         ret = cpu_eth_init(bis);
119         if (ret)
120                 return ret;
121
122         clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet,
123                 CLKCTRL_ENET_TIME_SEL_MASK | CLKCTRL_ENET_CLK_OUT_EN,
124                 CLKCTRL_ENET_TIME_SEL_RMII_CLK);
125
126 #if !defined(CONFIG_DENX_M28_V11) && !defined(CONFIG_DENX_M28_V10)
127         /* Reset the new PHY */
128         gpio_direction_output(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 0);
129         udelay(10000);
130         gpio_set_value(MXS_PAD_TO_GPIO(MX28_PAD_AUART2_RTS__GPIO_3_11), 1);
131         udelay(10000);
132 #endif
133
134         ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
135         if (ret) {
136                 printf("FEC MXS: Unable to init FEC0\n");
137                 return ret;
138         }
139
140         ret = fecmxc_initialize_multi(bis, 1, 3, MXS_ENET1_BASE);
141         if (ret) {
142                 printf("FEC MXS: Unable to init FEC1\n");
143                 return ret;
144         }
145
146         dev = eth_get_dev_by_name("FEC0");
147         if (!dev) {
148                 printf("FEC MXS: Unable to get FEC0 device entry\n");
149                 return -EINVAL;
150         }
151
152         ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
153         if (ret) {
154                 printf("FEC MXS: Unable to register FEC0 mii postcall\n");
155                 return ret;
156         }
157
158         dev = eth_get_dev_by_name("FEC1");
159         if (!dev) {
160                 printf("FEC MXS: Unable to get FEC1 device entry\n");
161                 return -EINVAL;
162         }
163
164         ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
165         if (ret) {
166                 printf("FEC MXS: Unable to register FEC1 mii postcall\n");
167                 return ret;
168         }
169
170         return ret;
171 }
172
173 #endif