From: Stefano Babic <sbabic@denx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] imx: mx6var_som: Add support for Variscite mx6 boards
Date: Thu, 7 Apr 2016 06:46:04 +0200 [thread overview]
Message-ID: <5705E60C.5070201@denx.de> (raw)
In-Reply-To: <20160331135356.GA56795@ubuntu>
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@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@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@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@freescale.com>
> + *
> + * Copyright (C) 2016 Variscite Ltd. All Rights Reserved.
> + *
> + * Author: Eran Matityahu <eran.m@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@denx.de>
> + *
> + * (C) Copyright 2010
> + * Texas Instruments, <www.ti.com>
> + * Aneesh V <aneesh@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@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@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
=====================================================================
prev parent reply other threads:[~2016-04-07 4:46 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-31 13:53 [U-Boot] [PATCH] imx: mx6var_som: Add support for Variscite mx6 boards Eran Matityahu
2016-04-06 14:10 ` Stefano Babic
2016-04-07 4:46 ` Stefano Babic [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5705E60C.5070201@denx.de \
--to=sbabic@denx.de \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.