2 * Copyright (C) ST-Ericsson SA 2009
4 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/types.h>
14 #include <asm/errno.h>
15 #include <asm/arch/db8500_pincfg.h>
16 #include <asm/arch/prcmu.h>
17 #include <asm/arch/hardware.h>
18 #include <asm/arch/sys_proto.h>
21 #include "../../../drivers/mmc/arm_pl180_mmci.h"
23 #include "db8500_pins.h"
26 * Get a global data pointer
28 DECLARE_GLOBAL_DATA_PTR;
31 * Memory controller register
33 #define DMC_BASE_ADDR 0x80156000
34 #define DMC_CTL_97 (DMC_BASE_ADDR + 0x184)
37 * GPIO pin config common for MOP500/HREF boards
39 unsigned long gpio_cfg_common[] = {
53 GPIO145_SSP0_RXD | PIN_PULL_DOWN,
56 /* MMC0 (MicroSD card) */
57 GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH,
58 GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH,
59 GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH,
60 GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH,
61 GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL,
62 GPIO23_MC0_CLK | PIN_OUTPUT_LOW,
63 GPIO24_MC0_CMD | PIN_INPUT_PULLUP,
64 GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP,
65 GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP,
66 GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP,
67 GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP,
69 /* MMC4 (On-board eMMC) */
70 GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP,
71 GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP,
72 GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP,
73 GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP,
74 GPIO201_MC4_CMD | PIN_INPUT_PULLUP,
75 GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL,
76 GPIO203_MC4_CLK | PIN_OUTPUT_LOW,
77 GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP,
78 GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP,
79 GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP,
80 GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP,
83 GPIO29_U2_RXD | PIN_INPUT_PULLUP,
84 GPIO30_U2_TXD | PIN_OUTPUT_HIGH,
85 GPIO31_U2_CTSn | PIN_INPUT_PULLUP,
86 GPIO32_U2_RTSn | PIN_OUTPUT_HIGH,
89 * USB, pin 256-267 USB, Is probably already setup correctly from
90 * BootROM/boot stages, but we don't trust that and set it up anyway
106 unsigned long gpio_cfg_snowball[] = {
107 /* MMC0 (MicroSD card) */
108 GPIO217_GPIO | PIN_OUTPUT_HIGH, /* MMC_EN */
109 GPIO218_GPIO | PIN_INPUT_NOPULL, /* MMC_CD */
110 GPIO228_GPIO | PIN_OUTPUT_HIGH, /* SD_SEL */
113 GPIO167_GPIO | PIN_OUTPUT_HIGH, /* RSTn_MLC */
126 GPIO141_GPIO | PIN_OUTPUT_HIGH,
130 * Miscellaneous platform dependent initialisations
136 * Setup board (bd) and board-info (bi).
137 * bi_arch_number: Unique id for this board. It will passed in r1 to
138 * Linux startup code and is the machine_id.
139 * bi_boot_params: Where this board expects params.
141 gd->bd->bi_arch_number = MACH_TYPE_SNOWBALL;
142 gd->bd->bi_boot_params = 0x00000100;
144 /* Configure GPIO pins needed by U-boot */
145 db8500_gpio_config_pins(gpio_cfg_common, ARRAY_SIZE(gpio_cfg_common));
147 db8500_gpio_config_pins(gpio_cfg_snowball,
148 ARRAY_SIZE(gpio_cfg_snowball));
155 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
156 gd->ram_size = gd->bd->bi_dram[0].size =
157 get_ram_size(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MAX_RAM_SIZE);
162 static int raise_ab8500_gpio16(void)
167 ret = ab8500_read(AB8500_MISC, AB8500_GPIO_SEL2_REG);
172 ret = ab8500_write(AB8500_MISC, AB8500_GPIO_SEL2_REG, ret);
177 ret = ab8500_read(AB8500_MISC, AB8500_GPIO_DIR2_REG);
182 ret = ab8500_write(AB8500_MISC, AB8500_GPIO_DIR2_REG, ret);
187 ret = ab8500_read(AB8500_MISC, AB8500_GPIO_OUT2_REG);
192 ret = ab8500_write(AB8500_MISC, AB8500_GPIO_OUT2_REG, ret);
198 static int raise_ab8500_gpio26(void)
203 ret = ab8500_read(AB8500_MISC, AB8500_GPIO_DIR4_REG);
208 ret = ab8500_write(AB8500_MISC, AB8500_GPIO_DIR4_REG, ret);
213 ret = ab8500_read(AB8500_MISC, AB8500_GPIO_OUT4_REG);
218 ret = ab8500_write(AB8500_MISC, AB8500_GPIO_OUT4_REG, ret);
224 int board_late_init(void)
226 /* enable 3V3 for LAN controller */
227 if (raise_ab8500_gpio26() >= 0) {
228 /* Turn on FSMC device */
229 writel(0x1, 0x8000f000);
230 writel(0x1, 0x8000f008);
232 /* setup FSMC for LAN controler */
233 writel(0x305b, 0x80000000);
235 /* run at the highest possible speed */
236 writel(0x01010210, 0x80000004);
238 printf("error: can't raise GPIO26\n");
240 /* enable 3v6 for GBF chip */
241 if ((raise_ab8500_gpio16() < 0))
242 printf("error: cant' raise GPIO16\n");
244 /* empty UART RX FIFO */
253 * emmc_host_init - initialize the emmc controller.
254 * Configure GPIO settings, set initial clock and power for emmc slot.
255 * Initialize mmc struct and register with mmc framework.
257 static int emmc_host_init(void)
259 struct pl180_mmc_host *host;
261 host = malloc(sizeof(struct pl180_mmc_host));
264 memset(host, 0, sizeof(*host));
266 host->base = (struct sdi_registers *)CFG_EMMC_BASE;
267 host->pwr_init = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
268 host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V2 |
269 SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
270 strcpy(host->name, "EMMC");
271 host->caps = MMC_MODE_8BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz;
272 host->voltages = VOLTAGE_WINDOW_MMC;
273 host->clock_min = ARM_MCLK / (2 + SDI_CLKCR_CLKDIV_INIT_V2);
274 host->clock_max = ARM_MCLK / 2;
275 host->clock_in = ARM_MCLK;
278 return arm_pl180_mmci_init(host);
282 * mmc_host_init - initialize the external mmc controller.
283 * Configure GPIO settings, set initial clock and power for mmc slot.
284 * Initialize mmc struct and register with mmc framework.
286 static int mmc_host_init(void)
288 struct pl180_mmc_host *host;
291 host = malloc(sizeof(struct pl180_mmc_host));
294 memset(host, 0, sizeof(*host));
296 host->base = (struct sdi_registers *)CFG_MMC_BASE;
298 writel(sdi_u32, &host->base->power);
299 host->pwr_init = 0xBF;
300 host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V2 |
301 SDI_CLKCR_CLKEN | SDI_CLKCR_HWFC_EN;
302 strcpy(host->name, "MMC");
303 host->caps = MMC_MODE_8BIT;
305 host->voltages = VOLTAGE_WINDOW_SD;
306 host->clock_min = ARM_MCLK / (2 + SDI_CLKCR_CLKDIV_INIT_V2);
307 host->clock_max = ARM_MCLK / 2;
308 host->clock_in = ARM_MCLK;
311 return arm_pl180_mmci_init(host);
315 * board_mmc_init - initialize all the mmc/sd host controllers.
316 * Called by generic mmc framework.
318 int board_mmc_init(bd_t *bis)
324 error = emmc_host_init();
326 printf("emmc_host_init() %d\n", error);
330 u8500_mmc_power_init();
332 error = mmc_host_init();
334 printf("mmc_host_init() %d\n", error);
340 #endif /* CONFIG_MMC */