spl.c 5.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0+
2 3 4 5 6 7 8 9 10
/*
 * SPL board functions for CompuLab CL-SOM-iMX7 module
 *
 * (C) Copyright 2017 CompuLab, Ltd. http://www.compulab.com
 *
 * Author: Uri Mashiach <uri.mashiach@compulab.co.il>
 */

#include <common.h>
11
#include <hang.h>
12
#include <init.h>
13
#include <spl.h>
14
#include <fsl_esdhc_imx.h>
15 16 17 18 19 20
#include <asm/mach-imx/iomux-v3.h>
#include <asm/arch-mx7/mx7-pins.h>
#include <asm/arch-mx7/clock.h>
#include <asm/arch-mx7/mx7-ddr.h>
#include "common.h"

21
#ifdef CONFIG_FSL_ESDHC_IMX
22 23 24 25

static struct fsl_esdhc_cfg cl_som_imx7_spl_usdhc_cfg = {
	USDHC1_BASE_ADDR, 0, 4};

26
int board_mmc_init(struct bd_info *bis)
27 28 29 30 31
{
	cl_som_imx7_usdhc1_pads_set();
	cl_som_imx7_spl_usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
	return fsl_esdhc_initialize(bis, &cl_som_imx7_spl_usdhc_cfg);
}
32
#endif /* CONFIG_FSL_ESDHC_IMX */
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

static iomux_v3_cfg_t const led_pads[] = {
	MX7D_PAD_SAI1_TX_SYNC__GPIO6_IO14 | MUX_PAD_CTRL(PAD_CTL_PUS_PU5KOHM |
		PAD_CTL_PUE | PAD_CTL_SRE_SLOW)
};

static struct ddrc cl_som_imx7_spl_ddrc_regs_val = {
	.init1		= 0x00690000,
	.init0		= 0x00020083,
	.init3		= 0x09300004,
	.init4		= 0x04080000,
	.init5		= 0x00100004,
	.rankctl	= 0x0000033F,
	.dramtmg1	= 0x0007020E,
	.dramtmg2	= 0x03040407,
	.dramtmg3	= 0x00002006,
	.dramtmg4	= 0x04020305,
	.dramtmg5	= 0x03030202,
	.dramtmg8	= 0x00000803,
	.zqctl0		= 0x00810021,
	.dfitmg0	= 0x02098204,
	.dfitmg1	= 0x00030303,
	.dfiupd0	= 0x80400003,
	.dfiupd1	= 0x00100020,
	.dfiupd2	= 0x80100004,
	.addrmap4	= 0x00000F0F,
	.odtcfg		= 0x06000604,
	.odtmap		= 0x00000001,
};

static struct ddrc_mp cl_som_imx7_spl_ddrc_mp_val = {
	.pctrl_0	= 0x00000001,
};

static struct ddr_phy cl_som_imx7_spl_ddr_phy_regs_val = {
	.phy_con0	= 0x17420F40,
	.phy_con1	= 0x10210100,
	.phy_con4	= 0x00060807,
	.mdll_con0	= 0x1010007E,
	.drvds_con0	= 0x00000D6E,
	.cmd_sdll_con0	= 0x00000010,
	.offset_lp_con0	= 0x0000000F,
};

struct mx7_calibration cl_som_imx7_spl_calib_param = {
	.num_val	= 5,
	.values		= {
		0x0E407304,
		0x0E447304,
		0x0E447306,
		0x0E447304,
		0x0E407304,
	},
};

