[U-Boot] [PATCH] imx: mx6var_som: Add support for Variscite mx6 boards
Stefano Babic
sbabic at denx.de
Thu Apr 7 06:46:04 CEST 2016
Hi Eran,
On 31/03/2016 15:53, Eran Matityahu wrote:
> Add support for Variscite VAR-SOM-MX6 / DART-MX6 / VAR-SOM-SOLO/DUAL boards with features:
> PMIC, NAND flash, SD/MMC, USB, Ethernet, I2C, LVDS, HDMI.
>
> Signed-off-by: Eran Matityahu <eran.m at variscite.com>
> ---
> arch/arm/cpu/armv7/mx6/Kconfig | 7 +
> board/variscite/mx6var_som/Kconfig | 12 +
> board/variscite/mx6var_som/MAINTAINERS | 8 +
> board/variscite/mx6var_som/Makefile | 9 +
> board/variscite/mx6var_som/addresses.inc | 38 +
> board/variscite/mx6var_som/imximage.cfg | 13 +
> board/variscite/mx6var_som/mx6var_eeprom.c | 320 +++++
> board/variscite/mx6var_som/mx6var_eeprom.h | 88 ++
> board/variscite/mx6var_som/mx6var_eeprom_v2.c | 231 ++++
> board/variscite/mx6var_som/mx6var_eeprom_v2.h | 55 +
> board/variscite/mx6var_som/mx6var_som.c | 1587 +++++++++++++++++++++++++
> board/variscite/mx6var_som/u-boot-spl.lds | 59 +
> board/variscite/mx6var_som/values.inc | 39 +
> configs/mx6var_som_nand_defconfig | 7 +
> configs/mx6var_som_sd_defconfig | 7 +
> include/configs/mx6var_som.h | 419 +++++++
> include/configs/mx6var_spl.h | 81 ++
> tools/logos/variscite.bmp | Bin 0 -> 15414 bytes
This is a very big patch, just not easy to review. Is there any
possibility to split it ? I have my difficulties to review such a
monstruous patch.
It is so big that my answer was blocked by the ML due to the size (it
exceeds 100K). I have to drop some parts to avoid the block.
Some general notes:
- SPL is automatically set. Which is the reason to have an own
imximage.cfg ? All boards use the same. You do not need to set "booting
from nand" or BOOT FROM SD", because they share the same start offset in
the storage.
- can you better explain the reason under the ddr configuration in EEPROM ?
> +endif
> diff --git a/board/variscite/mx6var_som/MAINTAINERS b/board/variscite/mx6var_som/MAINTAINERS
> new file mode 100644
> index 0000000..f3f81dd
> --- /dev/null
> +++ b/board/variscite/mx6var_som/MAINTAINERS
> @@ -0,0 +1,8 @@
> +MX6VAR_SOM BOARD
> +M: Eran Matityahu <eran.m at variscite.com>
> +S: Maintained
> +F: board/variscite/mx6var_som/
> +F: include/configs/mx6var_som.h
> +F: include/configs/mx6var_spl.h
> +F: configs/mx6var_som_nand_defconfig
> +F: configs/mx6var_som_sd_defconfig
The list must match the files you want must be added to the projects.
Just a few of them are listed here.
> diff --git a/board/variscite/mx6var_som/Makefile b/board/variscite/mx6var_som/Makefile
> new file mode 100644
> index 0000000..efa90e2
> --- /dev/null
> +++ b/board/variscite/mx6var_som/Makefile
> @@ -0,0 +1,9 @@
> +#
> +# Copyright (C) 2007, Guennadi Liakhovetski <lg at denx.de>
> +#
> +# (C) Copyright 2011 Freescale Semiconductor, Inc.
> +#
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +
> +obj-y := mx6var_som.o mx6var_eeprom.o mx6var_eeprom_v2.o
> diff --git a/board/variscite/mx6var_som/addresses.inc b/board/variscite/mx6var_som/addresses.inc
> new file mode 100644
> index 0000000..3aaea54
> --- /dev/null
> +++ b/board/variscite/mx6var_som/addresses.inc
> @@ -0,0 +1,38 @@
> +0x00000000, 0x020C4068, 0x020C406C, 0x020C4070,
> +0x021B4818, 0x021B481C, 0x021B4820, 0x021B4824,
> +0x021B4828, 0x021B482C, 0x021B4830, 0x021B4834,
> +0x021B4838, 0x021B483C, 0x021B4840, 0x021B4848,
> +0x021B4850, 0x021B485C, 0x021B4890, 0x021B48B8,
> +0x021B48BC, 0x021B48C0
I miss why it shhoul be necessary this. Indeed, they are addresses that
are saved as structures into imx6-regs.h. Why do you need your custom way ?
> diff --git a/board/variscite/mx6var_som/imximage.cfg b/board/variscite/mx6var_som/imximage.cfg
> new file mode 100644
> index 0000000..54dc449
> --- /dev/null
> +++ b/board/variscite/mx6var_som/imximage.cfg
> @@ -0,0 +1,13 @@
> +/*
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +IMAGE_VERSION 2
> +
> +#ifdef CONFIG_SYS_BOOT_NAND
> +BOOT_FROM nand
> +#else
> +BOOT_FROM sd
> +#endif
I think the file is not needed at all and you can use the general
rch/arm/imx-common/spl_sd.cfg.
> diff --git a/board/variscite/mx6var_som/mx6var_eeprom.c b/board/variscite/mx6var_som/mx6var_eeprom.c
> new file mode 100644
> index 0000000..02fedd0
> --- /dev/null
> +++ b/board/variscite/mx6var_som/mx6var_eeprom.c
> @@ -0,0 +1,320 @@
> +/*
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
I start telling you that I do not understand the meaning for
mx6var_eeprom.c and mx6var_eepromV2.c
> +#include <common.h>
> +#include <command.h>
> +#include <i2c.h>
> +#include "mx6var_eeprom.h"
> +#ifdef CONFIG_SPL_BUILD
> +#include <asm/arch/mx6-ddr.h>
> +
> +#ifdef EEPROM_DEBUG
> +#define eeprom_debug(M, ...) printf("EEPROM DEBUG: " M, ##__VA_ARGS__)
> +#else
> +#define eeprom_debug(M, ...)
> +#endif
> +
> +bool var_eeprom_is_valid(struct var_eeprom_cfg *p_var_eeprom_cfg)
> +{
> + return (VARISCITE_MAGIC == p_var_eeprom_cfg->header.variscite_magic);
> +}
> +
> +void var_eeprom_mx6dlsl_dram_setup_iomux_from_struct(struct var_pinmux_group_regs *pinmux_group)
> +{
> + volatile struct mx6sdl_iomux_ddr_regs *mx6dl_ddr_iomux;
> + volatile struct mx6sdl_iomux_grp_regs *mx6dl_grp_iomux;
> +
> + mx6dl_ddr_iomux = (struct mx6sdl_iomux_ddr_regs *) MX6SDL_IOM_DDR_BASE;
> + mx6dl_grp_iomux = (struct mx6sdl_iomux_grp_regs *) MX6SDL_IOM_GRP_BASE;
> +
> + mx6dl_grp_iomux->grp_ddr_type = (u32)pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE;
> + mx6dl_grp_iomux->grp_ddrpke = (u32)pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRPKE;
> + mx6dl_ddr_iomux->dram_sdclk_0 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_sdclk_1 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_cas = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_ras = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_grp_iomux->grp_addds = (u32)pinmux_group->pinmux_ctrlpad_all_value;
[snip}
> + mx6dl_ddr_iomux->dram_dqm1 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm2 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm3 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm4 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm5 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm6 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6dl_ddr_iomux->dram_dqm7 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> +}
I am really missing the goal for this.
> +
> +void var_eeprom_mx6qd_dram_setup_iomux_from_struct(struct var_pinmux_group_regs *pinmux_group)
> +{
> + volatile struct mx6dq_iomux_ddr_regs *mx6q_ddr_iomux;
> + volatile struct mx6dq_iomux_grp_regs *mx6q_grp_iomux;
> +
> + mx6q_ddr_iomux = (struct mx6dq_iomux_ddr_regs *) MX6DQ_IOM_DDR_BASE;
> + mx6q_grp_iomux = (struct mx6dq_iomux_grp_regs *) MX6DQ_IOM_GRP_BASE;
> +
> + mx6q_grp_iomux->grp_ddr_type = (u32)pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE;
> + mx6q_grp_iomux->grp_ddrpke = (u32)pinmux_group->IOMUXC_SW_PAD_CTL_GRP_DDRPKE;
> + mx6q_ddr_iomux->dram_sdclk_0 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_sdclk_1 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
[snip}
> + mx6q_grp_iomux->grp_b5ds = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_grp_iomux->grp_b6ds = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_grp_iomux->grp_b7ds = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm0 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm1 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm2 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm3 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm4 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm5 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm6 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> + mx6q_ddr_iomux->dram_dqm7 = (u32)pinmux_group->pinmux_ctrlpad_all_value;
> +}
Ditto.
> +
> +void var_eeprom_dram_init_from_struct(struct var_eeprom_cfg *p_var_eeprom_cfg)
> +{
> + volatile struct mmdc_p_regs *mmdc_p0 = (struct mmdc_p_regs *) MMDC_P0_BASE_ADDR;
> + u32 i;
> + u32 last;
> + u32 opcode;
> +
> + /* Go through all register initializations and apply to correct registers... */
> + i = 0;
> + last = sizeof(p_var_eeprom_cfg->write_opcodes) / sizeof(u32);
> + while ( (0 != p_var_eeprom_cfg->write_opcodes[i].address) && (i < last) ) {
> + opcode = p_var_eeprom_cfg->write_opcodes[i].address & 0xF0000000;
> + switch (opcode) {
> + case VAR_DDR_INIT_OPCODE_WRITE_VAL_TO_ADDRESS:
> + /* ZQ calibration? ==> Need to wait? */
> + if (mmdc_p0->mpzqhwctrl == p_var_eeprom_cfg->write_opcodes[i].address) {
> + if (p_var_eeprom_cfg->write_opcodes[i].value & 0x3) {
> + while (mmdc_p0->mpzqhwctrl & 0x00010000);
> + }
> + }
> + else {
> + /* write value to reg */
> + volatile u32 *reg_ptr = (volatile u32 *)p_var_eeprom_cfg->write_opcodes[i].address;
> +
> + *reg_ptr = p_var_eeprom_cfg->write_opcodes[i].value;
> + }
> + break;
> + case VAR_DDR_INIT_OPCODE_WAIT_MASK_RISING: {
> + volatile u32 *reg_ptr = (volatile u32 *)p_var_eeprom_cfg->write_opcodes[i].address;
> +
> + while ( (p_var_eeprom_cfg->write_opcodes[i].value & *reg_ptr) != \
> + p_var_eeprom_cfg->write_opcodes[i].value );
> + break;
> + }
> + case VAR_DDR_INIT_OPCODE_WAIT_MASK_FALLING: {
> + volatile u32 *reg_ptr = (volatile u32 *)p_var_eeprom_cfg->write_opcodes[i].address;
> +
> + while ( (p_var_eeprom_cfg->write_opcodes[i].value & (~(*reg_ptr)) ) != \
> + p_var_eeprom_cfg->write_opcodes[i].value );
> + break;
> + }
> + case VAR_DDR_INIT_OPCODE_DELAY_USEC:
> + udelay(p_var_eeprom_cfg->write_opcodes[i].value);
> + break;
> + default:
> + break;
> + }
> +
> + i++;
> + }
It is not that common code is not flexible: mx6<SOC>_dram_iocfg() let
set the pinmux with own setup. You replace common code with this one,
and I do not understand why.
> +
> + /* Short delay */
> + udelay(500);
> +}
> +
> +#ifdef EEPROM_DEBUG
> +static void var_eeprom_printf_array_dwords(u32 *ptr, u32 address_mem, u32 size)
> +{
> + u32 idx;
> + u32 *p_end = ptr + (size/4);
> + idx = 0;
> + while (ptr < p_end) {
> + if ((idx & 0x3) == 0) {
> + printf("\n0x%08x:", address_mem);
> + address_mem += 0x10;
> + }
> + printf(" 0x%08x", *ptr);
> + idx++;
> + ptr++;
> + }
> + printf("\n");
> +}
> +#endif
> +
> +int var_eeprom_read_struct(struct var_eeprom_cfg *p_var_eeprom_cfg)
> +{
> + int eeprom_found;
> + int ret = 0;
> + i2c_set_bus_num(1);
> + eeprom_found = i2c_probe(VAR_MX6_EEPROM_CHIP);
> + eeprom_debug("eeprom_found(0x%x)=%d\n", VAR_MX6_EEPROM_CHIP, eeprom_found);
> + if (0 == eeprom_found) {
> + eeprom_debug("EEPROM device detected, address=0x%x\n", VAR_MX6_EEPROM_CHIP);
> +
> + if (i2c_read(VAR_MX6_EEPROM_CHIP, VAR_MX6_EEPROM_STRUCT_OFFSET, \
> + 1, (uchar *)p_var_eeprom_cfg, sizeof(struct var_eeprom_cfg))) {
> + eeprom_debug("Read device ID error!\n");
> + return -1;
> + } else {
> + /* Success */
> +#ifdef EEPROM_DEBUG
> + var_eeprom_printf_array_dwords((u32 *) p_var_eeprom_cfg, (u32) 0, \
> + sizeof(struct var_eeprom_cfg));
> +#endif
> + }
> + } else {
> + eeprom_debug("Error! Couldn't find EEPROM device\n");
> + }
> +
> + return ret;
> +}
> +#endif /* CONFIG_SPL_BUILD */
> +
> +void var_eeprom_strings_print(struct var_eeprom_cfg *p_var_eeprom_cfg)
> +{
> + p_var_eeprom_cfg->header.part_number[sizeof(p_var_eeprom_cfg->header.part_number)-1] = (u8)0x00;
> + p_var_eeprom_cfg->header.Assembly[sizeof(p_var_eeprom_cfg->header.Assembly)-1] = (u8)0x00;
> + p_var_eeprom_cfg->header.date[sizeof(p_var_eeprom_cfg->header.date)-1] = (u8)0x00;
> +
> + printf("Part number: %s\n", (char *)p_var_eeprom_cfg->header.part_number);
> + printf("Assembly: %s\n", (char *)p_var_eeprom_cfg->header.Assembly);
> + printf("Date of production: %s\n", (char *)p_var_eeprom_cfg->header.date);
> +}
> +
> +static int var_eeprom_write(uchar *ptr, u32 size, u32 offset)
> +{
> + int ret = 0;
> + u32 size_written;
> + u32 size_to_write;
> + u32 P0_select_page_EEPROM;
> + u32 chip;
> + u32 addr;
> +
> + /* Write to EEPROM device */
> + size_written = 0;
> + size_to_write = size;
> + while ((0 == ret) && (size_written < size_to_write)) {
> + P0_select_page_EEPROM = (offset > 0xFF);
> + chip = VAR_MX6_EEPROM_CHIP + P0_select_page_EEPROM;
> + addr = (offset & 0xFF);
> + ret = i2c_write(chip, addr, 1, ptr, VAR_MX6_EEPROM_WRITE_MAX_SIZE);
> +
> + /* Wait for EEPROM write operation to complete (No ACK) */
> + mdelay(11);
> +
> + size_written += VAR_MX6_EEPROM_WRITE_MAX_SIZE;
> + offset += VAR_MX6_EEPROM_WRITE_MAX_SIZE;
> + ptr += VAR_MX6_EEPROM_WRITE_MAX_SIZE;
> + }
> +
> + return ret;
> +}
There is eprom_read() and eprom_write() from cmd/eeprom.c. Does it not
work in your case ?
> +
> +/*
> + * vareeprom command intepreter.
> + */
> +static int do_var_eeprom_params(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> + struct var_eeprom_cfg var_eeprom_cfg;
> + int offset;
> +
> + if (argc != 4)
> + return -1;
> +
> + memset(&var_eeprom_cfg, 0x00, sizeof(var_eeprom_cfg));
> +
> + memcpy(&var_eeprom_cfg.header.part_number[0], argv[1], sizeof(var_eeprom_cfg.header.part_number));
> + memcpy(&var_eeprom_cfg.header.Assembly[0], argv[2], sizeof(var_eeprom_cfg.header.Assembly));
> + memcpy(&var_eeprom_cfg.header.date[0], argv[3], sizeof(var_eeprom_cfg.header.date));
> +
> + var_eeprom_strings_print(&var_eeprom_cfg);
> +
> + offset = (uchar *)&var_eeprom_cfg.header.part_number[0] - (uchar *)&var_eeprom_cfg.header;
> + if (var_eeprom_write((uchar *)&var_eeprom_cfg.header.part_number[0], \
> + sizeof(var_eeprom_cfg.header.part_number), \
> + VAR_MX6_EEPROM_STRUCT_OFFSET + offset) ) {
> + printf("Error writing to EEPROM!\n");
> + return -1;
> + }
> +
> + offset = (uchar *)&var_eeprom_cfg.header.Assembly[0] - (uchar *)&var_eeprom_cfg;
> + if (var_eeprom_write((uchar *)&var_eeprom_cfg.header.Assembly[0], \
> + sizeof(var_eeprom_cfg.header.Assembly), \
> + VAR_MX6_EEPROM_STRUCT_OFFSET + offset) ) {
> + printf("Error writing to EEPROM!\n");
> + return -1;
> + }
> +
> + offset = (uchar *)&var_eeprom_cfg.header.date[0] - (uchar *)&var_eeprom_cfg;
> + if (var_eeprom_write((uchar *)&var_eeprom_cfg.header.date[0], \
> + sizeof(var_eeprom_cfg.header.date), \
> + VAR_MX6_EEPROM_STRUCT_OFFSET + offset) ) {
> + printf("Error writing to EEPROM!\n");
> + return -1;
> + }
> +
> + printf("EEPROM updated successfully\n");
> +
> + return 0;
> +}
> +
> +U_BOOT_CMD(
> + vareeprom, 5, 1, do_var_eeprom_params,
> + "For internal use only",
> + "- Do not use"
> +);
> diff --git a/board/variscite/mx6var_som/mx6var_eeprom.h b/board/variscite/mx6var_som/mx6var_eeprom.h
> new file mode 100644
> index 0000000..5c70a27
> --- /dev/null
> +++ b/board/variscite/mx6var_som/mx6var_eeprom.h
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef _MX6VAR_EEPROM_H_
> +#define _MX6VAR_EEPROM_H_
> +
> +#define VARISCITE_MAGIC 0x49524157 /* == HEX("VARI")*/
> +
> +#define VAR_MX6_EEPROM_CHIP 0x56
> +#define VAR_DART_EEPROM_CHIP 0x52
> +
> +#define VAR_MX6_EEPROM_STRUCT_OFFSET 0x00000000
> +
> +#define VAR_MX6_EEPROM_WRITE_MAX_SIZE 0x4
> +
> +#define EEPROM_SIZE_BYTES 512
> +
> +#define VAR_DDR_INIT_OPCODE_WRITE_VAL_TO_ADDRESS 0x00000000
> +#define VAR_DDR_INIT_OPCODE_WAIT_MASK_RISING 0x10000000
> +#define VAR_DDR_INIT_OPCODE_WAIT_MASK_FALLING 0x20000000
> +#define VAR_DDR_INIT_OPCODE_DELAY_USEC 0x30000000
> +
> +#define SPL_DRAM_INIT_STATUS_OK 0
> +#define SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM 1
> +#define SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM_STRUCT_DETECTED 2
> +
> +struct var_eeprom_cfg_header
> +{
> + u32 variscite_magic; /* == HEX("VARI")?*/
> + u8 part_number[16];
> + u8 Assembly[16];
> + u8 date[16];
> + u8 version;
> + u8 reserved[7];
> + u32 ddr_size;
> +};
> +
> +struct var_pinmux_group_regs
> +{
> + u32 IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE;
> + u32 IOMUXC_SW_PAD_CTL_GRP_DDRPKE;
> + u32 IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL;
> + u32 IOMUXC_SW_PAD_CTL_GRP_DDRMODE;
> + u32 IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2;
> + u32 dram_reset;
> + u32 dram_sdcke0;
> + u32 dram_sdcke1;
> + u32 dram_sdodt0;
> + u32 dram_sdodt1;
> + u32 reserved;
> + u32 pinmux_ctrlpad_all_value;
> +};
> +
> +struct reg_write_opcode
> +{
> + u32 address; /* address encoded with opcode */
> + u32 value;
> +};
> +
> +struct var_eeprom_cfg
> +{
> + struct var_eeprom_cfg_header header;
> + struct var_pinmux_group_regs pinmux_group;
> + struct reg_write_opcode write_opcodes[ \
> + (EEPROM_SIZE_BYTES \
> + - sizeof(struct var_eeprom_cfg_header) \
> + - sizeof(struct var_pinmux_group_regs)) \
> + / sizeof(struct reg_write_opcode) ];
> +};
> +
> +bool var_eeprom_is_valid(struct var_eeprom_cfg *p_var_eeprom_cfg);
> +
> +/* init ddr iomux from struct */
> +void var_eeprom_mx6dlsl_dram_setup_iomux_from_struct(struct var_pinmux_group_regs *pinmux_group);
> +
> +void var_eeprom_mx6qd_dram_setup_iomux_from_struct(struct var_pinmux_group_regs *pinmux_group);
> +
> +/* init ddr from struct */
> +void var_eeprom_dram_init_from_struct(struct var_eeprom_cfg *p_var_eeprom_cfg);
> +
> +int var_eeprom_read_struct(struct var_eeprom_cfg *p_var_eeprom_cfg);
> +
> +void var_eeprom_strings_print(struct var_eeprom_cfg *p_var_eeprom_cfg);
> +
> +#endif /* _MX6VAR_EEPROM_H_ */
> diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v2.c b/board/variscite/mx6var_som/mx6var_eeprom_v2.c
> new file mode 100644
> index 0000000..490b470
> --- /dev/null
> +++ b/board/variscite/mx6var_som/mx6var_eeprom_v2.c
> @@ -0,0 +1,231 @@
> +/*
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifdef CONFIG_SPL_BUILD
> +#include <common.h>
> +#include <i2c.h>
> +#include "mx6var_eeprom_v2.h"
> +
> +#ifdef EEPROM_V2_DEBUG
> +#define eeprom_v2_debug(M, ...) printf("EEPROM_V2 DEBUG: " M, ##__VA_ARGS__)
> +#else
> +#define eeprom_v2_debug(M, ...)
> +#endif
> +
> +static u32 get_address_by_index(unsigned char index, u32 *ram_addresses);
> +static u32 get_value_by_index(unsigned char index, u32 *ram_values);
> +static int handle_one_command(struct eeprom_command *eeprom_commands,int command_num, \
> + u32 *ram_addresses, u32 *ram_values);
> +
> +
> +bool var_eeprom_v2_is_valid(struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg)
> +{
> + return (VARISCITE_MAGIC_V2 == p_var_eeprom_v2_cfg->variscite_magic);
> +}
> +
> +
> +void var_eeprom_v2_strings_print(struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg)
[snip]
> +}
> +
> +
> +static int handle_one_command(struct eeprom_command *eeprom_commands, int command_num, \
> + u32 *ram_addresses, u32 *ram_values)
> +{
> + volatile u32 *data;
> + u32 address;
> + u32 value;
> +
> + eeprom_v2_debug("Executing command %03d: %03d, %03d\n",
> + command_num,
> + eeprom_commands[command_num].address_index,
> + eeprom_commands[command_num].value_index);
> +
> + switch(eeprom_commands[command_num].address_index) {
> + case WHILE_NOT_EQUAL_INDEX:
> + command_num++;
> + address=get_address_by_index(eeprom_commands[command_num].address_index, ram_addresses);
> + value=get_value_by_index(eeprom_commands[command_num].value_index, ram_values);
> + data=(u32*)address;
> + eeprom_v2_debug("Waiting while data at address %08x is not equal %08x\n", address, value);
> +
> + while(data[0]!=value);
> +
> + command_num++;
> + break;
> + case WHILE_EQUAL_INDEX:
> + command_num++;
> + address=get_address_by_index(eeprom_commands[command_num].address_index, ram_addresses);
> + value=get_value_by_index(eeprom_commands[command_num].value_index, ram_values);
> + data=(u32*)address;
> + eeprom_v2_debug("Waiting while data at address %08x is equal %08x\n", address, value);
> +
> + while(data[0]==value);
> +
> + command_num++;
> + break;
> + case WHILE_AND_INDEX:
> + command_num++;
> + address=get_address_by_index(eeprom_commands[command_num].address_index, ram_addresses);
> + value=get_value_by_index(eeprom_commands[command_num].value_index, ram_values);
> + data=(u32*)address;
> + eeprom_v2_debug("Waiting while data at address %08x and %08x is not zero\n", address, value);
> +
> + while(data[0]&value);
> +
> + command_num++;
> + break;
> + case WHILE_NOT_AND_INDEX:
> + command_num++;
> + address=get_address_by_index(eeprom_commands[command_num].address_index, ram_addresses);
> + value=get_value_by_index(eeprom_commands[command_num].value_index, ram_values);
> + data=(u32*)address;
> + eeprom_v2_debug("Waiting while data at address %08x and %08x is zero\n", address, value);
> +
> + while(!(data[0]&value));
Code is quite confusing - it does quite the same thing, and can be
rewritten factorizing most part.
> +
> + command_num++;
> + break;
> + case DELAY_10USEC_INDEX:
> + /* Delay for Value * 10 uSeconds */
> + eeprom_v2_debug("Delaying for %d microseconds\n", eeprom_commands[command_num].value_index*10);
> + udelay((int)(eeprom_commands[command_num].value_index*10));
> + command_num++;
> + break;
> + case LAST_COMMAND_INDEX:
> + command_num=0;
> + break;
> + default:
> + address=get_address_by_index(eeprom_commands[command_num].address_index, ram_addresses);
> + value=get_value_by_index(eeprom_commands[command_num].value_index, ram_values);
> + data=(u32*)address;
> + eeprom_v2_debug("Setting data at address %08x to %08x\n", address, value);
> + data[0]=value;
> + command_num++;
> + break;
> + }
> +
> + return command_num;
> +}
> +
> +
> +static u32 get_address_by_index(unsigned char index, u32 *ram_addresses)
> +{
> + /*
> + * DDR Register struct
> + * The eeprom contains a structure of:
> + * 1 byte index in this addresses table, and
> + * 1 byte index to common values in the next table - to write to this address.
> + * If there are new addresses from the calibration program,
> + * they should be added to the end of the array.
> + * The maximum array size is 256 addresses.
> + */
> + const u32 rom_addresses[]=
> + {
> + #include "addresses.inc"
> + };
> +
> + if (index >= MAXIMUM_ROM_ADDR_INDEX)
> + return ram_addresses[index-MAXIMUM_ROM_ADDR_INDEX];
> +
> + return rom_addresses[index];
> +}
> +
> +
> +static u32 get_value_by_index(unsigned char index, u32 *ram_values)
> +{
> + const u32 rom_values[] =
> + {
> + #include "values.inc"
> + };
> +
> + if (index >= MAXIMUM_ROM_VALUE_INDEX)
> + return ram_values[index-MAXIMUM_ROM_VALUE_INDEX];
> +
> + return rom_values[index];
> +}
> +
> +
> +int var_eeprom_v2_read_struct(struct var_eeprom_v2_cfg *var_eeprom_v2_cfg, \
> + unsigned char address)
> +{
> + int eeprom_found = i2c_probe(address);
> + if (0 == eeprom_found) {
> + if (i2c_read(address, 0, 1, (void*) var_eeprom_v2_cfg, \
> + sizeof(struct var_eeprom_v2_cfg))) {
> + printf("Read device ID error!\n");
> + return -1;
> + }
> + } else {
> + printf("Error! Couldn't find EEPROM device\n");
> + }
> + return 0;
> +}
As I said, I have not understood at all the reason for that.
> +#endif
> diff --git a/board/variscite/mx6var_som/mx6var_eeprom_v2.h b/board/variscite/mx6var_som/mx6var_eeprom_v2.h
> new file mode 100644
> index 0000000..cebf46d
> --- /dev/null
> +++ b/board/variscite/mx6var_som/mx6var_eeprom_v2.h
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef _MX6VAR_V2_EEPROM_H_
> +#define _MX6VAR_V2_EEPROM_H_
> +
> +#define VARISCITE_MAGIC_V2 0x32524156 /* == HEX("VAR2") */
> +
> +#define MAXIMUM_ROM_ADDR_INDEX 200
> +#define MAXIMUM_ROM_VALUE_INDEX 200
> +#define WHILE_NOT_EQUAL_INDEX 241
> +#define WHILE_EQUAL_INDEX 242
> +#define WHILE_AND_INDEX 243
> +#define WHILE_NOT_AND_INDEX 244
> +#define DELAY_10USEC_INDEX 245
> +#define LAST_COMMAND_INDEX 255
> +
> +#define MAXIMUM_RAM_ADDRESSES 32
> +#define MAXIMUM_RAM_VALUES 32
> +
> +#define MAXIMUM_COMMANDS_NUMBER 150
> +
> +struct __attribute__((packed)) eeprom_command
> +{
> + unsigned char address_index;
> + unsigned char value_index;
> +};
> +
> +struct __attribute__((packed)) var_eeprom_v2_cfg
> +{
> + u32 variscite_magic; /* == HEX("VAR2")? */
> + u8 part_number[16];
> + u8 Assembly[16];
> + u8 date[12];
> + u32 custom_addresses_values[32];
> + struct eeprom_command eeprom_commands[MAXIMUM_COMMANDS_NUMBER];
> + u8 reserved[34];
> + u8 ddr_size;
> + u8 crc;
> +};
> +
> +bool var_eeprom_v2_is_valid(struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg);
> +void var_eeprom_v2_strings_print(struct var_eeprom_v2_cfg *p_var_eeprom_v2_cfg);
> +int handle_eeprom_data(struct var_eeprom_v2_cfg *var_eeprom_v2_cfg, \
> + u32 *ram_addresses, u32 *ram_values);
> +int setup_ddr_parameters(struct eeprom_command *eeprom_commands, \
> + u32 *ram_addresses, u32 *ram_values);
> +void load_custom_data(u32 *custom_addresses_values, u32 *ram_addresses, u32 *ram_values);
> +int var_eeprom_v2_read_struct(struct var_eeprom_v2_cfg *var_eeprom_v2_cfg, \
> + unsigned char address);
> +
> +#endif /* _MX6VAR_V2_EEPROM_H_ */
> diff --git a/board/variscite/mx6var_som/mx6var_som.c b/board/variscite/mx6var_som/mx6var_som.c
> new file mode 100644
> index 0000000..e99690b
> --- /dev/null
> +++ b/board/variscite/mx6var_som/mx6var_som.c
> @@ -0,0 +1,1587 @@
> +/*
> + * Copyright (C) 2012 Freescale Semiconductor, Inc.
> + * Author: Fabio Estevam <fabio.estevam at freescale.com>
> + *
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * Author: Eran Matityahu <eran.m at variscite.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <asm/arch/clock.h>
> +#include <asm/arch/imx-regs.h>
> +#include <asm/arch/iomux.h>
> +#include <malloc.h>
> +#include <asm/arch/mx6-pins.h>
> +#include <asm/errno.h>
> +#include <asm/gpio.h>
> +#include <asm/imx-common/mxc_i2c.h>
> +#include <asm/imx-common/iomux-v3.h>
> +#include <asm/imx-common/boot_mode.h>
> +#include <asm/imx-common/video.h>
> +#include <mmc.h>
> +#include <fsl_esdhc.h>
> +#include <micrel.h>
> +#include <miiphy.h>
> +#include <netdev.h>
> +#include <asm/arch/mxc_hdmi.h>
> +#include <asm/arch/crm_regs.h>
> +#include <asm/io.h>
> +#include <asm/arch/sys_proto.h>
> +#include <i2c.h>
> +#include <power/pmic.h>
> +#include <power/pfuze100_pmic.h>
> +#include <usb.h>
> +#include <usb/ehci-fsl.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
> + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
> + PAD_CTL_SRE_FAST | PAD_CTL_HYS)
> +
> +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
> + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
> + PAD_CTL_SRE_FAST | PAD_CTL_HYS)
> +
> +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
> + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
> +
> +#define GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
> +#define GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | \
> + PAD_CTL_SRE_FAST)
> +#define GPMI_PAD_CTRL2 (GPMI_PAD_CTRL0 | GPMI_PAD_CTRL1)
> +
> +#define PER_VCC_EN_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
> + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
> + PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
> +
> +#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
> + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
> + PAD_CTL_ODE | PAD_CTL_SRE_FAST)
> +
> +#define OTG_ID_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
> + PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
> + PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
> +
> +
> +#define VAR_SOM_BACKLIGHT_EN IMX_GPIO_NR(4, 30)
> +
> +bool lvds_enabled=false;
> +
> +#ifdef CONFIG_SYS_USE_NAND
> +static int var_load_file_from_nand(u32 addr, char *filename)
> +{
> + extern int ubi_part(char *part_name, const char *vid_header_offset);
> + extern int ubifs_init(void);
> + extern int uboot_ubifs_mount(char *vol_name);
> + extern int ubifs_load(char *filename, u32 addr, u32 size);
> + extern void cmd_ubifs_umount(void);
> +
> + char *ubi_part_name = "rootfs";
> + char *ubifs_vol_name = "ubi0:rootfs";
> +
> + if (ubi_part(ubi_part_name, NULL))
> + return -1;
> + if (ubifs_init())
> + return -1;
> + if (uboot_ubifs_mount(ubifs_vol_name))
> + return -1;
> +
> + /* Load the file to memory */
> + if (ubifs_load(filename, addr, 0)) {
> + printf("Error: splash file not found %s\n", filename);
> + cmd_ubifs_umount();
> + return -1;
> + }
> + cmd_ubifs_umount();
Why ? All this stuff can be done in a much more flexible way scripts in
the environment. It should be not hard-coded.
> + return 0;
> +}
> +#endif
> +
> +static int var_load_file_from_mmc(u32 addr, char *filename)
> +{
> +#define FS_TYPE_EXT 2
> + extern int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype);
> + extern int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
> + loff_t *actread);
> +
> + loff_t len_read;
> +
> +#ifdef CONFIG_SYS_USE_NAND
> + if (fs_set_blk_dev("mmc", "1:1", FS_TYPE_EXT))
> + return -1;
> +#else
> + if (fs_set_blk_dev("mmc", "0:2", FS_TYPE_EXT))
> + return -1;
> +#endif
> +
> + if (fs_read(filename, addr, 0, 0, &len_read)) {
> + printf("Error: splash file not found %s\n", filename);
> + return -1;
> + }
> +
> + printf("%llu bytes read\n", len_read);
> + return 0;
> +#undef FS_TYPE_EXT
> +}
I disagree - the logic should be not bound with the code. There is not
such a way in U-Boot. Boards rely on the environment, and the hush shell
does the rest, without hardcoding this into the board.
This behavior is also wrong for another reason: this drives crazy anyone
working with the shell. In fact, he can assume to define the behaviour
using the environment, but this is overwritten by your code.
> +
> +#ifdef CONFIG_SPLASH_SCREEN
> +int splash_screen_prepare(void)
> +{
> + char *filename;
> + const char *addr_str;
> + u32 addr = 0;
> +#ifdef CONFIG_SYS_USE_NAND
> + char *s;
> +#endif
> +
> + /* Get filename and load address from env */
> + addr_str = getenv("splashimage");
> + if (!addr_str) {
> + return -1;
> + }
> + addr = simple_strtoul(addr_str, 0, 16);
> + if (addr == 0) {
> + printf("Error: bad splashimage value %s\n", addr_str);
> + return -1;
> + }
> + filename = getenv("splash_filename");
> + if (!filename) {
> + printf("Error: splashimage defined, but splash_filename isn't\n");
> + return -1;
> + }
> +
> +#ifdef CONFIG_SYS_USE_NAND
> + s = getenv("chosen_rootfs");
> + if ((s != NULL) && (!strcmp(s, "emmc"))) {
> + if (var_load_file_from_mmc(addr, filename))
> + return -1;
> + } else {
> + if (var_load_file_from_nand(addr, filename))
> + return -1;
> + }
Ditto. All this logic must be not part of code.
> +#else /* MMC */
> + if (var_load_file_from_mmc(addr, filename))
> + return -1;
> +#endif
> +
> + /* Turn on backlight */
> + if (lvds_enabled)
> + gpio_set_value(VAR_SOM_BACKLIGHT_EN, 1);
And hardware-related part, as this one for backlight, are mixed with
behaviour parts (setting rootfs, for example).
> +
> + return 0;
> +}
> +#endif
> +
> +static bool is_som_solo(void)
> +{
> + bool ret;
> + int oldbus = i2c_get_bus_num();
> +
> + i2c_set_bus_num(PMIC_I2C_BUS);
> + /* Probing for PMIC which is not preset only on som solo */
> + ret = (0 != i2c_probe(CONFIG_POWER_PFUZE100_I2C_ADDR));
> +
> + i2c_set_bus_num(oldbus);
> + return ret;
If I understand from the title, you want to check if the CPU is a Solo
or DL. But then, instead of reading the CPU-ID, as we expect, you check
if you have a PMIC. It looks not straightforward.
> +}
> +
> +static bool is_solo_custom_board(void)
> +{
> + bool ret;
> + int oldbus = i2c_get_bus_num();
> +
> + i2c_set_bus_num(1);
> + /* Probing for extra EEPROM present only on solo custom board */
> + ret = (0 == i2c_probe(0x51));
> +
> + i2c_set_bus_num(oldbus);
> + return ret;
> +}
> +
> +static bool is_cpu_pop_package(void)
> +{
> + uint soc_sbmr = readl(SRC_BASE_ADDR + 0x4);
> + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
> + u32 reg;
> + u32 type;
> +
> + reg = readl(&anatop->digprog);
> + type = ((reg >> 16) & 0xff);
> + if (type != MXC_CPU_MX6DL)
> + return ((soc_sbmr & 0x200000) != 0);
There are a lot of is_cpu_type() to check for SOC type.
> + return false;
> +}
> +
> +static inline bool is_dart_board(void)
> +{
> + return is_cpu_pop_package();
> +}
> +
> +static inline bool is_mx6_custom_board(void)
> +{
> + return (!is_dart_board() && !is_solo_custom_board());
> +}
I do not know your board, but the way to select if this is the
evaluation board or a custom board seems to me arguable.
> +
> +enum mmc_boot_device {
> + SD_BOOT,
> + MMC_BOOT,
> + OTHER_BOOT,
> +};
> +
> +static unsigned get_mmc_boot_device(void)
> +{
> + struct src *psrc = (struct src *)SRC_BASE_ADDR;
> + unsigned reg = (readl(&psrc->sbmr1) >> 5) & 0x7;
> +
> + switch(reg) {
> + case 0x2:
> + return SD_BOOT;
> + case 0x3:
> + return MMC_BOOT;
> + default:
> + return OTHER_BOOT;
> + }
> +}
> +
> +static bool is_mmc_present(struct mmc *mmc)
> +{
> + int err;
> + struct mmc_cmd cmd;
> +
> + if (mmc->has_init)
> + return true;
> +
> + mdelay(1);
> + cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
> + cmd.cmdarg = 0;
> + cmd.resp_type = MMC_RSP_NONE;
> +
> + err = mmc->cfg->ops->send_cmd(mmc, &cmd, NULL);
> + if (err)
> + return false;
> +
> + mdelay(2);
> +
> + cmd.cmdidx = MMC_CMD_SEND_OP_COND;
> + cmd.resp_type = MMC_RSP_R3;
> + cmd.cmdarg = 0;
> +
> + err = mmc->cfg->ops->send_cmd(mmc, &cmd, NULL);
> + return (!err);
> +}
No idea for that, this is already managed, including error branches, by
common code in the MMC subsystem.
> +
> +static void print_emmc_size(void)
> +{
> + struct mmc *mmc;
> + int device;
> +
> + if (is_dart_board() && (MMC_BOOT == get_mmc_boot_device()))
> + device=0;
> + else
> + device=1;
This is another place where mmc order is set, leading to further confusion.
> +
> + mmc = find_mmc_device(device);
> + if (!mmc || !is_mmc_present(mmc) || mmc_init(mmc) || IS_SD(mmc)) {
> + puts("No eMMC\n");
> + return;
> + }
> + puts("eMMC: ");
> + print_size(mmc->capacity, "\n");
> +}
> +
> +static u32 var_ram_size(void)
> +{
> + u32 *p_ram_size = (u32 *)RAM_SIZE_ADDR;
> + return *p_ram_size;
> +}
> +
> +int dram_init(void)
> +{
> + gd->ram_size = var_ram_size() * 1024 * 1024;
> + return 0;
> +}
This is not the correct way to do it. U-Boot can detect the RAM on board
using get_ram_size(). You have a var_rime_size() function, but this does
not detect anything a returns a value defined at compiled time. Use
get_ram_size() instead.
> +
> +static iomux_v3_cfg_t const uart1_pads[] = {
> + IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
> + IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
> +};
> +
> +static iomux_v3_cfg_t const enet_pads1[] = {
> + IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + /* pin 35 - 1 (PHY_AD2) on reset */
> + IOMUX_PADS(PAD_RGMII_RXC__GPIO6_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* pin 32 - 1 - (MODE0) all */
> + IOMUX_PADS(PAD_RGMII_RD0__GPIO6_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* pin 31 - 1 - (MODE1) all */
> + IOMUX_PADS(PAD_RGMII_RD1__GPIO6_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* pin 28 - 1 - (MODE2) all */
> + IOMUX_PADS(PAD_RGMII_RD2__GPIO6_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* pin 27 - 1 - (MODE3) all */
> + IOMUX_PADS(PAD_RGMII_RD3__GPIO6_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
> + IOMUX_PADS(PAD_RGMII_RX_CTL__GPIO6_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> + /* AR8031 PHY Reset */
> + IOMUX_PADS(PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL)),
> +};
> +
> +static iomux_v3_cfg_t const enet_pads2[] = {
> + IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> + IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL)),
> +};
> +
> +static void setup_iomux_enet(void)
> +{
> + gpio_direction_output(IMX_GPIO_NR(1, 25), 0); /* Variscite SOM PHY reset */
> + gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
> + gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
> + gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
> + gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
> + gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
> +
> + SETUP_IOMUX_PADS(enet_pads1);
> +
> + gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
> +
> + /* Need delay 10ms according to KSZ9021 spec */
> + mdelay(10);
> + gpio_set_value(IMX_GPIO_NR(1, 25), 1);
> +
> + SETUP_IOMUX_PADS(enet_pads2);
> +}
> +
> +static iomux_v3_cfg_t const usdhc1_pads[] = {
> + IOMUX_PADS(PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> +};
> +
> +
> +static iomux_v3_cfg_t const usdhc2_pads[] = {
> + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> +};
> +
> +static iomux_v3_cfg_t const usdhc3_pads[] = {
> + IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> + IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
> +};
> +
> +#ifdef CONFIG_SYS_I2C_MXC
> +I2C_PADS(i2c_pad_info1,
> + PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_CSI0_DAT9__GPIO5_IO27 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(5, 27),
> + PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_CSI0_DAT8__GPIO5_IO26 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(5, 26));
> +
> +I2C_PADS(i2c_pad_info2,
> + PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(4, 12),
> + PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(4, 13));
> +
> +I2C_PADS(i2c_pad_info3,
> + PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_GPIO_5__GPIO1_IO05 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(1, 5),
> + PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + PAD_GPIO_16__GPIO7_IO11 | MUX_PAD_CTRL(I2C_PAD_CTRL),
> + IMX_GPIO_NR(7, 11));
> +#endif
> +
> +void setup_local_i2c(void) {
> + setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info1));
> + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info2));
> + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, I2C_PADS_INFO(i2c_pad_info3));
> +}
> +
> +iomux_v3_cfg_t const di0_pads[] = {
> + IOMUX_PADS(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK), /* DISP0_CLK */
> + IOMUX_PADS(PAD_DI0_PIN2__IPU1_DI0_PIN02), /* DISP0_HSYNC */
> + IOMUX_PADS(PAD_DI0_PIN3__IPU1_DI0_PIN03), /* DISP0_VSYNC */
> +};
> +
Just these three pins for display ? Where are set the other ones ?
> +static void var_setup_iomux_per_vcc_en(void)
> +{
> + SETUP_IOMUX_PAD(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(PER_VCC_EN_PAD_CTRL));
> + gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
> +}
> +
> +static void setup_iomux_uart(void)
> +{
> + SETUP_IOMUX_PADS(uart1_pads);
> +}
> +
> +#ifdef CONFIG_FSL_ESDHC
> +struct fsl_esdhc_cfg usdhc_cfg[2] = {
> + /*
> + * This is incorrect for DART board but it's overwritten
> + * in board_mmc_init() according to board setup
> + */
> + {USDHC2_BASE_ADDR},
> + {USDHC1_BASE_ADDR},
> +};
> +
> +int board_mmc_getcd(struct mmc *mmc)
> +{
> + return 1;
> +}
I do not understand is_mmc_present() at all. U-Boot mmc subsystem sends
already the commands to get if a mmc is present. You fix
board_mmc_getcd(), but you have your own method instead of rely on
common code.
> +
> +int board_mmc_init(bd_t *bis)
> +{
> +#ifndef CONFIG_SPL_BUILD
> + int ret;
> + int i;
> +
> + /*
> + * According to the board_mmc_init() the following map is done:
> + * (U-Boot device node) (Physical Port)
> + * On non DART boards:
> + * mmc0 SD2 (SD)
> + * mmc1 SD1 (eMMC)
> + *
> + * On DART board when booting from SD:
> + * mmc0 SD2 (SD)
> + * mmc1 SD3 (eMMC)
> + *
> + * On DART board when booting from eMMC:
> + * mmc0 SD3 (eMMC)
> + * mmc1 SD2 (SD)
> + */
Why do you need to redefine the order depending from the boot device ?
This makes things complicated and very confusing. Is it not much better
to maintain the same enumeration ?
> + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
> + switch (i) {
> + case 0:
> + if (is_dart_board() && (MMC_BOOT == get_mmc_boot_device())) {
> + SETUP_IOMUX_PADS(usdhc3_pads);
> + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
> + } else {
> + SETUP_IOMUX_PADS(usdhc2_pads);
> + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
> + }
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + usdhc_cfg[0].max_bus_width = 4;
> + break;
> + case 1:
> + if (is_dart_board() && (MMC_BOOT == get_mmc_boot_device())) {
> + SETUP_IOMUX_PADS(usdhc2_pads);
> + usdhc_cfg[1].esdhc_base = USDHC2_BASE_ADDR;
> + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
> + } else if (is_dart_board()) {
> + SETUP_IOMUX_PADS(usdhc3_pads);
> + usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR;
> + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
> + } else {
> + SETUP_IOMUX_PADS(usdhc1_pads);
> + usdhc_cfg[1].esdhc_base = USDHC1_BASE_ADDR;
> + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
> + }
> + gd->arch.sdhc_clk = usdhc_cfg[1].sdhc_clk;
> + usdhc_cfg[1].max_bus_width = 4;
> + break;
> + default:
> + printf("Warning: you configured more USDHC controllers"
> + "(%d) then supported by the board (%d)\n",
> + i + 1, CONFIG_SYS_FSL_USDHC_NUM);
> + return -EINVAL;
> + }
> +
> + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
> + if (ret)
> + return ret;
> + }
> + return 0;
> +#else
> + struct src *psrc = (struct src *)SRC_BASE_ADDR;
> + unsigned reg = readl(&psrc->sbmr1) >> 11;
> + /*
> + * Upon reading BOOT_CFG register the following map is done:
> + * Bit 11 and 12 of BOOT_CFG register can determine the current
> + * mmc port
> + * 0x1 SD2 (SD)
> + * 0x2 SD3 (DART eMMC)
> + */
> +
> + switch (reg & 0x3) {
> + case 0x1:
> + SETUP_IOMUX_PADS(usdhc2_pads);
> + usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + usdhc_cfg[0].max_bus_width = 4;
> + break;
> + case 0x2:
> + SETUP_IOMUX_PADS(usdhc3_pads);
> + usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
> + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
> + gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
> + usdhc_cfg[0].max_bus_width = 4;
> + break;
> + }
> +
> + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
> +#endif
> +}
> +#endif
> +
> +#ifdef CONFIG_SYS_USE_NAND
> +static iomux_v3_cfg_t const gpmi_pads[] = {
> + IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(GPMI_PAD_CTRL0)),
> + IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(GPMI_PAD_CTRL2)),
> + IOMUX_PADS(PAD_SD4_DAT0__NAND_DQS | MUX_PAD_CTRL(GPMI_PAD_CTRL1)),
> +};
> +
> +static void setup_gpmi_nand(void)
> +{
> + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +
> + SETUP_IOMUX_PADS(gpmi_pads);
> +
> + /* gate ENFC_CLK_ROOT clock first,before clk source switch */
> + clrbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
> +
> + /* config gpmi and bch clock to 100 MHz */
> + clrsetbits_le32(&mxc_ccm->cs2cdr,
> + MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
> + MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
> + MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
> + MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
> + MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
> + MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
> +
> + /* enable ENFC_CLK_ROOT clock */
> + setbits_le32(&mxc_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
> +
> + /* enable gpmi and bch clock gating */
> + setbits_le32(&mxc_ccm->CCGR4,
> + MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
> + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
> + MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
> + MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
> + MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
> +
> + /* enable apbh clock gating */
> + setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
> +}
> +#endif
> +
> +int board_phy_config(struct phy_device *phydev)
> +{
> + /* min rx data delay */
> + ksz9021_phy_extended_write(phydev,
> + MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
> + /* min tx data delay */
> + ksz9021_phy_extended_write(phydev,
> + MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
> + /* max rx/tx clock delay, min rx/tx control */
> + ksz9021_phy_extended_write(phydev,
> + MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
> +
> + if (phydev->drv->config)
> + phydev->drv->config(phydev);
> +
> + return 0;
> +}
> +
> +#if defined(CONFIG_VIDEO_IPUV3)
> +static void disable_lvds(struct display_info_t const *dev)
> +{
> + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
> +
> + int reg = readl(&iomux->gpr[2]);
> +
> + reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
> + IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
> +
> + writel(reg, &iomux->gpr[2]);
> +}
> +
> +static void do_enable_hdmi(struct display_info_t const *dev)
> +{
> + disable_lvds(dev);
> + /*
> + * imx_enable_hdmi_phy(); should be called here.
> + * It is ommitted to avoid a current known bug where
> + * the boot sometimes hangs if an HDMI cable is attached
> + * - at least on some DART SOMs.
> + */
> +}
> +
> +static void enable_lvds(struct display_info_t const *dev)
> +{
> + struct iomuxc *iomux = (struct iomuxc *)
> + IOMUXC_BASE_ADDR;
> + u32 reg = readl(&iomux->gpr[2]);
> + reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT |
> + IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT;
> + writel(reg, &iomux->gpr[2]);
> +
> + lvds_enabled=true;
> +}
> +
> +static void lvds_enable_disable(struct display_info_t const *dev)
> +{
> + if (getenv("splashimage") != NULL)
> + enable_lvds(dev);
> + else
> + disable_lvds(dev);
> +}
> +
> +static int detect_dart_vsc_display(struct display_info_t const *dev)
> +{
> + return (!is_mx6_custom_board());
> +}
> +
> +static int detect_mx6cb_cdisplay(struct display_info_t const *dev)
> +{
> + if (!is_mx6_custom_board())
> + return 0;
> +
> + i2c_set_bus_num(dev->bus);
> + return (0 == i2c_probe(dev->addr));
> +}
> +
> +static int detect_mx6cb_rdisplay(struct display_info_t const *dev)
> +{
> + if (!is_mx6_custom_board())
> + return 0;
> +
> + /* i2c probe the *c*display */
> + i2c_set_bus_num(MX6CB_CDISPLAY_I2C_BUS);
> + return (0 != i2c_probe(MX6CB_CDISPLAY_I2C_ADDR));
> +}
> +
> +#define MHZ2PS(f) (1000000/(f))
> +
> +struct display_info_t const displays[] = {{
> + .bus = -1,
> + .addr = 0,
> + .pixfmt = IPU_PIX_FMT_RGB24,
> + .detect = detect_hdmi,
> + .enable = do_enable_hdmi,
> + .mode = {
> + .name = "HDMI",
> + .refresh = 60,
> + .xres = 800,
> + .yres = 480,
> + .pixclock = 31777,
> + .left_margin = 48,
> + .right_margin = 16,
> + .upper_margin = 33,
> + .lower_margin = 10,
> + .hsync_len = 96,
> + .vsync_len = 2,
> + .sync = 0,
> + .vmode = FB_VMODE_NONINTERLACED
> +} }, {
> + .bus = -1,
> + .addr = 0,
> + .pixfmt = IPU_PIX_FMT_RGB666,
> + .detect = detect_dart_vsc_display,
> + .enable = lvds_enable_disable,
> + .mode = {
> + .name = "VAR-WVGA",
> + .refresh = 60, /* optional */
> + .xres = 800,
> + .yres = 480,
> + .pixclock = MHZ2PS(50),
> + .left_margin = 40,
> + .right_margin = 40,
> + .upper_margin = 29,
> + .lower_margin = 13,
> + .hsync_len = 48,
> + .vsync_len = 3,
> + .sync = FB_SYNC_EXT,
> + .vmode = FB_VMODE_NONINTERLACED
> +} }, {
> + .bus = MX6CB_CDISPLAY_I2C_BUS,
> + .addr = MX6CB_CDISPLAY_I2C_ADDR,
> + .pixfmt = IPU_PIX_FMT_RGB24,
> + .detect = detect_mx6cb_cdisplay,
> + .enable = lvds_enable_disable,
> + .mode = {
> + .name = "VAR-WVGA MX6CB-C",
> + .refresh = 60, /* optional */
> + .xres = 800,
> + .yres = 480,
> + .pixclock = MHZ2PS(50),
> + .left_margin = 39,
> + .right_margin = 39,
> + .upper_margin = 29,
> + .lower_margin = 13,
> + .hsync_len = 128,
> + .vsync_len = 2,
> + .sync = FB_SYNC_EXT,
> + .vmode = FB_VMODE_NONINTERLACED
> +} }, {
> + .bus = -1,
> + .addr = 0,
> + .pixfmt = IPU_PIX_FMT_RGB24,
> + .detect = detect_mx6cb_rdisplay,
> + .enable = lvds_enable_disable,
> + .mode = {
> + .name = "VAR-WVGA MX6CB-R",
> + .refresh = 60, /* optional */
> + .xres = 800,
> + .yres = 480,
> + .pixclock = MHZ2PS(50),
> + .left_margin = 0,
> + .right_margin = 40,
> + .upper_margin = 20,
> + .lower_margin = 13,
> + .hsync_len = 48,
> + .vsync_len = 3,
> + .sync = FB_SYNC_EXT,
> + .vmode = FB_VMODE_NONINTERLACED
> +} } };
> +
> +size_t display_count = ARRAY_SIZE(displays);
> +
> +static void setup_display(void)
> +{
> + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
> + int reg;
> +
> + /* Setup backlight */
> + SETUP_IOMUX_PAD(PAD_DISP0_DAT9__GPIO4_IO30 | MUX_PAD_CTRL(ENET_PAD_CTRL));
> +
> + /* Turn off backlight until display is ready */
> + gpio_direction_output(VAR_SOM_BACKLIGHT_EN , 0);
> +
> + /* Setup HSYNC, VSYNC, DISP_CLK for debugging purposes */
> + SETUP_IOMUX_PADS(di0_pads);
> +
> + enable_ipu_clock();
> + imx_setup_hdmi();
> +
> + /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
> + reg = readl(&mxc_ccm->CCGR3);
> + reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
> + writel(reg, &mxc_ccm->CCGR3);
> +
> + /* set LDB0, LDB1 clk select to 011/011 */
> + reg = readl(&mxc_ccm->cs2cdr);
> + reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
> + | MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
> + /* 1 -> ~50MHz , 2 -> ~56MHz, 3 -> ~75MHz, 4 -> ~68MHz */
> + reg |= (1 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
> + | (1 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
> + writel(reg, &mxc_ccm->cs2cdr);
> +
> + reg = readl(&mxc_ccm->cscmr2);
> + reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
> + writel(reg, &mxc_ccm->cscmr2);
> +
> + reg = readl(&mxc_ccm->chsccdr);
> + reg |= (CHSCCDR_CLK_SEL_LDB_DI0
> + << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
> + reg |= (CHSCCDR_CLK_SEL_LDB_DI0
> + << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
> + writel(reg, &mxc_ccm->chsccdr);
> +
> + reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
> + | IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW
> + | IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
> + | IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
> + | IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
> + | IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
> + | IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT
> + | IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0
> + | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
> + writel(reg, &iomux->gpr[2]);
> +
> + reg = readl(&iomux->gpr[3]);
> + reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK
> + | IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
> + | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
> + << IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
> + writel(reg, &iomux->gpr[3]);
> +}
> +#endif /* CONFIG_VIDEO_IPUV3 */
> +
> +/*
> + * Do not overwrite the console
> + * Use always serial for U-Boot console
> + */
> +int overwrite_console(void)
> +{
> + return 1;
> +}
> +
> +int board_eth_init(bd_t *bis)
> +{
> + uint32_t base = IMX_FEC_BASE;
> + struct mii_dev *bus = NULL;
> + struct phy_device *phydev = NULL;
> + int ret;
> +
> + setup_iomux_enet();
> +
> +#ifdef CONFIG_FEC_MXC
> + bus = fec_get_miibus(base, -1);
> +
> + if (!bus) {
> + printf("FEC MXC bus: %s:failed\n", __func__);
> + return 0;
> + }
> + /* "scan" phy 7 */
> + phydev = phy_find_by_mask(bus, (0x1 << 7),
<< CONFIG_FEC_MXC_PHYADDR
PHY_INTERFACE_MODE_RGMII);
> + if (!phydev) {
> + printf("FEC MXC phy find: %s:failed\n", __func__);
> + free(bus);
> + return 0;
> + }
> + printf("using phy at %d\n", phydev->addr);
> +
> + ret = fec_probe(bis, -1, base, bus, phydev);
> + if (ret) {
> + printf("FEC MXC probe: %s:failed\n", __func__);
> + free(phydev);
> + free(bus);
> + }
> +#endif
> +
> +#ifdef CONFIG_USB_ETHER
> + /* OTG - Ethernet Gadget */
Is it not CONFIG_CI_UDC ? If it runs as gadget..
> + usb_eth_initialize(bis);
> +#endif
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_USB_EHCI_MX6
> +#define VSC_USB_H1_PWR_EN IMX_GPIO_NR(4, 15)
> +#define VSC_USB_OTG_PWR_EN IMX_GPIO_NR(3, 22)
> +#define DART_USB_H1_PWR_EN IMX_GPIO_NR(1, 28)
> +#define DART_USB_OTG_PWR_EN IMX_GPIO_NR(4, 15)
> +
> +static void setup_usb(void)
> +{
> + if (is_dart_board()) {
> + /* config OTG ID iomux */
> + SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(OTG_ID_PAD_CTRL));
> + imx_iomux_set_gpr_register(1, 13, 1, 0);
> +
> + SETUP_IOMUX_PAD(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL));
> + gpio_direction_output(DART_USB_OTG_PWR_EN, 0);
> +
> + SETUP_IOMUX_PAD(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL));
> + gpio_direction_output(DART_USB_H1_PWR_EN, 0);
> + } else if (is_solo_custom_board()) {
> + /* config OTG ID iomux */
> + SETUP_IOMUX_PAD(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(OTG_ID_PAD_CTRL));
> + imx_iomux_set_gpr_register(1, 13, 1, 1);
> +
> + SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
> + gpio_direction_output(VSC_USB_OTG_PWR_EN, 0);
> +
> + SETUP_IOMUX_PAD(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL));
> + gpio_direction_output(VSC_USB_H1_PWR_EN, 0);
You set multiple pins here, and this can be written in a much more
readable way. If you see in all code (as well as you use later), there
is like a template:
- array with pin configuration for a function
- calling iomux_setup.. to make the configuration active.
This can be done as:
board = is_dart_board() .....;
pin_config = usb_pin_cfg[board]; /* Multiple array, one for board*/
imx_iomux_v3_setup_multiple_pads(pin_config,...)
most code here is duplicated
> + }
> +}
> +
> +int board_usb_phy_mode(int port)
> +{
> + char *s;
> + if (is_mx6_custom_board() && port==0) {
> + s = getenv("usbmode");
> + if ((s != NULL) && (!strcmp(s, "host")))
> + return USB_INIT_HOST;
> + else
> + return USB_INIT_DEVICE;
> + }
> + return usb_phy_mode(port);
> +}
> +
> +/*
> + * int board_ehci_hcd_init(int port)
> + * {
> + * if (is_dart_board() || is_solo_custom_board()) {
> + * no hub to reset
> + * } else if (is_mx6_custom_board()) {
> + * hub present but pulled up
> + * }
> + *
> + * return 0;
> + * }
> + */
Drop all dead code, it cannot be mainlined.
> +
> +int board_ehci_power(int port, int on)
> +{
> + if (is_mx6_custom_board())
> + return 0; /* no power enable needed */
> +
> + if (port > 1)
> + return -EINVAL;
> +
> + if (port) {
> + if (is_dart_board())
> + gpio_set_value(DART_USB_H1_PWR_EN, on);
> + else if (is_solo_custom_board())
> + gpio_set_value(VSC_USB_H1_PWR_EN, on);
> + } else {
> + if (is_dart_board())
> + gpio_set_value(DART_USB_OTG_PWR_EN, on);
> + else if (is_solo_custom_board())
> + gpio_set_value(VSC_USB_OTG_PWR_EN, on);
> + }
> +
> + return 0;
> +}
> +#endif /* CONFIG_USB_EHCI_MX6 */
> +
> +int board_early_init_f(void)
> +{
> + var_setup_iomux_per_vcc_en();
> +
> + setup_iomux_uart();
> +#if defined(CONFIG_VIDEO_IPUV3)
> + setup_display();
> +#endif
> +#ifdef CONFIG_SYS_I2C_MXC
> + setup_local_i2c();
> +#endif
> +#ifdef CONFIG_SYS_USE_NAND
> + setup_gpmi_nand();
> +#endif
> +
> + return 0;
> +}
> +
> +int board_init(void)
> +{
> + int ret = 0;
> +
> + /* address of boot parameters */
> + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
> + gd->bd->bi_arch_number = CONFIG_MACH_VAR_SOM_MX6;
Still needed ?
> +
> +#ifdef CONFIG_USB_EHCI_MX6
> + setup_usb();
> +#endif
> + return ret;
> +}
> +
> +static struct pmic *pfuze;
> +
> +static void set_anatop_bypass(void)
> +{
> + struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
> + u32 reg = readl(&anatop->reg_core);
> +
> + /* bypass VDDARM/VDDSOC */
> + reg |= (0x1F << 18) | 0x1F;
Use constants instead of hex values - this must be fixed in all code.
> + writel(reg, &anatop->reg_core);
> +}
> +
> +static void ldo_mode_set(void)
> +{
> + if (!is_som_solo()) {
> + unsigned int reg;
> + struct pmic *p = pfuze;
> + int retval = 0;
> +
> + if (!p) {
> + printf("No PMIC found!\n");
> + return;
> + }
> +
> + /* Set SW1AB to 1.325V */
> + retval += pmic_reg_read(p, PFUZE100_SW1ABVOL, ®);
> + reg &= ~SW1x_NORMAL_MASK;
> + reg |= SW1x_1_325V;
> + retval += pmic_reg_write(p, PFUZE100_SW1ABVOL, reg);
> +
> + /* Set SW1C to 1.325V */
> + retval += pmic_reg_read(p, PFUZE100_SW1CVOL, ®);
> + reg &= ~SW1x_NORMAL_MASK;
> + reg |= SW1x_1_325V;
> + retval += pmic_reg_write(p, PFUZE100_SW1CVOL, reg);
> +
> + if (retval) {
> + printf("PMIC write voltages error!\n");
> + return;
> + }
> +
> + set_anatop_bypass();
> + printf("switch to ldo_bypass mode!\n");
> + }
> +}
> +
> +int power_init_board(void)
> +{
> + if (!is_som_solo()) {
> + unsigned int reg;
> + int retval;
> +
> + retval = power_pfuze100_init(PMIC_I2C_BUS);
> + if (retval)
> + return -ENODEV;
> + pfuze = pmic_get("PFUZE100");
> + retval = pmic_probe(pfuze);
> + if (retval)
> + return -ENODEV;
> + pmic_reg_read(pfuze, PFUZE100_DEVICEID, ®);
> + printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
> +
> + if (!is_dart_board()) {
> +
> + /* Set Gigbit Ethernet voltage (SOM v1.1/1.0) */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW4VOL, ®);
> + reg &= ~0x7f;
> + reg |= 0x60; /* 2.4V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW4VOL, reg);
> +
> + /* Increase VGEN5 from 2.8 to 3V */
> + retval += pmic_reg_read(pfuze, PFUZE100_VGEN5VOL, ®);
> + reg &= ~LDO_VOL_MASK;
> + reg |= LDOB_3_00V;
> + retval += pmic_reg_write(pfuze, PFUZE100_VGEN5VOL, reg);
> +
> + /* Set SW1AB standby volage to 0.975V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1ABSTBY, ®);
> + reg &= ~SW1x_STBY_MASK;
> + reg |= SW1x_0_975V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABSTBY, reg);
> +
> + /* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1ABCONF, ®);
> + reg &= ~SW1xCONF_DVSSPEED_MASK;
> + reg |= SW1xCONF_DVSSPEED_4US;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABCONF, reg);
> +
> + /* Set SW1C standby voltage to 0.975V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1CSTBY, ®);
> + reg &= ~SW1x_STBY_MASK;
> + reg |= SW1x_0_975V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1CSTBY, reg);
> +
> +#ifdef LOW_POWER_MODE_ENABLE
> + /* Set low power mode voltages to disable */
> +
> + /* Set SW3A standby voltage to 1.275V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW3ASTBY, ®);
> + reg &= ~0x7f; /* SW3x STBY MASK */
> + reg = 0x23; /* SW3x 1.275V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW3ASTBY, reg);
> +
> + /* Set SW3A off voltage to 1.275V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW3AOFF, ®);
> + reg &= ~0x7f; /* SW3x OFF MASK */
> + reg = 0x23; /* SW3x 1.275V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW3AOFF, reg);
> +
> + /* Set SW2 to 3.2V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW2VOL, ®);
> + reg &= ~0x7f;
> + reg |= 0x70; /* SW2x 3.2V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW2VOL, reg);
> +
> + /* SW4MODE = OFF in standby */
> + reg = PWM_OFF;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW4MODE, reg);
> +
> + /* Set VGEN3 to 2.5V, VGEN3CTL = OFF in standby */
> + retval += pmic_reg_read(pfuze, PFUZE100_VGEN3VOL, ®);
> + reg &= ~0x7f;
> + reg |= 0x30; /* VGEN3EN, VGEN3STBY, ~VGEN3LPWR */
> + reg |= LDOB_2_50V;
> + retval += pmic_reg_write(pfuze, PFUZE100_VGEN3VOL, reg);
> +#else
> + /* Set VGEN3 to 2.5V, VGEN3CTL = low power in standby */
> + retval += pmic_reg_read(pfuze, PFUZE100_VGEN3VOL, ®);
> + reg &= ~0x7f;
> + reg |= 0x70; /* VGEN3EN, VGEN3STBY, VGEN3LPWR */
> + reg |= LDOB_2_50V;
> + retval += pmic_reg_write(pfuze, PFUZE100_VGEN3VOL, reg);
> +#endif
> + } else {
> +
> + /* Set SW1AB standby volage to 0.9V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1ABSTBY, ®);
> + reg &= ~SW1x_STBY_MASK;
> + reg |= SW1x_0_900V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABSTBY, reg);
> +
> + /* Set SW1AB off volage to 0.9V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1ABOFF, ®);
> + reg &= ~SW1x_OFF_MASK;
> + reg |= SW1x_0_900V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABOFF, reg);
> +
> + /* Set SW1C standby voltage to 0.9V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1CSTBY, ®);
> + reg &= ~SW1x_STBY_MASK;
> + reg |= SW1x_0_900V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1CSTBY, reg);
> +
> + /* Set SW1C off volage to 0.9V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1COFF, ®);
> + reg &= ~SW1x_OFF_MASK;
> + reg |= SW1x_0_900V;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1COFF, reg);
> +
> + /* Set SW2 to 3.3V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW2VOL, ®);
> + reg &= ~0x7f; /* SW2x NORMAL MASK */
> + reg |= 0x72; /* SW2x 3.3V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW2VOL, reg);
> +
> + /* Set SW2 standby voltage to 3.2V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW2STBY, ®);
> + reg &= ~0x7f; /* SW2x STBY MASK */
> + reg |= 0x70; /* SW2x 3.2V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW2STBY, reg);
> +
> + /* Set SW2 off voltage to 3.2V */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW2OFF, ®);
> + reg &= ~0x7f; /* SW2x OFF MASK */
> + reg |= 0x70; /* SW2x 3.2V */
> + retval += pmic_reg_write(pfuze, PFUZE100_SW2OFF, reg);
> +
> + reg = PWM_PFM;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABMODE, reg);
> +
> + /* Set SW1AB/VDDARM step ramp up time 2us */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1ABCONF, ®);
> + reg &= ~SW1xCONF_DVSSPEED_MASK;
> + reg |= SW1xCONF_DVSSPEED_2US;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1ABCONF, reg);
> +
> + reg = PWM_PFM;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1CMODE, reg);
> +
> + reg = PWM_PFM;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW2MODE, reg);
> +
> + reg = LDOB_3_30V;
> + retval += pmic_reg_write(pfuze, PFUZE100_VGEN6VOL, reg);
> + }
> +
You have to factoritze the common code and handle in case just the
differences, instead of copying the all code twice.
> + /* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
> + retval += pmic_reg_read(pfuze, PFUZE100_SW1CCONF, ®);
> + reg &= ~SW1xCONF_DVSSPEED_MASK;
> + reg |= SW1xCONF_DVSSPEED_4US;
> + retval += pmic_reg_write(pfuze, PFUZE100_SW1CCONF, reg);
> +
> + if (retval) {
> + printf("PMIC write voltages error!\n");
> + return -1;
> + }
> +
> + ldo_mode_set();
> + }
> +
> + return 0;
> +}
> +
> +static void update_env(void)
> +{
> + setenv("mmcroot" , "/dev/mmcblk0p2 rootwait rw");
> + if (is_cpu_type(MXC_CPU_MX6Q)) {
> + if (is_dart_board()) {
> + setenv("fdt_file", "imx6q-var-dart.dtb");
> + if (MMC_BOOT == get_mmc_boot_device())
> + setenv("mmcroot" , "/dev/mmcblk2p2 rootwait rw");
> + else
> + setenv("mmcroot" , "/dev/mmcblk1p2 rootwait rw");
> + } else {
> + if (is_solo_custom_board())
> + setenv("fdt_file", "imx6q-var-som-vsc.dtb");
> + else
> + setenv("fdt_file", "imx6q-var-som.dtb");
> + }
> + } else if (is_cpu_type(MXC_CPU_MX6D)) {
> + if (is_dart_board()) {
> + setenv("fdt_file", "imx6q-var-dart.dtb");
> + if (MMC_BOOT == get_mmc_boot_device())
> + setenv("mmcroot" , "/dev/mmcblk2p2 rootwait rw");
> + else
> + setenv("mmcroot" , "/dev/mmcblk1p2 rootwait rw");
> + } else {
> + setenv("fdt_file", "imx6q-var-som.dtb");
> + }
> + } else if (is_cpu_type(MXC_CPU_MX6DL)) {
> + if (is_som_solo()) {
> + if (is_solo_custom_board())
> + setenv("fdt_file", "imx6dl-var-som-solo-vsc.dtb");
> + else
> + setenv("fdt_file", "imx6dl-var-som-solo.dtb");
> + } else {
> + setenv("fdt_file", "imx6dl-var-som.dtb");
> + }
> + } else if (is_cpu_type(MXC_CPU_MX6SOLO)) {
> + if (is_som_solo()) {
> + if (is_solo_custom_board())
> + setenv("fdt_file", "imx6dl-var-som-solo-vsc.dtb");
> + else
> + setenv("fdt_file", "imx6dl-var-som-solo.dtb");
> + } else {
> + setenv("fdt_file", "imx6dl-var-som.dtb");
> + }
> + }
> +}
> +
This function is against the way U-Boot handle this, and it will be
rejected - take a look at the script capabilities in U-Boot, it seems
you do not like them at all !
> +static void imx6_pcie_assert_core_reset(void)
> +{
> + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
> +
> + if (is_mx6dqp())
> + setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
> +
> + setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
> + clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
> +}
> +
> +static void imx6_pcie_init_phy(void)
> +{
> + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
> +
> + clrbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE);
> +
> + clrsetbits_le32(&iomuxc_regs->gpr[12],
> + IOMUXC_GPR12_DEVICE_TYPE_MASK,
> + IOMUXC_GPR12_DEVICE_TYPE_RC);
> + clrsetbits_le32(&iomuxc_regs->gpr[12],
> + IOMUXC_GPR12_LOS_LEVEL_MASK,
> + IOMUXC_GPR12_LOS_LEVEL_9);
> +
> + writel((0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_OFFSET) |
> + (0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET) |
> + (20 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_OFFSET) |
> + (127 << IOMUXC_GPR8_PCS_TX_SWING_FULL_OFFSET) |
> + (127 << IOMUXC_GPR8_PCS_TX_SWING_LOW_OFFSET),
> + &iomuxc_regs->gpr[8]);
> +}
> +
> +static void imx6_pcie_deassert_core_reset(void)
> +{
> + struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
> +
> + if (is_mx6dqp())
> + clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
> +
> + /*
> + * Wait for the clock to settle a bit, when the clock are sourced
> + * from the CPU, we need about 30 ms to settle.
> + */
> + mdelay(50);
> +
> + /* Enable PCIe */
> + clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
> + setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
> +}
> +
> +/*
> + * Resets the PCIe controller in order to prevent a soft reboot hang
> + */
> +static void imx_pcie_reset(void)
> +{
> + imx6_pcie_assert_core_reset();
> + imx6_pcie_init_phy();
> + imx6_pcie_deassert_core_reset();
> +}
> +
> +int board_late_init(void)
> +{
> + char *s;
> +
> + print_emmc_size();
> +
> + s = getenv("var_auto_env");
> + if (s[0] == 'Y')
> + update_env();
> +
> + imx_pcie_reset();
> +
> + return 0;
> +}
> +
> +int checkboard(void)
> +{
> + puts("Board: Variscite VAR-SOM-MX6 ");
> +
> + if (is_cpu_type(MXC_CPU_MX6Q)) {
> + puts("Quad");
> + if (is_cpu_pop_package())
> + puts("-POP");
> +
> + } else if (is_cpu_type(MXC_CPU_MX6D)) {
> + puts("Dual");
> + if (is_cpu_pop_package())
> + puts("-POP");
> +
> + } else if (is_cpu_type(MXC_CPU_MX6DL)) {
> + if (is_som_solo())
> + puts("SOM-Dual");
> + else
> + puts("Dual Lite");
> +
> + } else if (is_cpu_type(MXC_CPU_MX6SOLO)) {
> + if (is_som_solo())
> + puts("SOM-Solo");
> + else
> + puts("Solo");
> + } else
> + puts("????");
> +
> + puts("\n");
> + return 0;
> +}
> +
> +#ifdef CONFIG_SPL_BUILD
> +#include <spl.h>
> +#include <libfdt.h>
> +#include <asm/arch/mx6-ddr.h>
> +#include "mx6var_eeprom.h"
> +#include "mx6var_eeprom_v2.h"
> +
> +/*
> + * Writes RAM size to RAM_SIZE_ADDR so U-Boot can read it
> + */
> +static void var_set_ram_size(u32 ram_size)
> +{
> + u32 *p_ram_size = (u32 *)RAM_SIZE_ADDR;
> + if (ram_size > 3840)
> + ram_size=3840;
> + *p_ram_size = ram_size;
> +}
> +
> +static void print_board_info(int eeprom_rev, void* var_eeprom, u32 ram_size)
> +{
> + u32 boot_device;
> + u32 max_freq;
> +
> + printf("\ni.MX%s SOC P-%s\n", get_imx_type(get_cpu_type()), \
> + is_cpu_pop_package() ? "POP" : "STD");
> +
> + max_freq = get_cpu_speed_grade_hz();
> + if (!max_freq)
> + printf("CPU running at %dMHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
> + else
> + printf("%d MHz CPU (running at %d MHz)\n", max_freq / 1000000,
> + mxc_get_clock(MXC_ARM_CLK) / 1000000);
> +
> + if (eeprom_rev==1)
> + var_eeprom_strings_print((struct var_eeprom_cfg *) var_eeprom);
> + else if (eeprom_rev==2)
> + var_eeprom_v2_strings_print((struct var_eeprom_v2_cfg *) var_eeprom);
> + else
> + return;
> +
> + printf("RAM: ");
> + print_size(ram_size * 1024 * 1024, "\n");
> +
> + printf("Boot Device: ");
> + boot_device = spl_boot_device();
> + switch (boot_device) {
> + case BOOT_DEVICE_MMC1:
> + switch (get_mmc_boot_device()) {
> + case SD_BOOT:
> + printf("MMC0 (SD)\n");
> + break;
> + case MMC_BOOT:
> + printf("MMC1 (DART eMMC)\n");
> + break;
> + default:
> + printf("MMC?\n");
> + break;
> + }
> + break;
> +
> + case BOOT_DEVICE_NAND:
> + printf("NAND\n");
> + break;
> +
> + default:
> + printf("UNKNOWN (%d)\n", boot_device);
> + break;
> + }
> +}
> +
> +static int spl_dram_init_by_eeprom(void)
> +{
> + struct var_eeprom_cfg var_eeprom_cfg = {{0}};
> + int ret;
> +
> + ret = var_eeprom_read_struct(&var_eeprom_cfg);
> + if (ret)
> + return SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM;
> +
> + /* is valid Variscite EEPROM? */
> + if (!var_eeprom_is_valid(&var_eeprom_cfg))
> + return SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM_STRUCT_DETECTED;
> +
> + switch (get_cpu_type()) {
> + case MXC_CPU_MX6DL:
> + case MXC_CPU_MX6SOLO:
> + var_eeprom_mx6dlsl_dram_setup_iomux_from_struct(&var_eeprom_cfg.pinmux_group);
> + break;
> + case MXC_CPU_MX6Q:
> + case MXC_CPU_MX6D:
> + default:
> + var_eeprom_mx6qd_dram_setup_iomux_from_struct(&var_eeprom_cfg.pinmux_group);
> + break;
> + }
> +
> + var_eeprom_dram_init_from_struct(&var_eeprom_cfg);
> +
> + var_set_ram_size(var_eeprom_cfg.header.ddr_size);
> + print_board_info(1, (void*) &var_eeprom_cfg, var_eeprom_cfg.header.ddr_size);
> +
> + return SPL_DRAM_INIT_STATUS_OK;
> +}
> +
> +/*
> + * Bugfix: Fix Freescale wrong processor documentation.
> + */
> +static void spl_mx6qd_dram_setup_iomux_check_reset(void)
> +{
> + volatile struct mx6dq_iomux_ddr_regs *mx6q_ddr_iomux;
> + u32 cputype = get_cpu_type();
> +
> + if ((cputype == MXC_CPU_MX6D) || (cputype == MXC_CPU_MX6Q)) {
> + mx6q_ddr_iomux = (struct mx6dq_iomux_ddr_regs *) MX6DQ_IOM_DDR_BASE;
> +
> + if (mx6q_ddr_iomux->dram_reset == (u32)0x000C0030)
> + mx6q_ddr_iomux->dram_reset = (u32)0x00000030;
> + }
> +}
> +
> +static void ccgr_init(void)
> +{
> + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +
> + writel(0x00C03F3F, &ccm->CCGR0);
> + writel(0x0030FC03, &ccm->CCGR1);
> + writel(0x0FFFC000, &ccm->CCGR2);
> + writel(0x3FF00000, &ccm->CCGR3);
> + writel(0x00FFF300, &ccm->CCGR4);
> + writel(0x0F0000C3, &ccm->CCGR5);
> + writel(0x000003FF, &ccm->CCGR6);
> +}
> +
> +static void gpr_init(void)
> +{
> + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
> +
> + /* enable AXI cache for VDOA/VPU/IPU */
> + writel(0xF00000CF, &iomux->gpr[4]);
> + /* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
> + writel(0x007F007F, &iomux->gpr[6]);
> + writel(0x007F007F, &iomux->gpr[7]);
> +}
> +
> +static int spl_dram_init_by_eeprom_v2(void)
> +{
> + u32 ram_addresses[MAXIMUM_RAM_ADDRESSES];
> + u32 ram_values[MAXIMUM_RAM_VALUES];
> + struct var_eeprom_v2_cfg var_eeprom_v2_cfg = {0};
> + int ret, ram_size;
> +
> + ret = var_eeprom_v2_read_struct(&var_eeprom_v2_cfg, \
> + is_dart_board() ? VAR_DART_EEPROM_CHIP : VAR_MX6_EEPROM_CHIP);
> +
> + if (ret)
> + return SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM;
> +
> + if (!var_eeprom_v2_is_valid(&var_eeprom_v2_cfg))
> + return SPL_DRAM_INIT_STATUS_ERROR_NO_EEPROM_STRUCT_DETECTED;
> +
> + handle_eeprom_data(&var_eeprom_v2_cfg, ram_addresses, ram_values);
> +
> + ram_size = var_eeprom_v2_cfg.ddr_size * 128;
> + var_set_ram_size(ram_size);
> + print_board_info(2, (void*) &var_eeprom_v2_cfg, ram_size);
> + return SPL_DRAM_INIT_STATUS_OK;
> +}
> +
> +static void spl_dram_init(void)
> +{
> + int status;
> +
> + status = spl_dram_init_by_eeprom();
> + if (status != SPL_DRAM_INIT_STATUS_OK) {
> + status = spl_dram_init_by_eeprom_v2();
> + if (status != SPL_DRAM_INIT_STATUS_OK) {
> + printf("Error initializing RAM using EEPROM\n");
> + hang();
> + }
> + }
> + spl_mx6qd_dram_setup_iomux_check_reset();
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> + /* setup AIPS and disable watchdog */
> + arch_cpu_init();
> +
> + ccgr_init();
> + gpr_init();
> +
> + /* iomux and setup of i2c */
> + board_early_init_f();
> +
> + /* setup GP timer */
> + timer_init();
> +
> + /* Wait 330ms before starting to print to console */
> + mdelay(330);
> +
> + /* UART clocks enabled and gd valid - init serial console */
> + preloader_console_init();
> +
> + /* DDR initialization */
> + spl_dram_init();
> +
> + /* Clear the BSS. */
> + memset(__bss_start, 0, __bss_end - __bss_start);
> +
> + /* load/boot image from boot device */
> + board_init_r(NULL, 0);
> +}
> +#endif
> diff --git a/board/variscite/mx6var_som/u-boot-spl.lds b/board/variscite/mx6var_som/u-boot-spl.lds
> new file mode 100644
> index 0000000..33d8406
> --- /dev/null
> +++ b/board/variscite/mx6var_som/u-boot-spl.lds
> @@ -0,0 +1,59 @@
> +/*
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <garyj at denx.de>
> + *
> + * (C) Copyright 2010
> + * Texas Instruments, <www.ti.com>
> + * Aneesh V <aneesh at ti.com>
> + *
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
> + LENGTH = CONFIG_SPL_MAX_SIZE }
> +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
> + LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
> +
> +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> +OUTPUT_ARCH(arm)
> +ENTRY(_start)
> +SECTIONS
> +{
> + .text :
> + {
> + __start = .;
> + *(.vectors)
> + arch/arm/cpu/armv7/start.o (.text*)
> + *(.text*)
> + } >.sram
> +
> + . = ALIGN(4);
> + .rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
> +
> + . = ALIGN(4);
> + .data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
> +
> + . = ALIGN(4);
> + .u_boot_list : {
> + KEEP(*(SORT(.u_boot_list*_i2c_*)));
> + } >.sram
> +
> + . = ALIGN(4);
> + __image_copy_end = .;
> +
> + .end :
> + {
> + *(.__end)
> + }
> +
> + .bss :
> + {
> + . = ALIGN(4);
> + __bss_start = .;
> + *(.bss*)
> + . = ALIGN(4);
> + __bss_end = .;
> + } >.sram
> +}
Any reason for that ? There is a global .lds file, and you should use it.
> diff --git a/board/variscite/mx6var_som/values.inc b/board/variscite/mx6var_som/values.inc
> new file mode 100644
> index 0000000..aafc088
> --- /dev/null
> +++ b/board/variscite/mx6var_som/values.inc
> @@ -0,0 +1,39 @@
> +0x00000000,0x00000010,0x00000013,0x00000017,
> +0x00000027,0x00000028,0x00000030,0x00000038,
> +0x00000047,0x00000053,0x00000080,0x000000DD,
> +0x0000020E,0x00000800,0x00001740,0x0000174C,
> +0x00001800,0x000026D2,0x00003000,0x00003030,
> +0x00005800,0x00007800,0x00008000,0x00008033,
> +0x0000803B,0x00011006,0x00011117,0x00011740,
> +0x00020000,0x00020025,0x0002002D,0x00020036,
> +0x00022227,0x00025565,0x0002556D,0x00025576,
> +0x00048031,0x00048039,0x00080000,0x00081740,
> +0x000C0000,0x000C0030,0x00130029,0x00160E83,
> +0x0019002E,0x001C0019,0x001D002C,0x001F0019,
> +0x001F001F,0x001F002B,0x00220AAC,0x0024001F,
> +0x423D3843,0x42440244,0x43240334,0x432C0340,
> +0x4528053C,0x45300544,0x454A61A5,0x46344840,
> +0x48364A3E,0x484A4C4A,0x4B2B4842,0x4B4A4E4C,
> +0x555A7974,0x676B5313,0x821A0000,0x83110000,
> +0x831A0000,0x84190000,0x841A0000,0x8A8F7955,
> +0xA1390003,0xB66D8B63,0xB66E8B63,0xC2018030,
> +0xC2018038,0xC41A0000,0xDB538F64,0xF3333333,
> +0xFF0A8030,0xFF0A8038,0xFF328F64,0xFFFFFFFF
I do not like this way for generating a DCD-like table.
> diff --git a/configs/mx6var_som_nand_defconfig b/configs/mx6var_som_nand_defconfig
> new file mode 100644
> index 0000000..59c3747
> --- /dev/null
> +++ b/configs/mx6var_som_nand_defconfig
> @@ -0,0 +1,7 @@
> +CONFIG_ARM=y
> +CONFIG_ARCH_MX6=y
> +CONFIG_TARGET_MX6VAR_SOM=y
> +CONFIG_SPL=y
> +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/variscite/mx6var_som/imximage.cfg,SPL,MX6QDL,SYS_BOOT_NAND"
> +# CONFIG_CMD_IMLS is not set
> +# CONFIG_CMD_FLASH is not set
> diff --git a/configs/mx6var_som_sd_defconfig b/configs/mx6var_som_sd_defconfig
> new file mode 100644
> index 0000000..875234e
> --- /dev/null
> +++ b/configs/mx6var_som_sd_defconfig
> @@ -0,0 +1,7 @@
> +CONFIG_ARM=y
> +CONFIG_ARCH_MX6=y
> +CONFIG_TARGET_MX6VAR_SOM=y
> +CONFIG_SPL=y
> +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/variscite/mx6var_som/imximage.cfg,SPL,MX6QDL"
> +# CONFIG_CMD_IMLS is not set
> +# CONFIG_CMD_FLASH is not set
> diff --git a/include/configs/mx6var_som.h b/include/configs/mx6var_som.h
> new file mode 100644
> index 0000000..6771a2d
> --- /dev/null
> +++ b/include/configs/mx6var_som.h
> @@ -0,0 +1,419 @@
> +/*
> + * Copyright (C) 2012 Freescale Semiconductor, Inc.
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * Author: Eran Matityahu <eran.m at variscite.com>
> + *
> + * Configuration settings for the Variscite VAR-SOM-MX6 board.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef __MX6VAR_SOM_CONFIG_H
> +#define __MX6VAR_SOM_CONFIG_H
> +
> +#ifdef CONFIG_SPL
> +#define CONFIG_SPL_LIBCOMMON_SUPPORT
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define CONFIG_SPL_NAND_SUPPORT
> +#else
> +#define CONFIG_SPL_MMC_SUPPORT
> +#endif
> +#include "mx6var_spl.h"
> +#endif
> +#include "mx6_common.h"
> +
> +/* Address of reserved 4Bytes in OCRAM for sending RAM size from SPL to U-Boot */
> +#define RAM_SIZE_ADDR ((CONFIG_SPL_TEXT_BASE) + (CONFIG_SPL_MAX_SIZE))
> +
> +#define CONFIG_MACH_VAR_SOM_MX6 4419
> +#define CONFIG_MACH_TYPE CONFIG_MACH_VAR_SOM_MX6
> +
> +#define CONFIG_MXC_UART_BASE UART1_BASE
> +#define CONFIG_CONSOLE_DEV "ttymxc0"
> +#define CONFIG_MMCROOT "/dev/mmcblk0p2"
> +
> +#define CONFIG_IMX_THERMAL
> +
> +/* Size of malloc() pool */
> +#define CONFIG_SYS_MALLOC_LEN (10 * SZ_1M)
> +
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_BOARD_LATE_INIT
> +
> +#define CONFIG_CMD_GPIO
> +
> +#define CONFIG_MXC_UART
> +
> +#define LOW_POWER_MODE_ENABLE
> +
> +/* MMC Configs */
> +#define CONFIG_SYS_FSL_ESDHC_ADDR 0
> +#define CONFIG_SYS_FSL_USDHC_NUM 2
> +#define CONFIG_SYS_MMC_ENV_DEV 0
> +#define CONFIG_SYS_MMC_ENV_PART 0
> +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1
> +
> +#define CONFIG_CMD_PING
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_MII
> +#define CONFIG_FEC_MXC
> +#define CONFIG_MII
> +#define IMX_FEC_BASE ENET_BASE_ADDR
> +#define CONFIG_FEC_XCV_TYPE RGMII
> +#define CONFIG_ETHPRIME "FEC"
> +#define CONFIG_FEC_MXC_PHYADDR 7
> +
> +#define CONFIG_PHYLIB
> +#define CONFIG_PHY_MICREL
> +#define CONFIG_PHY_MICREL_KSZ9021
> +
> +#ifdef CONFIG_BOOTDELAY
> +#undef CONFIG_BOOTDELAY
> +#endif
> +#define CONFIG_BOOTDELAY 1
> +
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:16m(boot),16m(kernel),16m(dtb),-(rootfs) "
> +#else
> +#define MFG_NAND_PARTITION ""
> +#endif
> +
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define MMC_DEV_SET " "
> +#else
> +#define MMC_DEV_SET "mmcdev=" __stringify(CONFIG_SYS_MMC_ENV_DEV)
> +#endif
> +
> +#define MFG_ENV_SETTINGS \
> + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \
> + "rdinit=/linuxrc " \
> + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \
> + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\
> + "g_mass_storage.iSerialNumber=\"\" "\
> + "enable_wait_mode=off "\
> + MFG_NAND_PARTITION \
> + "\0" \
> + "initrd_addr=0x12C00000\0" \
> + "initrd_high=0xffffffff\0" \
> + "bootcmd_mfg=run mfgtool_args;bootm ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \
> +
> +
> +#define MMC_BOOT_ENV_SETTINGS \
> + "uimage=uImage\0" \
> + "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
> + "boot_fdt=try\0" \
> + "ip_dyn=yes\0" \
> + MMC_DEV_SET \
> + "\0" \
> + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \
> + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \
> + "mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}; " \
> + "run videoargs\0" \
> + "loadbootscript=" \
> + "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
> + "bootscript=echo Running bootscript from mmc ...; " \
> + "source\0" \
> + "loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
> + "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
> + "mmcboot=echo Booting from mmc ...; " \
> + "run mmcargs; " \
> + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
> + "if run loadfdt; then " \
> + "bootm ${loadaddr} - ${fdt_addr}; " \
> + "else " \
> + "if test ${boot_fdt} = try; then " \
> + "bootm; " \
> + "else " \
> + "echo WARN: Cannot load the DT; " \
> + "fi; " \
> + "fi; " \
> + "else " \
> + "bootm; " \
> + "fi;\0" \
> +
> +
> +#define NAND_BOOT_ENV_SETTINGS \
> + "bootargs_ubifs=setenv bootargs console=${console},${baudrate} ubi.mtd=3 " \
> + "root=ubi0:rootfs rootfstype=ubifs; " \
> + "run videoargs\0" \
> + "bootargs_emmc=setenv bootargs console=${console},${baudrate} " \
> + "root=/dev/mmcblk1p1 rootwait rw; " \
> + "run videoargs\0" \
> + "bootcmd=" \
> + "if test ${chosen_rootfs} != emmc; then " \
> + "run bootargs_ubifs; " \
> + "else " \
> + "run bootargs_emmc; " \
> + "fi; " \
> + "nand read ${loadaddr} 0x400000 0x600000;" \
> + "nand read ${fdt_addr} 0x3e0000 0x20000;" \
> + "bootm ${loadaddr} - ${fdt_addr}\0" \
> + "mtdids=" MTDIDS_DEFAULT "\0" \
> + "mtdparts=" MTDPARTS_DEFAULT "\0" \
> +
> +
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define BOOT_ENV_SETTINGS NAND_BOOT_ENV_SETTINGS
> +#else
> +#define BOOT_ENV_SETTINGS MMC_BOOT_ENV_SETTINGS
> +#define CONFIG_BOOTCOMMAND \
> + "mmc dev ${mmcdev};" \
> + "if mmc rescan; then " \
> + "if run loadbootscript; then " \
> + "run bootscript; " \
> + "else " \
> + "if run loaduimage; then " \
> + "run mmcboot; " \
> + "else " \
> + "run netboot; " \
> + "fi; " \
> + "fi; " \
> + "else run netboot; fi"
> +#endif
> +
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> + MFG_ENV_SETTINGS \
> + BOOT_ENV_SETTINGS \
> + "var_auto_env=Y\0" \
> + "fdt_addr=0x18000000\0" \
> + "fdt_high=0xffffffff\0" \
> + "splash_filename=/boot/splash.bmp\0" \
> + "splashimage=0x18100000\0" \
> + "enable_splash=setenv splash_filename /boot/splash.bmp; " \
> + "setenv splashimage 0x18100000\0" \
> + "disable_splash=setenv splash_filename; setenv splashimage\0" \
> + "console=" CONFIG_CONSOLE_DEV "\0" \
> + "netargs=setenv bootargs console=${console},${baudrate} " \
> + "root=/dev/nfs rw " \
> + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp; " \
> + "run videoargs\0" \
> + "netboot=echo Booting from net ...; " \
> + "run netargs; " \
> + "if test ${ip_dyn} = yes; then " \
> + "setenv get_cmd dhcp; " \
> + "else " \
> + "setenv get_cmd tftp; " \
> + "fi; " \
> + "${get_cmd} ${uimage}; " \
> + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
> + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
> + "bootm ${loadaddr} - ${fdt_addr}; " \
> + "else " \
> + "if test ${boot_fdt} = try; then " \
> + "bootm; " \
> + "else " \
> + "echo WARN: Cannot load the DT; " \
> + "fi; " \
> + "fi; " \
> + "else " \
> + "bootm; " \
> + "fi;\0" \
> + "videoargs=" \
> + "if hdmidet; then " \
> + "setenv bootargs ${bootargs} " \
> + "video=mxcfb0:dev=hdmi,1920x1080M at 60,if=RGB24; " \
> + "fi; " \
> + "setenv bootargs ${bootargs} " \
> + "video=mxcfb1:off; " \
> + "i2c dev 2; " \
> + "if i2c probe 0x38; then " \
> + "setenv bootargs ${bootargs} " \
> + "screen_alternate=yes;" \
> + "fi;\0"
> +
> +
You could even think about to use the "distro" environment.
> +#define CONFIG_ARP_TIMEOUT 200UL
> +
> +#undef CONFIG_SYS_PROMPT
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define CONFIG_SYS_PROMPT "VAR-SOM-MX6 (NAND) => "
> +#else
> +#define CONFIG_SYS_PROMPT "VAR-SOM-MX6 (MMC) => "
> +#endif
We mostly decide to not use a custom prompt for the board - see commit
to remove them, letting the same prompt for all boards.
> +
> +#define CONFIG_SYS_MEMTEST_START 0x10000000
> +#define CONFIG_SYS_MEMTEST_END 0x10010000
> +#define CONFIG_SYS_MEMTEST_SCRATCH 0x10800000
> +
> +#define CONFIG_STACKSIZE (128 * 1024)
> +
> +/* Physical Memory Map */
> +#define CONFIG_NR_DRAM_BANKS 1
> +#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
> +
> +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
> +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
> +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
> +
> +#define CONFIG_SYS_INIT_SP_OFFSET \
> + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
> +#define CONFIG_SYS_INIT_SP_ADDR \
> + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
> +
> +/* FLASH and environment organization */
> +#define CONFIG_ENV_SIZE (8 * 1024)
> +
> +#ifdef CONFIG_SYS_BOOT_NAND
> +#define CONFIG_SYS_USE_NAND
> +#define CONFIG_ENV_IS_IN_NAND
> +/* NAND boot config */
> +#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE
> +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x200000
> +#define CONFIG_SYS_NAND_PAGE_SIZE 2048
> +#else
> +#define CONFIG_ENV_IS_IN_MMC
> +#endif
> +
> +#if defined(CONFIG_MX6DL)
> +#define CONFIG_DEFAULT_FDT_FILE "imx6dl-var-som.dtb"
> +#elif defined(CONFIG_MX6S)
> +#define CONFIG_DEFAULT_FDT_FILE "imx6dl-var-som.dtb"
> +#elif defined(CONFIG_MX6Q)
> +#define CONFIG_DEFAULT_FDT_FILE "imx6q-var-som.dtb"
> +#else
> +#define CONFIG_DEFAULT_FDT_FILE "imx6q-var-som.dtb"
> +#endif
> +
> +#ifdef CONFIG_SYS_USE_NAND
> +#define CONFIG_CMD_NAND
> +#define CONFIG_CMD_NAND_TRIMFFS
> +
> +/* UBI/UBIFS support */
> +#define CONFIG_CMD_UBI
> +#define CONFIG_CMD_UBIFS
> +#define CONFIG_RBTREE
> +#define CONFIG_MTD_DEVICE
> +#define CONFIG_MTD_PARTITIONS
> +#define CONFIG_CMD_MTDPARTS
> +#define CONFIG_LZO
> +
> +#define MTDIDS_DEFAULT "nand0=nandflash-0"
> +
> +/*
> + * Partions' layout for NAND is:
> + * mtd0: 2M (spl) First boot loader
> + * mtd1: 2M (u-boot, dtb)
> + * mtd2: 6M (kernel)
> + * mtd4: left (rootfs)
> + */
> +/* Default mtd partition table */
> +#define MTDPARTS_DEFAULT "mtdparts=nandflash-0:"\
> + "2m(spl),"\
> + "2m(u-boot),"\
> + "6m(kernel),"\
> + "-(rootfs)" /* ubifs */
> +
> +/* NAND stuff */
> +#define CONFIG_NAND_MXS
> +#define CONFIG_SYS_MAX_NAND_DEVICE 1
> +#define CONFIG_SYS_NAND_BASE 0x40000000
> +#define CONFIG_SYS_NAND_5_ADDR_CYCLE
> +#define CONFIG_SYS_NAND_ONFI_DETECTION
> +
> +/* DMA stuff, needed for GPMI/MXS NAND support */
> +#define CONFIG_APBH_DMA
> +#define CONFIG_APBH_DMA_BURST
> +#define CONFIG_APBH_DMA_BURST8
> +#endif
> +
> +#if defined(CONFIG_ENV_IS_IN_MMC)
> +#define CONFIG_ENV_OFFSET (0x3E0000)
> +#elif defined(CONFIG_ENV_IS_IN_NAND)
> +#undef CONFIG_ENV_SIZE
> +#define CONFIG_ENV_OFFSET (0x180000)
> +#define CONFIG_ENV_SECT_SIZE (128 << 10)
> +#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
> +#endif
> +
> +#define CONFIG_OF_LIBFDT
> +
> +/* Framebuffer */
> +#define CONFIG_VIDEO
> +#define CONFIG_VIDEO_IPUV3
> +#define CONFIG_CFB_CONSOLE
> +#define CONFIG_VGA_AS_SINGLE_DEVICE
> +#define CONFIG_SYS_CONSOLE_IS_IN_ENV
> +#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
> +#define CONFIG_VIDEO_BMP_RLE8
> +#define CONFIG_SPLASH_SCREEN
> +#define CONFIG_SPLASH_SCREEN_ALIGN
> +#define CONFIG_BMP_16BPP
> +#define CONFIG_VIDEO_LOGO
> +#define CONFIG_VIDEO_BMP_LOGO
> +#ifdef CONFIG_MX6DL
> +#define CONFIG_IPUV3_CLK 198000000
> +#else
> +#define CONFIG_IPUV3_CLK 264000000
> +#endif
> +#define CONFIG_IMX_HDMI
> +#define CONFIG_CMD_HDMIDETECT
> +#define CONFIG_IMX_VIDEO_SKIP
> +#define CONFIG_CMD_BMP
> +
> +#define PMIC_I2C_BUS 1
> +#define MX6CB_CDISPLAY_I2C_BUS 2
> +#define MX6CB_CDISPLAY_I2C_ADDR 0x38
> +
> +/* I2C Configs */
> +#define CONFIG_CMD_I2C
> +#define CONFIG_SYS_I2C
> +#define CONFIG_SYS_I2C_MXC
> +#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */
> +#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */
> +#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
> +#define CONFIG_SYS_I2C_SPEED 100000
> +
> +/* PMIC */
> +#define CONFIG_POWER
> +#define CONFIG_POWER_I2C
> +#define CONFIG_POWER_PFUZE100
> +#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08
> +
> +/* USB Configs */
> +#define CONFIG_CMD_USB
> +#ifdef CONFIG_CMD_USB
> +#define CONFIG_USB_EHCI
> +#define CONFIG_USB_EHCI_MX6
> +#define CONFIG_USB_STORAGE
> +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
> +#define CONFIG_USB_HOST_ETHER
> +#define CONFIG_USB_ETHER_ASIX
> +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
> +#define CONFIG_MXC_USB_FLAGS 0
> +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2 /* Enabled USB controller number */
> +#endif
> +
> +#define CONFIG_CI_UDC
> +#define CONFIG_USBD_HS
> +#define CONFIG_USB_GADGET_DUALSPEED
> +
> +/* Uncomment for USB Ethernet Gadget support */
> +/*
> + * #define CONFIG_USB_ETHER
> + * #define CONFIG_USB_ETH_CDC
> + */
> +#define CONFIG_NETCONSOLE
> +
> +#define CONFIG_USB_GADGET
> +#define CONFIG_CMD_USB_MASS_STORAGE
> +#define CONFIG_USB_FUNCTION_MASS_STORAGE
> +#define CONFIG_USB_GADGET_DOWNLOAD
> +#define CONFIG_USB_GADGET_VBUS_DRAW 2
> +
> +#define CONFIG_G_DNL_VENDOR_NUM 0x0525
> +#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5
> +#define CONFIG_G_DNL_MANUFACTURER "Variscite"
> +
> +/* USB Device Firmware Update support */
> +#define CONFIG_CMD_DFU
> +#define CONFIG_USB_FUNCTION_DFU
> +#define CONFIG_DFU_MMC
> +#define CONFIG_DFU_RAM
> +#ifdef CONFIG_SYS_USE_NAND
> +#define CONFIG_SYS_MAX_NAND_DEVICE 1
> +#define CONFIG_DFU_NAND
> +#endif
> +
> +#endif /* __MX6VAR_SOM_CONFIG_H */
> diff --git a/include/configs/mx6var_spl.h b/include/configs/mx6var_spl.h
> new file mode 100644
> index 0000000..54cf4f1
> --- /dev/null
> +++ b/include/configs/mx6var_spl.h
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (C) 2014 Gateworks Corporation
> + * Author: Tim Harvey <tharvey at gateworks.com>
> + *
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +#ifndef __IMX6_SPL_CONFIG_H
> +#define __IMX6_SPL_CONFIG_H
> +
> +#ifdef CONFIG_SPL
> +
> +#define CONFIG_SPL_FRAMEWORK
> +
> +/*
> + * see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:
> + * - IMX6SDL OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF
> + * - IMX6DQ has 2x IRAM of IMX6SDL but we intend to support IMX6SDL as well
> + * - BOOT ROM stack is at 0x0091FFB8
> + * - if icache/dcache is enabled (eFuse/strapping controlled) then the
> + * IMX BOOT ROM will setup MMU table at 0x00918000, therefore we need to
> + * fit between 0x00907000 and 0x00918000.
> + * - Additionally the BOOT ROM loads what they consider the firmware image
> + * which consists of a 4K header in front of us that contains the IVT, DCD
> + * and some padding thus 'our' max size is really 0x00908000 - 0x00918000
> + * or 64KB
> + */
> +#define CONFIG_SYS_THUMB_BUILD
> +#define CONFIG_SPL_LDSCRIPT "board/variscite/mx6var_som/u-boot-spl.lds"
> +#define CONFIG_SPL_TEXT_BASE 0x00908000
> +#define CONFIG_SPL_MAX_SIZE 0xFFFC /* ==0x10000-0x4, reserve 4Bytes for sending RAM size from SPL to U-Boot */
This is a hack - if we need an interface between SPL and u-boot, it must
be solved globally nad not for a single function. And is it not set in
the bdinfo structure ?
> +#define CONFIG_SPL_STACK 0x0091FFB8
> +#define CONFIG_SPL_LIBCOMMON_SUPPORT
> +#define CONFIG_SPL_LIBGENERIC_SUPPORT
> +#define CONFIG_SPL_SERIAL_SUPPORT
> +#define CONFIG_SPL_I2C_SUPPORT
> +#define CONFIG_SPL_GPIO_SUPPORT
> +
You set again a lot of stuff instead of using mx6_spl.h. You should
include this file, undefined the constants that are conflicting with
your setup without duplicating all stuff.
> +/* NAND support */
> +#if defined(CONFIG_SPL_NAND_SUPPORT)
> +#define CONFIG_SPL_NAND_MXS
> +#define CONFIG_SPL_DMA_SUPPORT
> +#endif
> +
> +/* MMC support */
> +#if defined(CONFIG_SPL_MMC_SUPPORT)
> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 138 /* offset 69KB */
> +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 800 /* 400 KB */
> +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1
> +#define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024)
> +#endif
> +
> +/* SATA support */
> +#if defined(CONFIG_SPL_SATA_SUPPORT)
> +#define CONFIG_SPL_SATA_BOOT_DEVICE 0
> +#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION 1
> +#endif
> +
> +/* Define the payload for FAT/EXT support */
> +#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
> +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
> +#define CONFIG_SPL_LIBDISK_SUPPORT
> +#endif
> +
> +#if defined(CONFIG_MX6SX)
> +#define CONFIG_SPL_BSS_START_ADDR 0x88200000
> +#define CONFIG_SPL_BSS_MAX_SIZE 0x100000 /* 1 MB */
> +#define CONFIG_SYS_SPL_MALLOC_START 0x88300000
> +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x3200000 /* 50 MB */
> +#define CONFIG_SYS_TEXT_BASE 0x87800000
> +#else
> +#define CONFIG_SPL_BSS_START_ADDR 0x18200000
> +#define CONFIG_SPL_BSS_MAX_SIZE 0x100000 /* 1 MB */
> +#define CONFIG_SYS_SPL_MALLOC_START 0x18300000
> +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x3200000 /* 50 MB */
> +#define CONFIG_SYS_TEXT_BASE 0x17800000
> +#endif
> +#endif
> +
> +#endif
> diff --git a/tools/logos/variscite.bmp b/tools/logos/variscite.bmp
I tend to reject this. You have already implemented a splashscreen and
you can load an image to the display. Is it not enough ?
> new file mode 100644
> index 0000000000000000000000000000000000000000..f3ca27ceb169cd5d174fa919248968877cb0e3d3
> GIT binary patch
> literal 15414
> zcmeHO34B!LwU2kgL_-?_NHAh*x%YW*oFT>rL2W at 1H!9Ey5zD at apnzf#MH;{mV~o*=
> z6n&VdJdo9}8iv3iVKoq03NnF<0ok<4kPu*!FqZ;F&pYRQ_s(MTMEYxgCYA$t`Id9;
> z`G05m&Nuw%+OuP)2&Rsa5fO>_b{wxRcwG~5E#3ufjfse$3p>RX5dj^4l?)wIQsAyT
Best regards,
Stefano Babic
--
=====================================================================
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
More information about the U-Boot
mailing list