blob: b85fd806cba8fef6e65c29953a3c1ce69e8b1ef8 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Eric Nelsone5b3a502013-03-11 08:44:53 +00002/*
3 * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
4 * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
Eric Nelsone5b3a502013-03-11 08:44:53 +00005 */
6
Simon Glassed38aef2020-05-10 11:40:03 -06007#include <command.h>
Simon Glass313112a2019-08-01 09:46:46 -06008#include <env.h>
Simon Glass97589732020-05-10 11:40:02 -06009#include <init.h>
Simon Glass274e0b02020-05-10 11:39:56 -060010#include <net.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060011#include <asm/global_data.h>
Eric Nelsone5b3a502013-03-11 08:44:53 +000012#include <asm/io.h>
13#include <asm/arch/clock.h>
14#include <asm/arch/imx-regs.h>
15#include <asm/arch/iomux.h>
16#include <asm/arch/sys_proto.h>
17#include <malloc.h>
18#include <asm/arch/mx6-pins.h>
Simon Glassdbd79542020-05-10 11:40:11 -060019#include <linux/delay.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090020#include <linux/errno.h>
Eric Nelsone5b3a502013-03-11 08:44:53 +000021#include <asm/gpio.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020022#include <asm/mach-imx/iomux-v3.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020023#include <asm/mach-imx/sata.h>
24#include <asm/mach-imx/spi.h>
25#include <asm/mach-imx/boot_mode.h>
26#include <asm/mach-imx/video.h>
Yangbo Lu73340382019-06-21 11:42:28 +080027#include <fsl_esdhc_imx.h>
Eric Nelsone5b3a502013-03-11 08:44:53 +000028#include <micrel.h>
29#include <miiphy.h>
30#include <netdev.h>
Eric Nelsone5b3a502013-03-11 08:44:53 +000031#include <asm/arch/crm_regs.h>
32#include <asm/arch/mxc_hdmi.h>
33#include <i2c.h>
Eric Nelson068e9712014-10-02 12:16:27 -070034#include <input.h>
35#include <netdev.h>
Mateusz Kulikowski3add69e2016-03-31 23:12:23 +020036#include <usb/ehci-ci.h>
Eric Nelsone5b3a502013-03-11 08:44:53 +000037
38DECLARE_GLOBAL_DATA_PTR;
Troy Kisky645ccc52013-09-25 18:41:17 -070039#define GP_USB_OTG_PWR IMX_GPIO_NR(3, 22)
Eric Nelsone5b3a502013-03-11 08:44:53 +000040
Benoît Thébaudeau21670242013-04-26 01:34:47 +000041#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
42 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
43 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Eric Nelsone5b3a502013-03-11 08:44:53 +000044
Benoît Thébaudeau21670242013-04-26 01:34:47 +000045#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
46 PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
47 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
Eric Nelsone5b3a502013-03-11 08:44:53 +000048
Benoît Thébaudeau21670242013-04-26 01:34:47 +000049#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
50 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
Eric Nelsone5b3a502013-03-11 08:44:53 +000051
Benoît Thébaudeau21670242013-04-26 01:34:47 +000052#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
Eric Nelsone5b3a502013-03-11 08:44:53 +000053 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
54
Benoît Thébaudeau21670242013-04-26 01:34:47 +000055#define BUTTON_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
56 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
Eric Nelsone5b3a502013-03-11 08:44:53 +000057
Troy Kisky281f4e32019-11-03 18:20:04 -080058#define RGB_PAD_CTRL PAD_CTL_DSE_120ohm
59
Benoît Thébaudeau21670242013-04-26 01:34:47 +000060#define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \
61 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
Eric Nelsone5b3a502013-03-11 08:44:53 +000062 PAD_CTL_SRE_SLOW)
63
Benoît Thébaudeau21670242013-04-26 01:34:47 +000064#define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \
65 PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
66 PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
Eric Nelsone5b3a502013-03-11 08:44:53 +000067
68#define OUTPUT_40OHM (PAD_CTL_SPEED_MED|PAD_CTL_DSE_40ohm)
69
Troy Kisky281f4e32019-11-03 18:20:04 -080070#if defined(CONFIG_MX6QDL)
Troy Kisky281f4e32019-11-03 18:20:04 -080071#define IOMUX_PAD_CTRL(name, pad_ctrl) \
72 NEW_PAD_CTRL(MX6Q_PAD_##name, pad_ctrl), \
73 NEW_PAD_CTRL(MX6DL_PAD_##name, pad_ctrl)
74#else
Troy Kisky281f4e32019-11-03 18:20:04 -080075#define IOMUX_PAD_CTRL(name, pad_ctrl) NEW_PAD_CTRL(MX6_PAD_##name, pad_ctrl)
76#endif
77
Eric Nelsone5b3a502013-03-11 08:44:53 +000078int dram_init(void)
79{
fabio.estevam@freescale.com3ca6d0a2013-03-14 02:32:55 +000080 gd->ram_size = ((ulong)CONFIG_DDR_MB * 1024 * 1024);
Eric Nelsone5b3a502013-03-11 08:44:53 +000081
82 return 0;
83}
84
Eric Nelson068e9712014-10-02 12:16:27 -070085static iomux_v3_cfg_t const uart1_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -080086 IOMUX_PAD_CTRL(SD3_DAT6__UART1_RX_DATA, UART_PAD_CTRL),
87 IOMUX_PAD_CTRL(SD3_DAT7__UART1_TX_DATA, UART_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +000088};
89
Eric Nelson068e9712014-10-02 12:16:27 -070090static iomux_v3_cfg_t const uart2_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -080091 IOMUX_PAD_CTRL(EIM_D26__UART2_TX_DATA, UART_PAD_CTRL),
92 IOMUX_PAD_CTRL(EIM_D27__UART2_RX_DATA, UART_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +000093};
94
Eric Nelsone0bd0982014-10-02 12:16:24 -070095static iomux_v3_cfg_t const usdhc2_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -080096 IOMUX_PAD_CTRL(SD2_CLK__SD2_CLK, USDHC_PAD_CTRL),
97 IOMUX_PAD_CTRL(SD2_CMD__SD2_CMD, USDHC_PAD_CTRL),
98 IOMUX_PAD_CTRL(SD2_DAT0__SD2_DATA0, USDHC_PAD_CTRL),
99 IOMUX_PAD_CTRL(SD2_DAT1__SD2_DATA1, USDHC_PAD_CTRL),
100 IOMUX_PAD_CTRL(SD2_DAT2__SD2_DATA2, USDHC_PAD_CTRL),
101 IOMUX_PAD_CTRL(SD2_DAT3__SD2_DATA3, USDHC_PAD_CTRL),
Eric Nelsone0bd0982014-10-02 12:16:24 -0700102};
103
Eric Nelson068e9712014-10-02 12:16:27 -0700104static iomux_v3_cfg_t const enet_pads1[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800105 IOMUX_PAD_CTRL(ENET_MDIO__ENET_MDIO, ENET_PAD_CTRL),
106 IOMUX_PAD_CTRL(ENET_MDC__ENET_MDC, ENET_PAD_CTRL),
107 IOMUX_PAD_CTRL(RGMII_TXC__RGMII_TXC, ENET_PAD_CTRL),
108 IOMUX_PAD_CTRL(RGMII_TD0__RGMII_TD0, ENET_PAD_CTRL),
109 IOMUX_PAD_CTRL(RGMII_TD1__RGMII_TD1, ENET_PAD_CTRL),
110 IOMUX_PAD_CTRL(RGMII_TD2__RGMII_TD2, ENET_PAD_CTRL),
111 IOMUX_PAD_CTRL(RGMII_TD3__RGMII_TD3, ENET_PAD_CTRL),
112 IOMUX_PAD_CTRL(RGMII_TX_CTL__RGMII_TX_CTL, ENET_PAD_CTRL),
113 IOMUX_PAD_CTRL(ENET_REF_CLK__ENET_TX_CLK, ENET_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000114 /* pin 35 - 1 (PHY_AD2) on reset */
Troy Kisky281f4e32019-11-03 18:20:04 -0800115 IOMUX_PAD_CTRL(RGMII_RXC__GPIO6_IO30, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000116 /* pin 32 - 1 - (MODE0) all */
Troy Kisky281f4e32019-11-03 18:20:04 -0800117 IOMUX_PAD_CTRL(RGMII_RD0__GPIO6_IO25, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000118 /* pin 31 - 1 - (MODE1) all */
Troy Kisky281f4e32019-11-03 18:20:04 -0800119 IOMUX_PAD_CTRL(RGMII_RD1__GPIO6_IO27, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000120 /* pin 28 - 1 - (MODE2) all */
Troy Kisky281f4e32019-11-03 18:20:04 -0800121 IOMUX_PAD_CTRL(RGMII_RD2__GPIO6_IO28, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000122 /* pin 27 - 1 - (MODE3) all */
Troy Kisky281f4e32019-11-03 18:20:04 -0800123 IOMUX_PAD_CTRL(RGMII_RD3__GPIO6_IO29, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000124 /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
Troy Kisky281f4e32019-11-03 18:20:04 -0800125 IOMUX_PAD_CTRL(RGMII_RX_CTL__GPIO6_IO24, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000126 /* pin 42 PHY nRST */
Troy Kisky281f4e32019-11-03 18:20:04 -0800127 IOMUX_PAD_CTRL(EIM_D23__GPIO3_IO23, NO_PAD_CTRL),
128 IOMUX_PAD_CTRL(ENET_RXD0__GPIO1_IO27, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000129};
130
Eric Nelson068e9712014-10-02 12:16:27 -0700131static iomux_v3_cfg_t const enet_pads2[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800132 IOMUX_PAD_CTRL(RGMII_RXC__RGMII_RXC, ENET_PAD_CTRL),
133 IOMUX_PAD_CTRL(RGMII_RD0__RGMII_RD0, ENET_PAD_CTRL),
134 IOMUX_PAD_CTRL(RGMII_RD1__RGMII_RD1, ENET_PAD_CTRL),
135 IOMUX_PAD_CTRL(RGMII_RD2__RGMII_RD2, ENET_PAD_CTRL),
136 IOMUX_PAD_CTRL(RGMII_RD3__RGMII_RD3, ENET_PAD_CTRL),
137 IOMUX_PAD_CTRL(RGMII_RX_CTL__RGMII_RX_CTL, ENET_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000138};
139
Troy Kisky645ccc52013-09-25 18:41:17 -0700140static iomux_v3_cfg_t const misc_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800141 IOMUX_PAD_CTRL(GPIO_1__USB_OTG_ID, WEAK_PULLUP),
142 IOMUX_PAD_CTRL(KEY_COL4__USB_OTG_OC, WEAK_PULLUP),
143 IOMUX_PAD_CTRL(EIM_D30__USB_H1_OC, WEAK_PULLUP),
Troy Kisky645ccc52013-09-25 18:41:17 -0700144 /* OTG Power enable */
Troy Kisky281f4e32019-11-03 18:20:04 -0800145 IOMUX_PAD_CTRL(EIM_D22__GPIO3_IO22, OUTPUT_40OHM),
Troy Kisky645ccc52013-09-25 18:41:17 -0700146};
147
Eric Nelsone5b3a502013-03-11 08:44:53 +0000148/* wl1271 pads on nitrogen6x */
Eric Nelson068e9712014-10-02 12:16:27 -0700149static iomux_v3_cfg_t const wl12xx_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800150 IOMUX_PAD_CTRL(NANDF_CS1__GPIO6_IO14, WEAK_PULLDOWN),
151 IOMUX_PAD_CTRL(NANDF_CS2__GPIO6_IO15, OUTPUT_40OHM),
152 IOMUX_PAD_CTRL(NANDF_CS3__GPIO6_IO16, OUTPUT_40OHM),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000153};
154#define WL12XX_WL_IRQ_GP IMX_GPIO_NR(6, 14)
155#define WL12XX_WL_ENABLE_GP IMX_GPIO_NR(6, 15)
156#define WL12XX_BT_ENABLE_GP IMX_GPIO_NR(6, 16)
157
158/* Button assignments for J14 */
159static iomux_v3_cfg_t const button_pads[] = {
160 /* Menu */
Troy Kisky281f4e32019-11-03 18:20:04 -0800161 IOMUX_PAD_CTRL(NANDF_D1__GPIO2_IO01, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000162 /* Back */
Troy Kisky281f4e32019-11-03 18:20:04 -0800163 IOMUX_PAD_CTRL(NANDF_D2__GPIO2_IO02, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000164 /* Labelled Search (mapped to Power under Android) */
Troy Kisky281f4e32019-11-03 18:20:04 -0800165 IOMUX_PAD_CTRL(NANDF_D3__GPIO2_IO03, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000166 /* Home */
Troy Kisky281f4e32019-11-03 18:20:04 -0800167 IOMUX_PAD_CTRL(NANDF_D4__GPIO2_IO04, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000168 /* Volume Down */
Troy Kisky281f4e32019-11-03 18:20:04 -0800169 IOMUX_PAD_CTRL(GPIO_19__GPIO4_IO05, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000170 /* Volume Up */
Troy Kisky281f4e32019-11-03 18:20:04 -0800171 IOMUX_PAD_CTRL(GPIO_18__GPIO7_IO13, BUTTON_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000172};
173
174static void setup_iomux_enet(void)
175{
176 gpio_direction_output(IMX_GPIO_NR(3, 23), 0); /* SABRE Lite PHY rst */
177 gpio_direction_output(IMX_GPIO_NR(1, 27), 0); /* Nitrogen6X PHY rst */
178 gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
179 gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
180 gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
181 gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
182 gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
Troy Kisky281f4e32019-11-03 18:20:04 -0800183 SETUP_IOMUX_PADS(enet_pads1);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000184 gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
185
186 /* Need delay 10ms according to KSZ9021 spec */
187 udelay(1000 * 10);
188 gpio_set_value(IMX_GPIO_NR(3, 23), 1); /* SABRE Lite PHY reset */
189 gpio_set_value(IMX_GPIO_NR(1, 27), 1); /* Nitrogen6X PHY reset */
190
Troy Kisky281f4e32019-11-03 18:20:04 -0800191 SETUP_IOMUX_PADS(enet_pads2);
Troy Kiskyd24ee322014-10-02 12:16:29 -0700192 udelay(100); /* Wait 100 us before using mii interface */
Eric Nelsone5b3a502013-03-11 08:44:53 +0000193}
194
Eric Nelson068e9712014-10-02 12:16:27 -0700195static iomux_v3_cfg_t const usb_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800196 IOMUX_PAD_CTRL(GPIO_17__GPIO7_IO12, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000197};
198
199static void setup_iomux_uart(void)
200{
Troy Kisky281f4e32019-11-03 18:20:04 -0800201 SETUP_IOMUX_PADS(uart1_pads);
202 SETUP_IOMUX_PADS(uart2_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000203}
204
205#ifdef CONFIG_USB_EHCI_MX6
206int board_ehci_hcd_init(int port)
207{
Troy Kisky281f4e32019-11-03 18:20:04 -0800208 SETUP_IOMUX_PADS(usb_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000209
210 /* Reset USB hub */
211 gpio_direction_output(IMX_GPIO_NR(7, 12), 0);
212 mdelay(2);
213 gpio_set_value(IMX_GPIO_NR(7, 12), 1);
214
215 return 0;
216}
Troy Kisky645ccc52013-09-25 18:41:17 -0700217
218int board_ehci_power(int port, int on)
219{
220 if (port)
221 return 0;
222 gpio_set_value(GP_USB_OTG_PWR, on);
223 return 0;
224}
225
Eric Nelsone5b3a502013-03-11 08:44:53 +0000226#endif
227
Eric Nelsone5b3a502013-03-11 08:44:53 +0000228#ifdef CONFIG_MXC_SPI
Nikita Kiryanov00cd7382014-08-20 15:08:50 +0300229int board_spi_cs_gpio(unsigned bus, unsigned cs)
230{
231 return (bus == 0 && cs == 0) ? (IMX_GPIO_NR(3, 19)) : -1;
232}
233
Eric Nelson068e9712014-10-02 12:16:27 -0700234static iomux_v3_cfg_t const ecspi1_pads[] = {
Eric Nelsone5b3a502013-03-11 08:44:53 +0000235 /* SS1 */
Troy Kisky281f4e32019-11-03 18:20:04 -0800236 IOMUX_PAD_CTRL(EIM_D19__GPIO3_IO19, NO_PAD_CTRL),
237 IOMUX_PAD_CTRL(EIM_D17__ECSPI1_MISO, SPI_PAD_CTRL),
238 IOMUX_PAD_CTRL(EIM_D18__ECSPI1_MOSI, SPI_PAD_CTRL),
239 IOMUX_PAD_CTRL(EIM_D16__ECSPI1_SCLK, SPI_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000240};
241
Eric Nelson068e9712014-10-02 12:16:27 -0700242static void setup_spi(void)
Eric Nelsone5b3a502013-03-11 08:44:53 +0000243{
Troy Kisky281f4e32019-11-03 18:20:04 -0800244 SETUP_IOMUX_PADS(ecspi1_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000245}
246#endif
247
248int board_phy_config(struct phy_device *phydev)
249{
250 /* min rx data delay */
251 ksz9021_phy_extended_write(phydev,
252 MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
253 /* min tx data delay */
254 ksz9021_phy_extended_write(phydev,
255 MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
256 /* max rx/tx clock delay, min rx/tx control */
257 ksz9021_phy_extended_write(phydev,
258 MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
259 if (phydev->drv->config)
260 phydev->drv->config(phydev);
261
262 return 0;
263}
264
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900265int board_eth_init(struct bd_info *bis)
Eric Nelsone5b3a502013-03-11 08:44:53 +0000266{
267 uint32_t base = IMX_FEC_BASE;
268 struct mii_dev *bus = NULL;
269 struct phy_device *phydev = NULL;
270 int ret;
271
Troy Kisky3d5b2562019-07-29 12:15:56 -0700272 gpio_request(WL12XX_WL_IRQ_GP, "wifi_irq");
273 gpio_request(IMX_GPIO_NR(6, 30), "rgmii_rxc");
274 gpio_request(IMX_GPIO_NR(6, 25), "rgmii_rd0");
275 gpio_request(IMX_GPIO_NR(6, 27), "rgmii_rd1");
276 gpio_request(IMX_GPIO_NR(6, 28), "rgmii_rd2");
277 gpio_request(IMX_GPIO_NR(6, 29), "rgmii_rd3");
278 gpio_request(IMX_GPIO_NR(6, 24), "rgmii_rx_ctl");
279 gpio_request(IMX_GPIO_NR(3, 23), "rgmii_reset_sabrelite");
280 gpio_request(IMX_GPIO_NR(1, 27), "rgmii_reset_nitrogen6x");
Eric Nelsone5b3a502013-03-11 08:44:53 +0000281 setup_iomux_enet();
282
283#ifdef CONFIG_FEC_MXC
284 bus = fec_get_miibus(base, -1);
285 if (!bus)
Fabio Estevam5ff50db2015-09-11 00:53:51 -0300286 return -EINVAL;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000287 /* scan phy 4,5,6,7 */
Marek Behún3927efb2022-04-07 00:33:08 +0200288 phydev = phy_find_by_mask(bus, (0xf << 4));
Eric Nelsone5b3a502013-03-11 08:44:53 +0000289 if (!phydev) {
Fabio Estevam5ff50db2015-09-11 00:53:51 -0300290 ret = -EINVAL;
291 goto free_bus;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000292 }
293 printf("using phy at %d\n", phydev->addr);
294 ret = fec_probe(bis, -1, base, bus, phydev);
Fabio Estevam5ff50db2015-09-11 00:53:51 -0300295 if (ret)
296 goto free_phydev;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000297#endif
Troy Kisky645ccc52013-09-25 18:41:17 -0700298
Eric Nelsone5b3a502013-03-11 08:44:53 +0000299 return 0;
Fabio Estevam5ff50db2015-09-11 00:53:51 -0300300
301free_phydev:
302 free(phydev);
303free_bus:
304 free(bus);
305 return ret;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000306}
307
308static void setup_buttons(void)
309{
Troy Kisky281f4e32019-11-03 18:20:04 -0800310 SETUP_IOMUX_PADS(button_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000311}
312
Eric Nelsone5b3a502013-03-11 08:44:53 +0000313#if defined(CONFIG_VIDEO_IPUV3)
314
315static iomux_v3_cfg_t const backlight_pads[] = {
316 /* Backlight on RGB connector: J15 */
Troy Kisky281f4e32019-11-03 18:20:04 -0800317 IOMUX_PAD_CTRL(SD1_DAT3__GPIO1_IO21, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000318#define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
319
320 /* Backlight on LVDS connector: J6 */
Troy Kisky281f4e32019-11-03 18:20:04 -0800321 IOMUX_PAD_CTRL(SD1_CMD__GPIO1_IO18, NO_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000322#define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
323};
324
325static iomux_v3_cfg_t const rgb_pads[] = {
Troy Kisky281f4e32019-11-03 18:20:04 -0800326 IOMUX_PAD_CTRL(DI0_DISP_CLK__IPU1_DI0_DISP_CLK, RGB_PAD_CTRL),
327 IOMUX_PAD_CTRL(DI0_PIN15__IPU1_DI0_PIN15, RGB_PAD_CTRL),
328 IOMUX_PAD_CTRL(DI0_PIN2__IPU1_DI0_PIN02, RGB_PAD_CTRL),
329 IOMUX_PAD_CTRL(DI0_PIN3__IPU1_DI0_PIN03, RGB_PAD_CTRL),
330 IOMUX_PAD_CTRL(DI0_PIN4__GPIO4_IO20, RGB_PAD_CTRL),
331 IOMUX_PAD_CTRL(DISP0_DAT0__IPU1_DISP0_DATA00, RGB_PAD_CTRL),
332 IOMUX_PAD_CTRL(DISP0_DAT1__IPU1_DISP0_DATA01, RGB_PAD_CTRL),
333 IOMUX_PAD_CTRL(DISP0_DAT2__IPU1_DISP0_DATA02, RGB_PAD_CTRL),
334 IOMUX_PAD_CTRL(DISP0_DAT3__IPU1_DISP0_DATA03, RGB_PAD_CTRL),
335 IOMUX_PAD_CTRL(DISP0_DAT4__IPU1_DISP0_DATA04, RGB_PAD_CTRL),
336 IOMUX_PAD_CTRL(DISP0_DAT5__IPU1_DISP0_DATA05, RGB_PAD_CTRL),
337 IOMUX_PAD_CTRL(DISP0_DAT6__IPU1_DISP0_DATA06, RGB_PAD_CTRL),
338 IOMUX_PAD_CTRL(DISP0_DAT7__IPU1_DISP0_DATA07, RGB_PAD_CTRL),
339 IOMUX_PAD_CTRL(DISP0_DAT8__IPU1_DISP0_DATA08, RGB_PAD_CTRL),
340 IOMUX_PAD_CTRL(DISP0_DAT9__IPU1_DISP0_DATA09, RGB_PAD_CTRL),
341 IOMUX_PAD_CTRL(DISP0_DAT10__IPU1_DISP0_DATA10, RGB_PAD_CTRL),
342 IOMUX_PAD_CTRL(DISP0_DAT11__IPU1_DISP0_DATA11, RGB_PAD_CTRL),
343 IOMUX_PAD_CTRL(DISP0_DAT12__IPU1_DISP0_DATA12, RGB_PAD_CTRL),
344 IOMUX_PAD_CTRL(DISP0_DAT13__IPU1_DISP0_DATA13, RGB_PAD_CTRL),
345 IOMUX_PAD_CTRL(DISP0_DAT14__IPU1_DISP0_DATA14, RGB_PAD_CTRL),
346 IOMUX_PAD_CTRL(DISP0_DAT15__IPU1_DISP0_DATA15, RGB_PAD_CTRL),
347 IOMUX_PAD_CTRL(DISP0_DAT16__IPU1_DISP0_DATA16, RGB_PAD_CTRL),
348 IOMUX_PAD_CTRL(DISP0_DAT17__IPU1_DISP0_DATA17, RGB_PAD_CTRL),
349 IOMUX_PAD_CTRL(DISP0_DAT18__IPU1_DISP0_DATA18, RGB_PAD_CTRL),
350 IOMUX_PAD_CTRL(DISP0_DAT19__IPU1_DISP0_DATA19, RGB_PAD_CTRL),
351 IOMUX_PAD_CTRL(DISP0_DAT20__IPU1_DISP0_DATA20, RGB_PAD_CTRL),
352 IOMUX_PAD_CTRL(DISP0_DAT21__IPU1_DISP0_DATA21, RGB_PAD_CTRL),
353 IOMUX_PAD_CTRL(DISP0_DAT22__IPU1_DISP0_DATA22, RGB_PAD_CTRL),
354 IOMUX_PAD_CTRL(DISP0_DAT23__IPU1_DISP0_DATA23, RGB_PAD_CTRL),
Eric Nelsone5b3a502013-03-11 08:44:53 +0000355};
356
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500357static void do_enable_hdmi(struct display_info_t const *dev)
Eric Nelsone5b3a502013-03-11 08:44:53 +0000358{
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500359 imx_enable_hdmi_phy();
Eric Nelsone5b3a502013-03-11 08:44:53 +0000360}
361
362static int detect_i2c(struct display_info_t const *dev)
363{
Anatolij Gustschinabd37d12024-07-20 14:48:03 +0200364 struct udevice *udev = NULL;
365 int ret;
366
367 ret = i2c_get_chip_for_busnum(dev->bus, dev->addr, 1, &udev);
368 return ret ? 0 : 1;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000369}
370
371static void enable_lvds(struct display_info_t const *dev)
372{
373 struct iomuxc *iomux = (struct iomuxc *)
374 IOMUXC_BASE_ADDR;
375 u32 reg = readl(&iomux->gpr[2]);
376 reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
377 writel(reg, &iomux->gpr[2]);
378 gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
379}
380
Robert Winklerbdb89582014-10-02 12:16:31 -0700381static void enable_lvds_jeida(struct display_info_t const *dev)
382{
383 struct iomuxc *iomux = (struct iomuxc *)
384 IOMUXC_BASE_ADDR;
385 u32 reg = readl(&iomux->gpr[2]);
386 reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
387 |IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA;
388 writel(reg, &iomux->gpr[2]);
389 gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
390}
391
Eric Nelsone5b3a502013-03-11 08:44:53 +0000392static void enable_rgb(struct display_info_t const *dev)
393{
Troy Kisky281f4e32019-11-03 18:20:04 -0800394 SETUP_IOMUX_PADS(rgb_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000395 gpio_direction_output(RGB_BACKLIGHT_GP, 1);
396}
397
Eric Benard7f63c142014-04-04 19:05:53 +0200398struct display_info_t const displays[] = {{
Eric Nelsoneb452ef2014-10-02 12:16:39 -0700399 .bus = 1,
400 .addr = 0x50,
Eric Nelsone5b3a502013-03-11 08:44:53 +0000401 .pixfmt = IPU_PIX_FMT_RGB24,
Eric Nelsoneb452ef2014-10-02 12:16:39 -0700402 .detect = detect_i2c,
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500403 .enable = do_enable_hdmi,
Eric Nelsone5b3a502013-03-11 08:44:53 +0000404 .mode = {
405 .name = "HDMI",
406 .refresh = 60,
407 .xres = 1024,
408 .yres = 768,
409 .pixclock = 15385,
410 .left_margin = 220,
411 .right_margin = 40,
412 .upper_margin = 21,
413 .lower_margin = 7,
414 .hsync_len = 60,
415 .vsync_len = 10,
416 .sync = FB_SYNC_EXT,
417 .vmode = FB_VMODE_NONINTERLACED
418} }, {
Robert Winklerbdb89582014-10-02 12:16:31 -0700419 .bus = 0,
420 .addr = 0,
421 .pixfmt = IPU_PIX_FMT_RGB24,
422 .detect = NULL,
423 .enable = enable_lvds_jeida,
424 .mode = {
425 .name = "LDB-WXGA",
426 .refresh = 60,
427 .xres = 1280,
428 .yres = 800,
429 .pixclock = 14065,
430 .left_margin = 40,
431 .right_margin = 40,
432 .upper_margin = 3,
433 .lower_margin = 80,
434 .hsync_len = 10,
435 .vsync_len = 10,
436 .sync = FB_SYNC_EXT,
437 .vmode = FB_VMODE_NONINTERLACED
438} }, {
Eric Nelsonafe97772014-10-02 12:16:34 -0700439 .bus = 0,
440 .addr = 0,
441 .pixfmt = IPU_PIX_FMT_RGB24,
442 .detect = NULL,
443 .enable = enable_lvds,
444 .mode = {
445 .name = "LDB-WXGA-S",
446 .refresh = 60,
447 .xres = 1280,
448 .yres = 800,
449 .pixclock = 14065,
450 .left_margin = 40,
451 .right_margin = 40,
452 .upper_margin = 3,
453 .lower_margin = 80,
454 .hsync_len = 10,
455 .vsync_len = 10,
456 .sync = FB_SYNC_EXT,
457 .vmode = FB_VMODE_NONINTERLACED
458} }, {
Eric Nelsone5b3a502013-03-11 08:44:53 +0000459 .bus = 2,
460 .addr = 0x4,
461 .pixfmt = IPU_PIX_FMT_LVDS666,
462 .detect = detect_i2c,
463 .enable = enable_lvds,
464 .mode = {
465 .name = "Hannstar-XGA",
466 .refresh = 60,
467 .xres = 1024,
468 .yres = 768,
469 .pixclock = 15385,
470 .left_margin = 220,
471 .right_margin = 40,
472 .upper_margin = 21,
473 .lower_margin = 7,
474 .hsync_len = 60,
475 .vsync_len = 10,
476 .sync = FB_SYNC_EXT,
477 .vmode = FB_VMODE_NONINTERLACED
478} }, {
Eric Nelson4f754862014-10-02 12:16:33 -0700479 .bus = 0,
480 .addr = 0,
481 .pixfmt = IPU_PIX_FMT_LVDS666,
482 .detect = NULL,
483 .enable = enable_lvds,
484 .mode = {
485 .name = "LG-9.7",
486 .refresh = 60,
487 .xres = 1024,
488 .yres = 768,
489 .pixclock = 15385, /* ~65MHz */
490 .left_margin = 480,
491 .right_margin = 260,
492 .upper_margin = 16,
493 .lower_margin = 6,
494 .hsync_len = 250,
495 .vsync_len = 10,
496 .sync = FB_SYNC_EXT,
497 .vmode = FB_VMODE_NONINTERLACED
498} }, {
Eric Nelsone5b3a502013-03-11 08:44:53 +0000499 .bus = 2,
500 .addr = 0x38,
501 .pixfmt = IPU_PIX_FMT_LVDS666,
502 .detect = detect_i2c,
503 .enable = enable_lvds,
504 .mode = {
505 .name = "wsvga-lvds",
506 .refresh = 60,
507 .xres = 1024,
508 .yres = 600,
509 .pixclock = 15385,
510 .left_margin = 220,
511 .right_margin = 40,
512 .upper_margin = 21,
513 .lower_margin = 7,
514 .hsync_len = 60,
515 .vsync_len = 10,
516 .sync = FB_SYNC_EXT,
517 .vmode = FB_VMODE_NONINTERLACED
518} }, {
519 .bus = 2,
Eric Nelsonab8001d2014-10-02 12:16:35 -0700520 .addr = 0x10,
521 .pixfmt = IPU_PIX_FMT_RGB666,
522 .detect = detect_i2c,
523 .enable = enable_rgb,
524 .mode = {
525 .name = "fusion7",
526 .refresh = 60,
527 .xres = 800,
528 .yres = 480,
529 .pixclock = 33898,
530 .left_margin = 96,
531 .right_margin = 24,
532 .upper_margin = 3,
533 .lower_margin = 10,
534 .hsync_len = 72,
535 .vsync_len = 7,
536 .sync = 0x40000002,
537 .vmode = FB_VMODE_NONINTERLACED
538} }, {
Eric Nelson6c4dff62014-10-02 12:16:36 -0700539 .bus = 0,
540 .addr = 0,
541 .pixfmt = IPU_PIX_FMT_RGB666,
542 .detect = NULL,
543 .enable = enable_rgb,
544 .mode = {
545 .name = "svga",
546 .refresh = 60,
547 .xres = 800,
548 .yres = 600,
549 .pixclock = 15385,
550 .left_margin = 220,
551 .right_margin = 40,
552 .upper_margin = 21,
553 .lower_margin = 7,
554 .hsync_len = 60,
555 .vsync_len = 10,
556 .sync = 0,
557 .vmode = FB_VMODE_NONINTERLACED
558} }, {
Eric Nelsonab8001d2014-10-02 12:16:35 -0700559 .bus = 2,
Eric Nelson4368a3c2014-10-02 12:16:37 -0700560 .addr = 0x41,
561 .pixfmt = IPU_PIX_FMT_LVDS666,
562 .detect = detect_i2c,
563 .enable = enable_lvds,
564 .mode = {
565 .name = "amp1024x600",
566 .refresh = 60,
567 .xres = 1024,
568 .yres = 600,
569 .pixclock = 15385,
570 .left_margin = 220,
571 .right_margin = 40,
572 .upper_margin = 21,
573 .lower_margin = 7,
574 .hsync_len = 60,
575 .vsync_len = 10,
576 .sync = FB_SYNC_EXT,
577 .vmode = FB_VMODE_NONINTERLACED
578} }, {
Eric Nelson523aec22014-10-02 12:16:38 -0700579 .bus = 0,
580 .addr = 0,
581 .pixfmt = IPU_PIX_FMT_LVDS666,
582 .detect = 0,
583 .enable = enable_lvds,
584 .mode = {
585 .name = "wvga-lvds",
586 .refresh = 57,
587 .xres = 800,
588 .yres = 480,
589 .pixclock = 15385,
590 .left_margin = 220,
591 .right_margin = 40,
592 .upper_margin = 21,
593 .lower_margin = 7,
594 .hsync_len = 60,
595 .vsync_len = 10,
596 .sync = FB_SYNC_EXT,
597 .vmode = FB_VMODE_NONINTERLACED
598} }, {
Eric Nelson4368a3c2014-10-02 12:16:37 -0700599 .bus = 2,
Eric Nelsone5b3a502013-03-11 08:44:53 +0000600 .addr = 0x48,
601 .pixfmt = IPU_PIX_FMT_RGB666,
602 .detect = detect_i2c,
603 .enable = enable_rgb,
604 .mode = {
605 .name = "wvga-rgb",
606 .refresh = 57,
607 .xres = 800,
608 .yres = 480,
609 .pixclock = 37037,
610 .left_margin = 40,
611 .right_margin = 60,
612 .upper_margin = 10,
613 .lower_margin = 10,
614 .hsync_len = 20,
615 .vsync_len = 10,
616 .sync = 0,
617 .vmode = FB_VMODE_NONINTERLACED
Eric Nelsond7b66062014-10-02 12:16:32 -0700618} }, {
619 .bus = 0,
620 .addr = 0,
621 .pixfmt = IPU_PIX_FMT_RGB24,
622 .detect = NULL,
623 .enable = enable_rgb,
624 .mode = {
625 .name = "qvga",
626 .refresh = 60,
627 .xres = 320,
628 .yres = 240,
629 .pixclock = 37037,
630 .left_margin = 38,
631 .right_margin = 37,
632 .upper_margin = 16,
633 .lower_margin = 15,
634 .hsync_len = 30,
635 .vsync_len = 3,
636 .sync = 0,
637 .vmode = FB_VMODE_NONINTERLACED
Eric Nelsone5b3a502013-03-11 08:44:53 +0000638} } };
Eric Benard7f63c142014-04-04 19:05:53 +0200639size_t display_count = ARRAY_SIZE(displays);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000640
Eric Nelsond17aa9d2014-10-02 12:16:22 -0700641int board_cfb_skip(void)
642{
Simon Glass64b723f2017-08-03 12:22:12 -0600643 return NULL != env_get("novideo");
Eric Nelsond17aa9d2014-10-02 12:16:22 -0700644}
645
Eric Nelsone5b3a502013-03-11 08:44:53 +0000646static void setup_display(void)
647{
648 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000649 struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000650 int reg;
651
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500652 enable_ipu_clock();
653 imx_setup_hdmi();
Eric Nelsone5b3a502013-03-11 08:44:53 +0000654 /* Turn on LDB0,IPU,IPU DI0 clocks */
655 reg = __raw_readl(&mxc_ccm->CCGR3);
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500656 reg |= MXC_CCM_CCGR3_LDB_DI0_MASK;
Eric Nelsone5b3a502013-03-11 08:44:53 +0000657 writel(reg, &mxc_ccm->CCGR3);
658
Eric Nelsone5b3a502013-03-11 08:44:53 +0000659 /* set LDB0, LDB1 clk select to 011/011 */
660 reg = readl(&mxc_ccm->cs2cdr);
661 reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
662 |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
663 reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
664 |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
665 writel(reg, &mxc_ccm->cs2cdr);
666
667 reg = readl(&mxc_ccm->cscmr2);
668 reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
669 writel(reg, &mxc_ccm->cscmr2);
670
671 reg = readl(&mxc_ccm->chsccdr);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000672 reg |= (CHSCCDR_CLK_SEL_LDB_DI0
Pardeep Kumar Singlac1fa1302013-07-25 12:12:13 -0500673 <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000674 writel(reg, &mxc_ccm->chsccdr);
675
676 reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
677 |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
678 |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
679 |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
680 |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
681 |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
682 |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
683 |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
684 |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
685 writel(reg, &iomux->gpr[2]);
686
687 reg = readl(&iomux->gpr[3]);
Eric Nelson6a1c1042013-08-20 11:44:43 -0700688 reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
689 |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
Eric Nelsone5b3a502013-03-11 08:44:53 +0000690 | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
691 <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
692 writel(reg, &iomux->gpr[3]);
693
694 /* backlights off until needed */
Troy Kisky281f4e32019-11-03 18:20:04 -0800695 SETUP_IOMUX_PADS(backlight_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000696 gpio_direction_input(LVDS_BACKLIGHT_GP);
697 gpio_direction_input(RGB_BACKLIGHT_GP);
698}
699#endif
700
Eric Nelsonc310e412014-10-02 12:16:25 -0700701static iomux_v3_cfg_t const init_pads[] = {
Troy Kiskya8c2f062014-10-02 12:16:26 -0700702 /* SGTL5000 sys_mclk */
Troy Kisky281f4e32019-11-03 18:20:04 -0800703 IOMUX_PAD_CTRL(GPIO_0__CCM_CLKO1, OUTPUT_40OHM),
Troy Kiskya8c2f062014-10-02 12:16:26 -0700704
705 /* J5 - Camera MCLK */
Troy Kisky281f4e32019-11-03 18:20:04 -0800706 IOMUX_PAD_CTRL(GPIO_3__CCM_CLKO2, OUTPUT_40OHM),
Troy Kiskya8c2f062014-10-02 12:16:26 -0700707
708 /* wl1271 pads on nitrogen6x */
Eric Nelsonc310e412014-10-02 12:16:25 -0700709 /* WL12XX_WL_IRQ_GP */
Troy Kisky281f4e32019-11-03 18:20:04 -0800710 IOMUX_PAD_CTRL(NANDF_CS1__GPIO6_IO14, WEAK_PULLDOWN),
Eric Nelsonc310e412014-10-02 12:16:25 -0700711 /* WL12XX_WL_ENABLE_GP */
Troy Kisky281f4e32019-11-03 18:20:04 -0800712 IOMUX_PAD_CTRL(NANDF_CS2__GPIO6_IO15, OUTPUT_40OHM),
Eric Nelsonc310e412014-10-02 12:16:25 -0700713 /* WL12XX_BT_ENABLE_GP */
Troy Kisky281f4e32019-11-03 18:20:04 -0800714 IOMUX_PAD_CTRL(NANDF_CS3__GPIO6_IO16, OUTPUT_40OHM),
Eric Nelsonc310e412014-10-02 12:16:25 -0700715 /* USB otg power */
Troy Kisky281f4e32019-11-03 18:20:04 -0800716 IOMUX_PAD_CTRL(EIM_D22__GPIO3_IO22, OUTPUT_40OHM),
717 IOMUX_PAD_CTRL(NANDF_D5__GPIO2_IO05, OUTPUT_40OHM),
718 IOMUX_PAD_CTRL(NANDF_WP_B__GPIO6_IO09, OUTPUT_40OHM),
719 IOMUX_PAD_CTRL(GPIO_8__GPIO1_IO08, OUTPUT_40OHM),
720 IOMUX_PAD_CTRL(GPIO_6__GPIO1_IO06, OUTPUT_40OHM),
Eric Nelsonc310e412014-10-02 12:16:25 -0700721};
722
723#define WL12XX_WL_IRQ_GP IMX_GPIO_NR(6, 14)
724
725static unsigned gpios_out_low[] = {
726 /* Disable wl1271 */
727 IMX_GPIO_NR(6, 15), /* disable wireless */
728 IMX_GPIO_NR(6, 16), /* disable bluetooth */
729 IMX_GPIO_NR(3, 22), /* disable USB otg power */
730 IMX_GPIO_NR(2, 5), /* ov5640 mipi camera reset */
731 IMX_GPIO_NR(1, 8), /* ov5642 reset */
732};
733
734static unsigned gpios_out_high[] = {
735 IMX_GPIO_NR(1, 6), /* ov5642 powerdown */
736 IMX_GPIO_NR(6, 9), /* ov5640 mipi camera power down */
737};
738
739static void set_gpios(unsigned *p, int cnt, int val)
740{
741 int i;
742
743 for (i = 0; i < cnt; i++)
744 gpio_direction_output(*p++, val);
745}
746
Eric Nelsone5b3a502013-03-11 08:44:53 +0000747int board_early_init_f(void)
748{
749 setup_iomux_uart();
750
Eric Nelsonc310e412014-10-02 12:16:25 -0700751 set_gpios(gpios_out_high, ARRAY_SIZE(gpios_out_high), 1);
752 set_gpios(gpios_out_low, ARRAY_SIZE(gpios_out_low), 0);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000753 gpio_direction_input(WL12XX_WL_IRQ_GP);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000754
Troy Kisky281f4e32019-11-03 18:20:04 -0800755 SETUP_IOMUX_PADS(wl12xx_pads);
756 SETUP_IOMUX_PADS(init_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000757 setup_buttons();
758
759#if defined(CONFIG_VIDEO_IPUV3)
760 setup_display();
761#endif
762 return 0;
763}
764
765/*
766 * Do not overwrite the console
767 * Use always serial for U-Boot console
768 */
769int overwrite_console(void)
770{
771 return 1;
772}
773
774int board_init(void)
775{
Fabio Estevamceb74c42014-07-09 17:59:54 -0300776 struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
Troy Kisky8606ae22013-09-25 18:41:16 -0700777
778 clrsetbits_le32(&iomuxc_regs->gpr[1],
779 IOMUXC_GPR1_OTG_ID_MASK,
780 IOMUXC_GPR1_OTG_ID_GPIO1);
781
Troy Kisky281f4e32019-11-03 18:20:04 -0800782 SETUP_IOMUX_PADS(misc_pads);
Troy Kisky645ccc52013-09-25 18:41:17 -0700783
Eric Nelsone5b3a502013-03-11 08:44:53 +0000784 /* address of boot parameters */
785 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
786
787#ifdef CONFIG_MXC_SPI
788 setup_spi();
789#endif
Troy Kisky281f4e32019-11-03 18:20:04 -0800790 SETUP_IOMUX_PADS(usdhc2_pads);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000791
Simon Glassab3055a2017-06-14 21:28:25 -0600792#ifdef CONFIG_SATA
Eric Nelsone5b3a502013-03-11 08:44:53 +0000793 setup_sata();
794#endif
795
796 return 0;
797}
798
799int checkboard(void)
800{
Troy Kisky3d5b2562019-07-29 12:15:56 -0700801 int ret = gpio_get_value(WL12XX_WL_IRQ_GP);
802
803 if (ret < 0) {
804 /* The gpios have not been probed yet. Read it myself */
805 struct gpio_regs *regs = (struct gpio_regs *)GPIO6_BASE_ADDR;
806 int gpio = WL12XX_WL_IRQ_GP & 0x1f;
807
808 ret = (readl(&regs->gpio_psr) >> gpio) & 0x01;
809 }
810 if (ret)
Eric Nelsone5b3a502013-03-11 08:44:53 +0000811 puts("Board: Nitrogen6X\n");
812 else
813 puts("Board: SABRE Lite\n");
814
815 return 0;
816}
817
818struct button_key {
819 char const *name;
820 unsigned gpnum;
821 char ident;
822};
823
824static struct button_key const buttons[] = {
825 {"back", IMX_GPIO_NR(2, 2), 'B'},
826 {"home", IMX_GPIO_NR(2, 4), 'H'},
827 {"menu", IMX_GPIO_NR(2, 1), 'M'},
828 {"search", IMX_GPIO_NR(2, 3), 'S'},
829 {"volup", IMX_GPIO_NR(7, 13), 'V'},
830 {"voldown", IMX_GPIO_NR(4, 5), 'v'},
831};
832
833/*
834 * generate a null-terminated string containing the buttons pressed
835 * returns number of keys pressed
836 */
837static int read_keys(char *buf)
838{
839 int i, numpressed = 0;
840 for (i = 0; i < ARRAY_SIZE(buttons); i++) {
841 if (!gpio_get_value(buttons[i].gpnum))
842 buf[numpressed++] = buttons[i].ident;
843 }
844 buf[numpressed] = '\0';
845 return numpressed;
846}
847
Simon Glassed38aef2020-05-10 11:40:03 -0600848static int do_kbd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Eric Nelsone5b3a502013-03-11 08:44:53 +0000849{
850 char envvalue[ARRAY_SIZE(buttons)+1];
851 int numpressed = read_keys(envvalue);
Simon Glass6a38e412017-08-03 12:22:09 -0600852 env_set("keybd", envvalue);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000853 return numpressed == 0;
854}
855
856U_BOOT_CMD(
857 kbd, 1, 1, do_kbd,
858 "Tests for keypresses, sets 'keybd' environment variable",
859 "Returns 0 (true) to shell if key is pressed."
860);
861
Pali Rohár39c43c32022-07-10 13:42:55 +0200862#ifdef CONFIG_USE_PREBOOT
Eric Nelsone5b3a502013-03-11 08:44:53 +0000863static char const kbd_magic_prefix[] = "key_magic";
864static char const kbd_command_prefix[] = "key_cmd";
865
866static void preboot_keys(void)
867{
868 int numpressed;
869 char keypress[ARRAY_SIZE(buttons)+1];
870 numpressed = read_keys(keypress);
871 if (numpressed) {
Simon Glass64b723f2017-08-03 12:22:12 -0600872 char *kbd_magic_keys = env_get("magic_keys");
Eric Nelsone5b3a502013-03-11 08:44:53 +0000873 char *suffix;
874 /*
875 * loop over all magic keys
876 */
877 for (suffix = kbd_magic_keys; *suffix; ++suffix) {
878 char *keys;
879 char magic[sizeof(kbd_magic_prefix) + 1];
880 sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
Simon Glass64b723f2017-08-03 12:22:12 -0600881 keys = env_get(magic);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000882 if (keys) {
883 if (!strcmp(keys, keypress))
884 break;
885 }
886 }
887 if (*suffix) {
888 char cmd_name[sizeof(kbd_command_prefix) + 1];
889 char *cmd;
890 sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
Simon Glass64b723f2017-08-03 12:22:12 -0600891 cmd = env_get(cmd_name);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000892 if (cmd) {
Simon Glass6a38e412017-08-03 12:22:09 -0600893 env_set("preboot", cmd);
Eric Nelsone5b3a502013-03-11 08:44:53 +0000894 return;
895 }
896 }
897 }
898}
899#endif
900
901#ifdef CONFIG_CMD_BMODE
902static const struct boot_mode board_boot_modes[] = {
903 /* 4 bit bus width */
904 {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
905 {"mmc1", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
906 {NULL, 0},
907};
908#endif
909
910int misc_init_r(void)
911{
Troy Kisky3d5b2562019-07-29 12:15:56 -0700912 gpio_request(RGB_BACKLIGHT_GP, "lvds backlight");
913 gpio_request(LVDS_BACKLIGHT_GP, "lvds backlight");
914 gpio_request(GP_USB_OTG_PWR, "usbotg power");
915 gpio_request(IMX_GPIO_NR(7, 12), "usbh1 hub reset");
916 gpio_request(IMX_GPIO_NR(2, 2), "back");
917 gpio_request(IMX_GPIO_NR(2, 4), "home");
918 gpio_request(IMX_GPIO_NR(2, 1), "menu");
919 gpio_request(IMX_GPIO_NR(2, 3), "search");
920 gpio_request(IMX_GPIO_NR(7, 13), "volup");
921 gpio_request(IMX_GPIO_NR(4, 5), "voldown");
Pali Rohár39c43c32022-07-10 13:42:55 +0200922#ifdef CONFIG_USE_PREBOOT
Eric Nelsone5b3a502013-03-11 08:44:53 +0000923 preboot_keys();
924#endif
925
926#ifdef CONFIG_CMD_BMODE
927 add_board_boot_modes(board_boot_modes);
928#endif
Simon Glass4d949a22017-08-03 12:22:10 -0600929 env_set_hex("reset_cause", get_imx_reset_cause());
Eric Nelsone5b3a502013-03-11 08:44:53 +0000930 return 0;
931}