static void cl_som_imx7_spl_dram_cfg_size(u32 ram_size)
{
	switch (ram_size) {
	case SZ_256M:
		cl_som_imx7_spl_ddrc_regs_val.mstr		= 0x01041001;
		cl_som_imx7_spl_ddrc_regs_val.rfshtmg		= 0x00400046;
		cl_som_imx7_spl_ddrc_regs_val.dramtmg0		= 0x090E1109;
		cl_som_imx7_spl_ddrc_regs_val.addrmap0		= 0x00000014;
		cl_som_imx7_spl_ddrc_regs_val.addrmap1		= 0x00151515;
		cl_som_imx7_spl_ddrc_regs_val.addrmap5		= 0x03030303;
		cl_som_imx7_spl_ddrc_regs_val.addrmap6		= 0x0F0F0303;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0	= 0x0C0C0C0C;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0	= 0x04040404;
		break;
	case SZ_512M:
		cl_som_imx7_spl_ddrc_regs_val.mstr		= 0x01040001;
		cl_som_imx7_spl_ddrc_regs_val.rfshtmg		= 0x00400046;
		cl_som_imx7_spl_ddrc_regs_val.dramtmg0		= 0x090E1109;
		cl_som_imx7_spl_ddrc_regs_val.addrmap0		= 0x00000015;
		cl_som_imx7_spl_ddrc_regs_val.addrmap1		= 0x00161616;
		cl_som_imx7_spl_ddrc_regs_val.addrmap5		= 0x04040404;
		cl_som_imx7_spl_ddrc_regs_val.addrmap6		= 0x0F0F0404;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0	= 0x0C0C0C0C;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0	= 0x04040404;
		break;
	case SZ_1G:
		cl_som_imx7_spl_ddrc_regs_val.mstr		= 0x01040001;
		cl_som_imx7_spl_ddrc_regs_val.rfshtmg		= 0x00400046;
		cl_som_imx7_spl_ddrc_regs_val.dramtmg0		= 0x090E1109;
		cl_som_imx7_spl_ddrc_regs_val.addrmap0		= 0x00000016;
		cl_som_imx7_spl_ddrc_regs_val.addrmap1		= 0x00171717;
		cl_som_imx7_spl_ddrc_regs_val.addrmap5		= 0x04040404;
		cl_som_imx7_spl_ddrc_regs_val.addrmap6		= 0x0F040404;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0	= 0x0A0A0A0A;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0	= 0x02020202;
		break;
	case SZ_2G:
		cl_som_imx7_spl_ddrc_regs_val.mstr		= 0x01040001;
		cl_som_imx7_spl_ddrc_regs_val.rfshtmg		= 0x0040005E;
		cl_som_imx7_spl_ddrc_regs_val.dramtmg0		= 0x090E110A;
		cl_som_imx7_spl_ddrc_regs_val.addrmap0		= 0x00000018;
		cl_som_imx7_spl_ddrc_regs_val.addrmap1		= 0x00181818;
		cl_som_imx7_spl_ddrc_regs_val.addrmap5		= 0x04040404;
		cl_som_imx7_spl_ddrc_regs_val.addrmap6		= 0x04040404;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_rd_con0	= 0x0A0A0A0A;
		cl_som_imx7_spl_ddr_phy_regs_val.offset_wr_con0	= 0x04040404;
		break;
	}

	mx7_dram_cfg(&cl_som_imx7_spl_ddrc_regs_val,
		     &cl_som_imx7_spl_ddrc_mp_val,
		     &cl_som_imx7_spl_ddr_phy_regs_val,
		     &cl_som_imx7_spl_calib_param);
}

static void cl_som_imx7_spl_dram_cfg(void)
{
	ulong ram_size_test, ram_size = 0;

	for (ram_size = SZ_2G; ram_size >= SZ_256M; ram_size >>= 1) {
		cl_som_imx7_spl_dram_cfg_size(ram_size);
		ram_size_test = get_ram_size((long int *)PHYS_SDRAM, ram_size);
		if (ram_size_test == ram_size)
			break;
	}

	if (ram_size < SZ_256M) {
		puts("!!!ERROR!!! DRAM detection failed!!!\n");
		hang();
	}
}

S
Simon Glass 已提交
160
#ifdef CONFIG_SPL_SPI
161 162 163 164 165

static void cl_som_imx7_spl_spi_init(void)
{
	cl_som_imx7_espi1_pads_set();
}
S
Simon Glass 已提交
166
#else /* !CONFIG_SPL_SPI */
167
static void cl_som_imx7_spl_spi_init(void) {}
S
Simon Glass 已提交
168
#endif /* CONFIG_SPL_SPI */
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

void board_init_f(ulong dummy)
{
	imx_iomux_v3_setup_multiple_pads(led_pads, 1);
	/* setup AIPS and disable watchdog */
	arch_cpu_init();
	/* setup GP timer */
	timer_init();
	cl_som_imx7_spl_spi_init();
	cl_som_imx7_uart1_pads_set();
	/* UART clocks enabled and gd valid - init serial console */
	preloader_console_init();
	/* DRAM detection  */
	cl_som_imx7_spl_dram_cfg();
	/* Clear the BSS. */
	memset(__bss_start, 0, __bss_end - __bss_start);
	/* load/boot image from boot device */
	board_init_r(NULL, 0);
}

void spl_board_init(void)
{
	u32 boot_device = spl_boot_device();

	if (boot_device == BOOT_DEVICE_SPI)
		puts("Booting from SPI flash\n");
	else if (boot_device == BOOT_DEVICE_MMC1)
		puts("Booting from SD card\n");
	else
		puts("Unknown boot device\n");
}

void board_boot_order(u32 *spl_boot_list)
{
	spl_boot_list[0] = spl_boot_device();
	switch (spl_boot_list[0]) {
	case BOOT_DEVICE_SPI:
		spl_boot_list[1] = BOOT_DEVICE_MMC1;
		break;
	case BOOT_DEVICE_MMC1:
		spl_boot_list[1] = BOOT_DEVICE_SPI;
		break;
	}
}