blob: 445ce987b683c8f7e3c6e344d892467508db9cd4 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Markus Niebelee2cd2b2014-07-18 16:52:44 +02002/*
3 * Copyright (C) 2012 Freescale Semiconductor, Inc.
4 * Author: Fabio Estevam <fabio.estevam@freescale.com>
5 *
Matthias Schifferb50ae032021-11-02 11:36:46 +01006 * Copyright (C) 2013, 2014 TQ-Systems (ported SabreSD to TQMa6x)
Markus Niebelee2cd2b2014-07-18 16:52:44 +02007 * Author: Markus Niebel <markus.niebel@tq-group.com>
Markus Niebelee2cd2b2014-07-18 16:52:44 +02008 */
9
Simon Glassa7b51302019-11-14 12:57:46 -070010#include <init.h>
Markus Niebelee2cd2b2014-07-18 16:52:44 +020011#include <asm/arch/clock.h>
12#include <asm/arch/mx6-pins.h>
13#include <asm/arch/imx-regs.h>
14#include <asm/arch/iomux.h>
15#include <asm/arch/sys_proto.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060016#include <env.h>
Simon Glass2dc9c342020-05-10 11:40:01 -060017#include <fdt_support.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060018#include <asm/global_data.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +090019#include <linux/errno.h>
Markus Niebelee2cd2b2014-07-18 16:52:44 +020020#include <asm/gpio.h>
21#include <asm/io.h>
Stefano Babic33731bc2017-06-29 10:16:06 +020022#include <asm/mach-imx/spi.h>
Yangbo Lu73340382019-06-21 11:42:28 +080023#include <fsl_esdhc_imx.h>
Masahiro Yamada75f82d02018-03-05 01:20:11 +090024#include <linux/libfdt.h>
Markus Niebelee2cd2b2014-07-18 16:52:44 +020025#include <mmc.h>
26#include <power/pfuze100_pmic.h>
27#include <power/pmic.h>
Stefan Roese4630f262015-08-05 10:50:50 +020028#include <spi_flash.h>
Markus Niebelee2cd2b2014-07-18 16:52:44 +020029
30#include "tqma6_bb.h"
31
32DECLARE_GLOBAL_DATA_PTR;
33
34#define USDHC_CLK_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
35 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
36
37#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
38 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
39
40#define GPIO_OUT_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
41 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
42
43#define GPIO_IN_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \
44 PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
45
46#define SPI_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
47 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
48
Markus Niebelee2cd2b2014-07-18 16:52:44 +020049int dram_init(void)
50{
Markus Niebela87a7832014-11-18 13:22:57 +010051 gd->ram_size = imx_ddr_size();
Markus Niebelee2cd2b2014-07-18 16:52:44 +020052
53 return 0;
54}
55
56static const uint16_t tqma6_emmc_dsr = 0x0100;
57
Michael Krummsdorfade873e2020-04-09 15:21:41 +020058#ifndef CONFIG_DM_MMC
Markus Niebelee2cd2b2014-07-18 16:52:44 +020059/* eMMC on USDHCI3 always present */
60static iomux_v3_cfg_t const tqma6_usdhc3_pads[] = {
61 NEW_PAD_CTRL(MX6_PAD_SD3_CLK__SD3_CLK, USDHC_PAD_CTRL),
62 NEW_PAD_CTRL(MX6_PAD_SD3_CMD__SD3_CMD, USDHC_PAD_CTRL),
63 NEW_PAD_CTRL(MX6_PAD_SD3_DAT0__SD3_DATA0, USDHC_PAD_CTRL),
64 NEW_PAD_CTRL(MX6_PAD_SD3_DAT1__SD3_DATA1, USDHC_PAD_CTRL),
65 NEW_PAD_CTRL(MX6_PAD_SD3_DAT2__SD3_DATA2, USDHC_PAD_CTRL),
66 NEW_PAD_CTRL(MX6_PAD_SD3_DAT3__SD3_DATA3, USDHC_PAD_CTRL),
67 NEW_PAD_CTRL(MX6_PAD_SD3_DAT4__SD3_DATA4, USDHC_PAD_CTRL),
68 NEW_PAD_CTRL(MX6_PAD_SD3_DAT5__SD3_DATA5, USDHC_PAD_CTRL),
69 NEW_PAD_CTRL(MX6_PAD_SD3_DAT6__SD3_DATA6, USDHC_PAD_CTRL),
70 NEW_PAD_CTRL(MX6_PAD_SD3_DAT7__SD3_DATA7, USDHC_PAD_CTRL),
71 /* eMMC reset */
72 NEW_PAD_CTRL(MX6_PAD_SD3_RST__SD3_RESET, GPIO_OUT_PAD_CTRL),
73};
74
75/*
76 * According to board_mmc_init() the following map is done:
Bin Meng75574052016-02-05 19:30:11 -080077 * (U-Boot device node) (Physical Port)
Markus Niebelee2cd2b2014-07-18 16:52:44 +020078 * mmc0 eMMC (SD3) on TQMa6
79 * mmc1 .. n optional slots used on baseboard
80 */
81struct fsl_esdhc_cfg tqma6_usdhc_cfg = {
82 .esdhc_base = USDHC3_BASE_ADDR,
83 .max_bus_width = 8,
84};
85
86int board_mmc_getcd(struct mmc *mmc)
87{
88 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
89 int ret = 0;
90
91 if (cfg->esdhc_base == USDHC3_BASE_ADDR)
92 /* eMMC/uSDHC3 is always present */
93 ret = 1;
94 else
95 ret = tqma6_bb_board_mmc_getcd(mmc);
96
97 return ret;
98}
99
100int board_mmc_getwp(struct mmc *mmc)
101{
102 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
103 int ret = 0;
104
105 if (cfg->esdhc_base == USDHC3_BASE_ADDR)
106 /* eMMC/uSDHC3 is always present */
107 ret = 0;
108 else
109 ret = tqma6_bb_board_mmc_getwp(mmc);
110
111 return ret;
112}
113
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900114int board_mmc_init(struct bd_info *bis)
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200115{
116 imx_iomux_v3_setup_multiple_pads(tqma6_usdhc3_pads,
117 ARRAY_SIZE(tqma6_usdhc3_pads));
118 tqma6_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
119 if (fsl_esdhc_initialize(bis, &tqma6_usdhc_cfg)) {
120 puts("Warning: failed to initialize eMMC dev\n");
121 } else {
122 struct mmc *mmc = find_mmc_device(0);
123 if (mmc)
124 mmc_set_dsr(mmc, tqma6_emmc_dsr);
125 }
126
127 tqma6_bb_board_mmc_init(bis);
128
129 return 0;
130}
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200131#endif
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200132
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200133#ifndef CONFIG_DM_SPI
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200134static iomux_v3_cfg_t const tqma6_ecspi1_pads[] = {
135 /* SS1 */
136 NEW_PAD_CTRL(MX6_PAD_EIM_D19__GPIO3_IO19, SPI_PAD_CTRL),
137 NEW_PAD_CTRL(MX6_PAD_EIM_D16__ECSPI1_SCLK, SPI_PAD_CTRL),
138 NEW_PAD_CTRL(MX6_PAD_EIM_D17__ECSPI1_MISO, SPI_PAD_CTRL),
139 NEW_PAD_CTRL(MX6_PAD_EIM_D18__ECSPI1_MOSI, SPI_PAD_CTRL),
140};
141
Markus Niebela116f6f2014-10-23 15:47:05 +0200142#define TQMA6_SF_CS_GPIO IMX_GPIO_NR(3, 19)
143
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200144static unsigned const tqma6_ecspi1_cs[] = {
Markus Niebela116f6f2014-10-23 15:47:05 +0200145 TQMA6_SF_CS_GPIO,
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200146};
147
Stefan Roesed56cb172015-03-12 13:34:30 +0100148__weak void tqma6_iomuxc_spi(void)
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200149{
150 unsigned i;
151
152 for (i = 0; i < ARRAY_SIZE(tqma6_ecspi1_cs); ++i)
153 gpio_direction_output(tqma6_ecspi1_cs[i], 1);
154 imx_iomux_v3_setup_multiple_pads(tqma6_ecspi1_pads,
155 ARRAY_SIZE(tqma6_ecspi1_pads));
156}
157
Patrick Delaunayc4468072019-02-27 15:20:35 +0100158#if defined(CONFIG_SF_DEFAULT_BUS) && defined(CONFIG_SF_DEFAULT_CS)
Markus Niebela116f6f2014-10-23 15:47:05 +0200159int board_spi_cs_gpio(unsigned bus, unsigned cs)
160{
161 return ((bus == CONFIG_SF_DEFAULT_BUS) &&
162 (cs == CONFIG_SF_DEFAULT_CS)) ? TQMA6_SF_CS_GPIO : -1;
163}
Patrick Delaunayc4468072019-02-27 15:20:35 +0100164#endif
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200165#endif
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200166
167int board_early_init_f(void)
168{
169 return tqma6_bb_board_early_init_f();
170}
171
172int board_init(void)
173{
174 /* address of boot parameters */
175 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
176
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200177#ifndef CONFIG_DM_SPI
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200178 tqma6_iomuxc_spi();
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200179#endif
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200180 tqma6_bb_board_init();
181
182 return 0;
183}
184
185static const char *tqma6_get_boardname(void)
186{
187 u32 cpurev = get_cpu_rev();
188
189 switch ((cpurev & 0xFF000) >> 12) {
190 case MXC_CPU_MX6SOLO:
191 return "TQMa6S";
192 break;
193 case MXC_CPU_MX6DL:
194 return "TQMa6DL";
195 break;
196 case MXC_CPU_MX6D:
197 return "TQMa6D";
198 break;
199 case MXC_CPU_MX6Q:
200 return "TQMa6Q";
201 break;
202 default:
203 return "??";
204 };
205}
206
Fabio Estevamba1015b2024-08-09 14:58:08 -0300207#if CONFIG_IS_ENABLED(DM_PMIC)
Markus Niebel00bb1872017-02-03 16:24:58 +0100208/* setup board specific PMIC */
209int power_init_board(void)
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200210{
Fabio Estevamba1015b2024-08-09 14:58:08 -0300211 struct udevice *dev;
Markus Niebel00bb1872017-02-03 16:24:58 +0100212 u32 reg, rev;
Fabio Estevamba1015b2024-08-09 14:58:08 -0300213 int ret;
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200214
Fabio Estevamba1015b2024-08-09 14:58:08 -0300215 ret = pmic_get("pmic@8", &dev);
216 if (ret < 0)
217 return 0;
218
219 reg = pmic_reg_read(dev, PFUZE100_DEVICEID);
220 rev = pmic_reg_read(dev, PFUZE100_REVID);
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200221
Fabio Estevamba1015b2024-08-09 14:58:08 -0300222 printf("PMIC: PFUZE100 ID=0x%02x REV=0x%02x\n", reg, rev);
Markus Niebel00bb1872017-02-03 16:24:58 +0100223 return 0;
224}
Michael Krummsdorfade873e2020-04-09 15:21:41 +0200225#endif
Markus Niebel00bb1872017-02-03 16:24:58 +0100226
227int board_late_init(void)
228{
Simon Glass6a38e412017-08-03 12:22:09 -0600229 env_set("board_name", tqma6_get_boardname());
Markus Niebel00bb1872017-02-03 16:24:58 +0100230
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200231 tqma6_bb_board_late_init();
232
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200233 printf("Board: %s on a %s\n", tqma6_get_boardname(),
234 tqma6_bb_get_boardname());
235 return 0;
236}
237
238/*
239 * Device Tree Support
240 */
241#if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
Markus Niebelc01ca162017-02-28 16:37:33 +0100242#define MODELSTRLEN 32u
Masahiro Yamadaf7ed78b2020-06-26 15:13:33 +0900243int ft_board_setup(void *blob, struct bd_info *bd)
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200244{
Markus Niebelc01ca162017-02-28 16:37:33 +0100245 char modelstr[MODELSTRLEN];
246
247 snprintf(modelstr, MODELSTRLEN, "TQ %s on %s", tqma6_get_boardname(),
248 tqma6_bb_get_boardname());
249 do_fixup_by_path_string(blob, "/", "model", modelstr);
250 fdt_fixup_memory(blob, (u64)PHYS_SDRAM, (u64)gd->ram_size);
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200251 /* bring in eMMC dsr settings */
252 do_fixup_by_path_u32(blob,
253 "/soc/aips-bus@02100000/usdhc@02198000",
254 "dsr", tqma6_emmc_dsr, 2);
255 tqma6_bb_ft_board_setup(blob, bd);
Simon Glass2aec3cc2014-10-23 18:58:47 -0600256
257 return 0;
Markus Niebelee2cd2b2014-07-18 16:52:44 +0200258}
259#endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */