ventana: Add Gateworks Ventana family support
PATCH 1/1 ventana: Add Gateworks Ventana family support
Gateworks Ventana is a product family based on the i.MX6. This patch adds support for all boards in the Ventana family. Where possible, data from the boards EEPROM is used to determine various details about the board at runtime.
--- board/gateworks/gw_ventana/1066mhz_4x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_2x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_4x128mx16.cfg | 42 + board/gateworks/gw_ventana/Makefile | 10 + board/gateworks/gw_ventana/README | 49 + board/gateworks/gw_ventana/clocks.cfg | 41 + board/gateworks/gw_ventana/ddr-setup.cfg | 96 ++ board/gateworks/gw_ventana/gw_ventana.c | 1729 ++++++++++++++++++++++ board/gateworks/gw_ventana/gw_ventana.cfg | 42 + board/gateworks/gw_ventana/ventana_eeprom.h | 107 ++ boards.cfg | 7 +- include/configs/gw_ventana.h | 409 +++++ 12 files changed, 2615 insertions(+), 1 deletion(-) create mode 100644 board/gateworks/gw_ventana/1066mhz_4x128mx16.cfg create mode 100644 board/gateworks/gw_ventana/800mhz_2x128mx16.cfg create mode 100644 board/gateworks/gw_ventana/800mhz_4x128mx16.cfg create mode 100644 board/gateworks/gw_ventana/Makefile create mode 100644 board/gateworks/gw_ventana/README create mode 100644 board/gateworks/gw_ventana/clocks.cfg create mode 100644 board/gateworks/gw_ventana/ddr-setup.cfg create mode 100644 board/gateworks/gw_ventana/gw_ventana.c create mode 100644 board/gateworks/gw_ventana/gw_ventana.cfg create mode 100644 board/gateworks/gw_ventana/ventana_eeprom.h create mode 100644 include/configs/gw_ventana.h
board/gateworks/gw_ventana/1066mhz_4x128mx16.cfg new file +42 -0
@@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Boundary Devices + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +DATA 4, MX6_MMDC_P0_MDPDC, 0x00020036 +DATA 4, MX6_MMDC_P0_MDCFG0, 0x555A7974 +DATA 4, MX6_MMDC_P0_MDCFG1, 0xDB538F64 +DATA 4, MX6_MMDC_P0_MDCFG2, 0x01FF00DB +DATA 4, MX6_MMDC_P0_MDRWD, 0x000026D2 +DATA 4, MX6_MMDC_P0_MDOR, 0x005A1023 +DATA 4, MX6_MMDC_P0_MDOTC, 0x09444040 +DATA 4, MX6_MMDC_P0_MDPDC, 0x00025576 +DATA 4, MX6_MMDC_P0_MDASP, 0x00000027 +DATA 4, MX6_MMDC_P0_MDCTL, 0x831A0000 +DATA 4, MX6_MMDC_P0_MDSCR, 0x04088032 +DATA 4, MX6_MMDC_P0_MDSCR, 0x00008033 +DATA 4, MX6_MMDC_P0_MDSCR, 0x00428031 +DATA 4, MX6_MMDC_P0_MDSCR, 0x19308030 +DATA 4, MX6_MMDC_P0_MDSCR, 0x04008040 +DATA 4, MX6_MMDC_P0_MPZQHWCTRL, 0xA1390003 +DATA 4, MX6_MMDC_P1_MPZQHWCTRL, 0xA1390003 +DATA 4, MX6_MMDC_P0_MDREF, 0x00005800 +DATA 4, MX6_MMDC_P0_MPODTCTRL, 0x00022227 +DATA 4, MX6_MMDC_P1_MPODTCTRL, 0x00022227 +DATA 4, MX6_MMDC_P0_MPDGCTRL0, 0x42720306 +DATA 4, MX6_MMDC_P0_MPDGCTRL1, 0x026F0266 +DATA 4, MX6_MMDC_P1_MPDGCTRL0, 0x4273030A +DATA 4, MX6_MMDC_P1_MPDGCTRL1, 0x02740240 +DATA 4, MX6_MMDC_P0_MPRDDLCTL, 0x45393B3E +DATA 4, MX6_MMDC_P1_MPRDDLCTL, 0x403A3747 +DATA 4, MX6_MMDC_P0_MPWRDLCTL, 0x40434541 +DATA 4, MX6_MMDC_P1_MPWRDLCTL, 0x473E4A3B +DATA 4, MX6_MMDC_P0_MPWLDECTRL0, 0x0011000E +DATA 4, MX6_MMDC_P0_MPWLDECTRL1, 0x000E001B +DATA 4, MX6_MMDC_P1_MPWLDECTRL0, 0x00190015 +DATA 4, MX6_MMDC_P1_MPWLDECTRL1, 0x00070018 +DATA 4, MX6_MMDC_P0_MPMUR0, 0x00000800 +DATA 4, MX6_MMDC_P1_MPMUR0, 0x00000800 +DATA 4, MX6_MMDC_P0_MDSCR, 0x00000000 +DATA 4, MX6_MMDC_P0_MAPSR, 0x00011006
board/gateworks/gw_ventana/800mhz_2x128mx16.cfg new file +42 -0
42 lines not on this page · raw message
board/gateworks/gw_ventana/800mhz_4x128mx16.cfg new file +42 -0
42 lines not on this page · raw message
board/gateworks/gw_ventana/Makefile new file +10 -0
@@ -0,0 +1,10 @@ +# +# Copyright (C) 2012-2013, Guennadi Liakhovetski <[email protected]> +# (C) Copyright 2012-2013 Freescale Semiconductor, Inc. +# Copyright (C) 2013, Gateworks Corporation +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y := gw_ventana.o +
board/gateworks/gw_ventana/README new file +49 -0
49 lines not on this page · raw message
board/gateworks/gw_ventana/clocks.cfg new file +41 -0
41 lines not on this page · raw message
board/gateworks/gw_ventana/ddr-setup.cfg new file +96 -0
96 lines not on this page · raw message
board/gateworks/gw_ventana/gw_ventana.c new file +1729 -0
1,729 lines not on this page · raw message
board/gateworks/gw_ventana/gw_ventana.cfg new file +42 -0
42 lines not on this page · raw message
board/gateworks/gw_ventana/ventana_eeprom.h new file +107 -0
107 lines not on this page · raw message
boards.cfg +6 -1
@@ -295,6 +295,7 @@ Active arm armv7 mx6 - udoo udoo_qua Active arm armv7 mx6 - wandboard wandboard_dl wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_quad wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_solo wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512 Fabio Estevam <[email protected]> +Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]> Active arm armv7 mx6 boundary nitrogen6x mx6qsabrelite nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024,SABRELITE Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl2g nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl2g.cfg,MX6DL,DDR_MB=2048 Eric Nelson <[email protected]>
@@ -308,7 +309,11 @@ Active arm armv7 mx6 freescale mx6qsabreauto Active arm armv7 mx6 freescale mx6sabresd mx6dlsabresd mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6sabresd mx6qsabresd mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6slevk mx6slevk mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL Fabio Estevam <[email protected]> -Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanaq1gspi gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH Tim Harvey <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanaq gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512 Tim Harvey <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanaq1g gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024 Tim Harvey <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanadl gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512 Tim Harvey <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanadl1g gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024 Tim Harvey <[email protected]> Active arm armv7 mx6 solidrun hummingboard hummingboard_solo hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512 Jon Nettleton <[email protected]> Active arm armv7 omap3 - overo omap3_overo - Steve Sakoman <[email protected]> Active arm armv7 omap3 - pandora omap3_pandora - Grazvydas Ignotas <[email protected]>
include/configs/gw_ventana.h new file +409 -0
409 lines not on this page · raw message
Signature · 1 line
1.8.4.2
PATCH 1/1 ventana: Add Gateworks Ventana family support
board/gateworks/gw_ventana/gw_ventana.c line 1218
Quoted 12 lines · Tim Harvey
board/gateworks/gw_ventana/gw_ventana.c new file +12
-0+static int setup_pmic_voltages (void ) +{ +int ret; +unsigned char value, rev_id =0 ; + + ret =i2c_set_bus_num (1 ); +if (ret) +return ret; +if (!i2c_probe (0x8 )) { +if (i2c_read (0x8 ,0 ,1 , &value,1 )) { +printf ("Read device ID error!\n" ); +return -1 ;
Please use the PMIC API to read/write to the PMIC.
Regards,
Fabio Estevam
PATCH 1/1 ventana: Add Gateworks Ventana family support
Quoted 16 lines · Fabio Estevam
board/gateworks/gw_ventana/gw_ventana.c line 1218
Quoted 12 lines · Tim Harvey
board/gateworks/gw_ventana/gw_ventana.c new file +12
-0+static int setup_pmic_voltages (void ) +{ +int ret; +unsigned char value, rev_id =0 ; + + ret =i2c_set_bus_num (1 ); +if (ret) +return ret; +if (!i2c_probe (0x8 )) { +if (i2c_read (0x8 ,0 ,1 , &value,1 )) { +printf ("Read device ID error!\n" ); +return -1 ;Please use the PMIC API to read/write to the PMIC.
Fabio,
Thanks for the review! I see include/power/pmic.h and will take a look.
Tim
Quoted 4 lines
Regards,
Fabio Estevam
PATCH 1/1 ventana: Add Gateworks Ventana family support
In reply to Tim HarveyHi Tim,
please run script/checkpatch on your patch before next submit. The tool reports plenty of issues that must be solved for mainlining.
Quoted 10 lines · Tim Harvey
Gateworks Ventana is a product family based on the i.MX6. This patch adds support for all boards in the Ventana family. Where possible, data from the boards EEPROM is used to determine various details about the board at runtime.
Signed-off-by Tim Harvey <[email protected]>--- board/gateworks/gw_ventana/1066mhz_4x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_2x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_4x128mx16.cfg | 42 +
These three files to set up the DDR are *identical* to the files with the same name in /board/boundary/nitrogen6x.
A such as duplication is not allowed. There should be a good reason to have new files - for solidrun, different values are requested for DDR.
Please consider to refer to supplied files instead of copying.
Quoted 18 lines
board/gateworks/gw_ventana/README new file +11
-0@@ -0,0 +1,49 @@ +U-Boot for the Gateworks Ventana Product Family boards + +This file contains information for the port of U-Boot to the Gateworks +Ventana Product family boards. + +1. Boot source, boot from NAND +------------------------------ + +The i.MX6 BOOT ROM expects some headers that provide details of NAND layout +and bad block information (referred to as 'bootstreams') which are replicated +multiple times in NAND.The number of replications is configurable through
board/gateworks/gw_ventana/README line 14
Quoted 3 lines
board/gateworks/gw_ventana/README new file +3
-0+board strapping options and eFUSE settings. The Freescale 'kobs-ng' +application from the Freescale LTIB BSP, which runs under Linux, must be used +to program the bootstream in order to setup the replicated headers correctly.
The behavior is quite different as we have currently in mainline. With kobs-ng you flash u-boot.bin, while the result image for i.MXes in mailine is u-boot.imx (u-boot.bin with imx header).
This behavior is also different to the roadmap we have discussed some times ago for the i.MX6. We will move i.MX to use SPL, and the bad blocks handling, not managed by the BOOT ROM, will be done inside SPL.
board/gateworks/gw_ventana/README line 26
Quoted 12 lines
board/gateworks/gw_ventana/README new file +12
-0+ +The Gateworks Ventana boards with NAND flash have been factory programmed +such that their eFUSE settings expect 2 copies of the boostream (this is +specified by providing kobs-ng with the --search_exponent=1 argument). Once in +Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream +with: + +kobs-ng init -v -x --search_exponent=1 u-boot.imx + +This information is taken from + +https://trac.gateworks.com/wiki/ventana%3Abuild_uboot
The link is broken - there is no permission with https, while http works.
board/gateworks/gw_ventana/README line 36
Quoted 10 lines
board/gateworks/gw_ventana/README new file +10
-0+ +2. Build +-------- + +There are several Gateworks Ventana boards that share a simliar design but +vary based on CPU, Memory configuration, and subloaded devices. Although +the subloaded devices are handled dynamically in the bootloader using +factory configured EEPROM data to modify the device-tree, the CPU choice +(IMX6Q vs IMX6DL) and memory configurations are currently compile-time +options.
We will have another advantage with SPL, that is we can have a single image working on different i.MX6 variants (Solo/Dual/Quad).
board/gateworks/gw_ventana/README line 48
Quoted 12 lines
board/gateworks/gw_ventana/README new file +12
-0+ +The following Gateworks Ventana configurations exist: + gwventanaq1gspi: MX6Q,1GB,SPI FLASH + gwventanaq : MX6Q,512MB,NAND FLASH + gwventanaq1g : MX6Q,1GB,NAND FLASH + gwventanadl : MX6DL,512MB,NAND FLASH + gwventanadl1g : MX6DL,1GB,NAND FLASH + +To build U-Boot for the MX6Q,1GB,NAND FLASH for example: + + make gwventanaq1g_config + make u-boot.imx
u-boot.imx should be the default target. But it seems weird you build u-boot.imx and then discard it (or am I wrong ?) to take u-boot.bin.
board/gateworks/gw_ventana/clocks.cfg line 3
Quoted 10 lines
board/gateworks/gw_ventana/README new file +1
-0+board/gateworks/gw_ventana/clocks.cfg new file +3
-0@@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 Gateworks Corporation + *
This is the only change in the file. The original file has a Boundary Device Copyright. You cannot simply substitute the original Copyright with your own.
clocks.cfg is then (apart some whitespaces) identical to clocks.cfg in nitrogen. Please do not duplicate files.
Quoted 9 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0@@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Boundary Devices + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Device Configuration Data (DCD)
board/gateworks/gw_ventana/ddr-setup.cfg line 16
Quoted 10 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+ * + * Each entry must have the format: + * Addr-type Address Value + * + * where: + * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ +
even ddr-setup.cfg is identical (but here Copyright is untouched). It seems we do not need any special .cfg file for the board.
Quoted 279 lines
board/gateworks/gw_ventana/gw_ventana.c new file +273
-0@@ -0,0 +1,1729 @@ +/* +* Copyright (C) 2013 Gateworks Corporation +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/mxc_hdmi.h> +#include <asm/arch/sys_proto.h> +#include <asm/errno.h> +#include <asm/gpio.h> +#include <asm/imx-common/iomux-v3.h> +#include <asm/imx-common/mxc_i2c.h> +#include <asm/imx-common/boot_mode.h> +#include <asm/imx-common/sata.h> +#include <linux/list.h> +#include <linux/ctype.h> +#include <linux/fb.h> +#include <mmc.h> +#include <fsl_esdhc.h> +#include <micrel.h> +#include <miiphy.h> +#include <netdev.h> +#include <ipu_pixfmt.h> +#include <i2c.h> +#include <fdt_support.h> +#include <jffs2/load_kernel.h> +#include <mtd_node.h> +#include <spi_flash.h> +#include <hwconfig.h> +#include <fuse.h> + +#include "ventana_eeprom.h" + +DECLARE_GLOBAL_DATA_PTR ; + +#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + 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_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 ENET_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 SPI_PAD_CTRL (PAD_CTL_HYS | \ + PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#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 DIO_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST) + +#define WEAK_PULLUP (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ + PAD_CTL_SRE_SLOW) + +#define OUTPUT_40OHM (PAD_CTL_SPEED_MED|PAD_CTL_DSE_40ohm) + +/* UART1, RS485 */ +iomux_v3_cfg_t const uart1_pads[] = { +MX6_PAD_SD3_DAT6__UART1_RX_DATA |MUX_PAD_CTRL (UART_PAD_CTRL ), +MX6_PAD_SD3_DAT7__UART1_TX_DATA |MUX_PAD_CTRL (UART_PAD_CTRL ), +}; + +/* UART2, Console */ +iomux_v3_cfg_t const uart2_pads[] = { +MX6_PAD_SD4_DAT7__UART2_TX_DATA |MUX_PAD_CTRL (UART_PAD_CTRL ), +MX6_PAD_SD4_DAT4__UART2_RX_DATA |MUX_PAD_CTRL (UART_PAD_CTRL ), +}; + +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL) + +/* I2C1, GSC */ +struct i2c_pads_info i2c_pad_info0 = { + .scl = { + .i2c_mode =MX6_PAD_EIM_D21__I2C1_SCL |PC , + .gpio_mode =MX6_PAD_EIM_D21__GPIO3_IO21 |PC , + .gp =IMX_GPIO_NR (3 ,21 ) + }, + .sda = { + .i2c_mode =MX6_PAD_EIM_D28__I2C1_SDA |PC , + .gpio_mode =MX6_PAD_EIM_D28__GPIO3_IO28 |PC , + .gp =IMX_GPIO_NR (3 ,28 ) + } +}; + +/* I2C2, PFUSE, PCIe Switch/Clock/Mezz */ +struct i2c_pads_info i2c_pad_info1 = { + .scl = { + .i2c_mode =MX6_PAD_KEY_COL3__I2C2_SCL |PC , + .gpio_mode =MX6_PAD_KEY_COL3__GPIO4_IO12 |PC , + .gp =IMX_GPIO_NR (4 ,12 ) + }, + .sda = { + .i2c_mode =MX6_PAD_KEY_ROW3__I2C2_SDA |PC , + .gpio_mode =MX6_PAD_KEY_ROW3__GPIO4_IO13 |PC , + .gp =IMX_GPIO_NR (4 ,13 ) + } +}; + +/* I2C3, Accel, Audio Codec, Video Decoder, Video Encoder, MIPI, LVDS, DIO */ +struct i2c_pads_info i2c_pad_info2 = { + .scl = { + .i2c_mode =MX6_PAD_GPIO_3__I2C3_SCL |PC , + .gpio_mode =MX6_PAD_GPIO_3__GPIO1_IO03 |PC , + .gp =IMX_GPIO_NR (1 ,3 ) + }, + .sda = { + .i2c_mode =MX6_PAD_GPIO_6__I2C3_SDA |PC , + .gpio_mode =MX6_PAD_GPIO_6__GPIO1_IO06 |PC , + .gp =IMX_GPIO_NR (1 ,6 ) + } +}; + +/* MMC */ +iomux_v3_cfg_t const usdhc3_pads[] = { +MX6_PAD_SD3_CLK__SD3_CLK |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_CMD__SD3_CMD |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_DAT0__SD3_DATA0 |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_DAT1__SD3_DATA1 |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_DAT2__SD3_DATA2 |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_DAT3__SD3_DATA3 |MUX_PAD_CTRL (USDHC_PAD_CTRL ), +MX6_PAD_SD3_DAT5__GPIO7_IO00 |MUX_PAD_CTRL (NO_PAD_CTRL ),/* CD */ +}; + +/* ENET */ +iomux_v3_cfg_t const enet_pads[] = { +MX6_PAD_ENET_MDIO__ENET_MDIO |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_ENET_MDC__ENET_MDC |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TXC__RGMII_TXC |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TD0__RGMII_TD0 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TD1__RGMII_TD1 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TD2__RGMII_TD2 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TD3__RGMII_TD3 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_ENET_REF_CLK__ENET_TX_CLK |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RXC__RGMII_RXC |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RD0__RGMII_RD0 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RD1__RGMII_RD1 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RD2__RGMII_RD2 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RD3__RGMII_RD3 |MUX_PAD_CTRL (ENET_PAD_CTRL ), +MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL |MUX_PAD_CTRL (ENET_PAD_CTRL ), +/* PHY nRST */ +MX6_PAD_ENET_TXD0__GPIO1_IO30 |MUX_PAD_CTRL (NO_PAD_CTRL ), +}; + +/* NAND */ +iomux_v3_cfg_t const nfc_pads[] = { +MX6_PAD_NANDF_CLE__NAND_CLE |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_ALE__NAND_ALE |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_WP_B__NAND_WP_B |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_RB0__NAND_READY_B |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_CS0__NAND_CE0_B |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_SD4_CMD__NAND_RE_B |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_SD4_CLK__NAND_WE_B |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D0__NAND_DATA00 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D1__NAND_DATA01 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D2__NAND_DATA02 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D3__NAND_DATA03 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D4__NAND_DATA04 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D5__NAND_DATA05 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D6__NAND_DATA06 |MUX_PAD_CTRL (NO_PAD_CTRL ), +MX6_PAD_NANDF_D7__NAND_DATA07 |MUX_PAD_CTRL (NO_PAD_CTRL ), +}; + +#ifdef CONFIG_CMD_NAND +static void setup_gpmi_nand (void ) +{ +struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR ; + +/* config gpmi nand iomux */ +imx_iomux_v3_setup_multiple_pads (nfc_pads,ARRAY_SIZE (nfc_pads)); + +/* 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 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 + +static void setup_iomux_enet (void ) +{ +imx_iomux_v3_setup_multiple_pads (enet_pads,ARRAY_SIZE (enet_pads)); + +/* toggle PHY_RST# */ +gpio_direction_output (IMX_GPIO_NR (1 ,30 ),0 ); +mdelay (2 ); +gpio_set_value (IMX_GPIO_NR (1 ,30 ),1 ); +} + +static void setup_iomux_uart (void ) +{ +imx_iomux_v3_setup_multiple_pads (uart1_pads,ARRAY_SIZE (uart1_pads)); +imx_iomux_v3_setup_multiple_pads (uart2_pads,ARRAY_SIZE (uart2_pads)); +} + +#ifdef CONFIG_USB_EHCI_MX6 +iomux_v3_cfg_t const usb_pads[] = { +MX6_PAD_GPIO_1__USB_OTG_ID |MUX_PAD_CTRL (WEAK_PULLUP ), +MX6_PAD_KEY_COL4__USB_OTG_OC |MUX_PAD_CTRL (WEAK_PULLUP ), +MX6_PAD_EIM_D22__GPIO3_IO22 |MUX_PAD_CTRL (OUTPUT_40OHM ), +}; + +int board_ehci_hcd_init (int port) +{ +/* Reset USB hub */ +imx_iomux_v3_setup_pad (MX6_PAD_SD1_DAT0__GPIO1_IO16 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,16 ),0 ); +mdelay (2 ); +gpio_set_value (IMX_GPIO_NR (1 ,16 ),1 ); + +return 0 ; +} + +int board_ehci_power (int port,int on) +{ +if (port) +return 0 ; +gpio_set_value (IMX_GPIO_NR (3 ,22 ), on); +return 0 ; +} +#endif /* CONFIG_USB_EHCI_MX6 */ + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg usdhc_cfg[1 ] = { + {USDHC3_BASE_ADDR }, +}; + +int board_mmc_getcd (struct mmc *mmc) +{ +struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; +int ret =0 ; + +if (cfg->esdhc_base ==USDHC3_BASE_ADDR ) { +/* Card Detect */ +gpio_direction_input (IMX_GPIO_NR (7 ,0 )); + ret = !gpio_get_value (IMX_GPIO_NR (7 ,0 )); + } + +return ret; +} + +int board_mmc_init (bd_t *bis)
board/gateworks/gw_ventana/gw_ventana.c line 283
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+{ +s32 status =0 ; +u32 index =0 ; + + usdhc_cfg[0 ].sdhc_clk =mxc_get_clock (MXC_ESDHC3_CLK ); + usdhc_cfg[0 ].max_bus_width =4 ; + +for (index =0 ; index <CONFIG_SYS_FSL_USDHC_NUM ; ++index) { +switch (index) { +case 0 :
I know I am the first responsible for this code. But if CONFIG_SYS_FSL_USDHC_NUM = 1 (and this is not easy changable without modifying the board), why do we need a loop ?
board/gateworks/gw_ventana/gw_ventana.c line 300
Quoted 1 line
board/gateworks/gw_ventana/gw_ventana.c new file +1
-0+/* Gateworks System Controller I2C access may NAK when busy - use
Wrong multiline comment. It should be:
/*
* your comment
* here
*/
Quoted 8 lines
board/gateworks/gw_ventana/gw_ventana.c new file +8
-0+* retries. +*/ +int gsc_i2c_read (uchar chip,uint addr,int alen,uchar *buf,int len) +{ +int retry =3 ; +int n =0 ; +int ret; +
board/gateworks/gw_ventana/gw_ventana.c line 318
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+while (n++ < retry) { + ret =i2c_read (chip, addr, alen, buf, len); +if (!ret) +break ; +printf ("%s: 0x%02x 0x%02x retry%d: %d\n" , __func__, chip, addr, + n, ret); +if (ret != -ENODEV ) +break ; +mdelay (10 ); + }
Whcih is the benefit of trying three times ?
Quoted 9 lines
board/gateworks/gw_ventana/gw_ventana.c new file +9
-0+int gsc_i2c_write (uchar chip,uint addr,int alen,uchar *buf,int len) +{ +int retry =3 ; +int n =0 ; +int ret; + +while (n++ < retry) { + ret =i2c_write (chip, addr, alen, buf, len); +if (!ret)
board/gateworks/gw_ventana/gw_ventana.c line 340
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+break ; +printf ("%s: 0x%02x 0x%02x retry%d: %d\n" , __func__, chip, addr, + n, ret); +if (ret != -ENODEV ) +break ; +mdelay (10 ); + } +mdelay (1 ); +return ret; +}
Same here. If first time fails, something happens. It makes no sense to try multiple times.
board/gateworks/gw_ventana/gw_ventana.c line 345
Quoted 5 lines
board/gateworks/gw_ventana/gw_ventana.c new file +5
-0+ +/* +* For SPL boot some boards need i2c before SDRAM is initialized so force +* variables to live in SRAM +*/
Agree - but then I will see SPL...
board/gateworks/gw_ventana/gw_ventana.c line 346
Quoted 1 line
board/gateworks/gw_ventana/gw_ventana.c new file +1
-0+static struct ventana_board_info __attribute__((section (".data" ))) ventana_info;
Can you explain why do you need this ?
board/gateworks/gw_ventana/gw_ventana.c line 348
Quoted 2 lines
board/gateworks/gw_ventana/gw_ventana.c new file +2
-0+ +/* read ventana EEPROM and return structure or NULL on error
Multiline comment
board/gateworks/gw_ventana/gw_ventana.c line 353
Quoted 5 lines
board/gateworks/gw_ventana/gw_ventana.c new file +5
-0+* should be called once, the first time eeprom data is needed +*/ +static void +read_eeprom (void ) +{
You have a I2C eprom. This is supported in U-Boot. Why do you not set CONFIG_SYS_I2C_EEPROM_ADDR in your config file and use general code ?
It seems to me you can drop your own read/write_eeprom() function.
Quoted 19 lines
board/gateworks/gw_ventana/gw_ventana.c new file +19
-0+int i; +int chksum; +struct ventana_board_info *info = &ventana_info; +unsigned char *buf = (unsigned char *)&ventana_info; +int n =0 ; + +memset (info,0 ,sizeof (ventana_info)); + +/* wait for bus and device exist - we will not boot w/o our EEPROM */ +while (1 ) { +if (0 ==i2c_set_bus_num (0 ) &&0 ==i2c_probe (0x51 )) +break ; +mdelay (1 ); + n++; + } + +/* read eeprom config section */ +if (gsc_i2c_read (0x51 ,0x00 ,1 , buf,sizeof (ventana_info))) { +printf ("EEPROM: Failed to read EEPROM\n" );
board/gateworks/gw_ventana/gw_ventana.c line 382
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ info->model[0 ] =0 ; +return ; + } + +/* sanity checks */ +if (info->model[0 ] !='G' || info->model[1 ] !='W' ) { +printf ("EEPROM: Invalid Model in EEPROM\n" ); + info->model[0 ] =0 ; +return ; + }
You can do your checks on the pyload after reading from the storage and using common functions.
Quoted 21 lines
board/gateworks/gw_ventana/gw_ventana.c new file +21
-0+#ifdef CONFIG_CMD_GSC +int read_hwmon (const char *name,uint reg,uint size,uint low,uint high) +{ +unsigned char buf[3 ]; +uint ui; +int ret; + +printf ("%-8s:" , name); +memset (buf,0 ,sizeof (buf)); +if (gsc_i2c_read (0x29 , reg,1 , buf, size)) { +printf ("fRD\n" ); + ret =-1 ; + }else { + ret =0 ; + ui = buf[0 ] | (buf[1 ]<<8 ) | (buf[2 ]<<16 ); +if (ui ==0xffffff ) { +printf ("fVL" ); + }else if (ui < low) { +printf ("%d fLO" , ui); + ret =-2 ; + }else if (ui > high) {
board/gateworks/gw_ventana/gw_ventana.c line 425
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+printf ("%d fHI" , ui); + ret =-3 ; + }else { +printf ("%d" , ui); + } + } +printf ("\n" ); + +return ret; +}
I need help - I have not understood. This functions prints only something - return values is discarded when function is called. Buf is filled, but can you better explain the purpose of the function.
Quoted 50 lines
board/gateworks/gw_ventana/gw_ventana.c new file +50
-0+ +int do_gsc (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]) +{ +struct ventana_board_info *info = &ventana_info; + +i2c_set_bus_num (0 ); +if ((strncasecmp ((const char *)info->model,"GW51" ,4 ) ==0 )) { +read_hwmon ("Temp" ,0x00 ,2 ,0 ,9000 ); +read_hwmon ("VIN" ,0x02 ,3 ,8000 ,60000 ); +read_hwmon ("VDD_3P3" ,0x05 ,3 ,3300 *0.9 ,3300 *1.1 ); +read_hwmon ("VBATT" ,0x08 ,3 ,2000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_CORE" ,0x0e ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_SOC" ,0x11 ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_HIGH" ,0x14 ,3 ,3000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_DDR" ,0x17 ,3 ,1500 *0.9 ,1500 *1.1 ); +read_hwmon ("VDD_5P0" ,0x0b ,3 ,5000 *0.9 ,5000 *1.1 ); +read_hwmon ("VDD_2P5" ,0x23 ,3 ,2500 *0.9 ,2500 *1.1 ); +read_hwmon ("VDD_1P8" ,0x1d ,3 ,1800 *0.9 ,1800 *1.1 ); + }else if ((strncasecmp ((const char *)info->model,"GW52" ,4 ) ==0 )) { +read_hwmon ("Temp" ,0x00 ,2 ,0 ,9000 ); +read_hwmon ("VIN" ,0x02 ,3 ,8000 ,60000 ); +read_hwmon ("VDD_3P3" ,0x05 ,3 ,3300 *0.9 ,3300 *1.1 ); +read_hwmon ("VBATT" ,0x08 ,3 ,2000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_CORE" ,0x0e ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_SOC" ,0x11 ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_HIGH" ,0x14 ,3 ,3000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_DDR" ,0x17 ,3 ,1500 *0.9 ,1500 *1.1 ); +read_hwmon ("VDD_5P0" ,0x0b ,3 ,5000 *0.9 ,5000 *1.1 ); +read_hwmon ("VDD_2P5" ,0x23 ,3 ,2500 *0.9 ,2500 *1.1 ); +read_hwmon ("VDD_1P8" ,0x1d ,3 ,1800 *0.9 ,1800 *1.1 ); +read_hwmon ("VDD_1P0" ,0x20 ,3 ,1000 *0.9 ,1000 *1.1 ); + }else if ((strncasecmp ((const char *)info->model,"GW53" ,4 ) ==0 )) { +read_hwmon ("Temp" ,0x00 ,2 ,0 ,9000 ); +read_hwmon ("VIN" ,0x02 ,3 ,8000 ,60000 ); +read_hwmon ("VDD_3P3" ,0x05 ,3 ,3300 *0.9 ,3300 *1.1 ); +read_hwmon ("VBATT" ,0x08 ,3 ,2000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_CORE" ,0x0e ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_SOC" ,0x11 ,3 ,1175 *0.9 ,1175 *1.1 ); +read_hwmon ("VDD_HIGH" ,0x14 ,3 ,3000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_DDR" ,0x17 ,3 ,1500 *0.9 ,1500 *1.1 ); +read_hwmon ("VDD_5P0" ,0x0b ,3 ,5000 *0.9 ,5000 *1.1 ); +read_hwmon ("VDD_2P5" ,0x23 ,3 ,2500 *0.9 ,2500 *1.1 ); +read_hwmon ("VDD_1P8" ,0x1d ,3 ,1800 *0.9 ,1800 *1.1 ); +read_hwmon ("VDD_1P0" ,0x20 ,3 ,1000 *0.9 ,1000 *1.1 ); + }else if ((strncasecmp ((const char *)info->model,"GW54" ,4 ) ==0 )) { +read_hwmon ("Temp" ,0x00 ,2 ,0 ,9000 ); +read_hwmon ("VIN" ,0x02 ,3 ,8000 ,60000 ); +read_hwmon ("VDD_3P3" ,0x05 ,3 ,3300 *0.9 ,3300 *1.1 ); +read_hwmon ("VBATT" ,0x08 ,3 ,2000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_CORE" ,0x0e ,3 ,1375 *0.9 ,1375 *1.1 );
board/gateworks/gw_ventana/gw_ventana.c line 485
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+read_hwmon ("VDD_SOC" ,0x11 ,3 ,1375 *0.9 ,1375 *1.1 ); +read_hwmon ("VDD_HIGH" ,0x14 ,3 ,3000 *0.9 ,3000 *1.1 ); +read_hwmon ("VDD_DDR" ,0x17 ,3 ,1500 *0.9 ,1500 *1.1 ); +read_hwmon ("VDD_5P0" ,0x0b ,3 ,5000 *0.9 ,5000 *1.1 ); +read_hwmon ("VDD_2P5" ,0x23 ,3 ,2500 *0.9 ,2500 *1.1 ); +read_hwmon ("VDD_1P8" ,0x1d ,3 ,1800 *0.9 ,1800 *1.1 ); +read_hwmon ("VDD_1P0" ,0x20 ,3 ,1000 *0.9 ,1000 *1.1 ); + } +return 0 ; +}
I think we can do better. Most cases are duplicated. Please split into
common calls (for example, read_hwmon("Temp", 0x00, 2, 0, 9000) is
always called) and board-variations. The identification is done on a single byte (GW51-GW54): you can use a more readable switch..case instead of multiple strncmp()
Quoted 5 lines
board/gateworks/gw_ventana/gw_ventana.c new file +5
-0+ + +/* get_mac from env string, with default +*/ +static void get_mac (char *envvar,unsigned char *def)
board/gateworks/gw_ventana/gw_ventana.c line 506
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+{ +char str[20 ]; +char *env =getenv (envvar); + +if (!env) { +sprintf (str,"%02X:%02X:%02X:%02X:%02X:%02X" , + def[0 ], def[1 ], def[2 ], def[3 ], def[4 ], def[5 ]); +setenv (envvar, str); + } +}
No idea why you need it. The FEC driver takes care of MAC address and set the ethaddr variable. This seems to me wrong.
Quoted 51 lines
board/gateworks/gw_ventana/gw_ventana.c new file +51
-0+ +#ifdef CONFIG_SERIAL_TAG +/* called when setting up ATAGS before booting kernel +* populate serialnum from the following (in order of priority): +* serial# env var +* eeprom +*/ +void get_board_serial (struct tag_serialnr *serialnr) +{ +char *serial =getenv ("serial#" ); + +if (serial) { + serialnr->high =0 ; + serialnr->low =simple_strtoul (serial,NULL ,10 ); + }else if (ventana_info.model[0 ]) { + serialnr->high =0 ; + serialnr->low = ventana_info.serial; + }else { + serialnr->high =0 ; + serialnr->low =0 ; + } +} +#endif + +#ifdef CONFIG_MXC_SPI +iomux_v3_cfg_t const ecspi1_pads[] = { +/* SS1 */ +MX6_PAD_EIM_D19__GPIO3_IO19 |MUX_PAD_CTRL (SPI_PAD_CTRL ), +MX6_PAD_EIM_D17__ECSPI1_MISO |MUX_PAD_CTRL (SPI_PAD_CTRL ), +MX6_PAD_EIM_D18__ECSPI1_MOSI |MUX_PAD_CTRL (SPI_PAD_CTRL ), +MX6_PAD_EIM_D16__ECSPI1_SCLK |MUX_PAD_CTRL (SPI_PAD_CTRL ), +}; + +static void setup_spi (void ) +{ +gpio_direction_output (CONFIG_SF_DEFAULT_CS ,1 ); +imx_iomux_v3_setup_multiple_pads (ecspi1_pads, +ARRAY_SIZE (ecspi1_pads)); +} +#endif + +int board_phy_config (struct phy_device *phydev) +{ +unsigned short val; + +/* Marvel 88E1510 */ +if (phydev->phy_id ==0x1410dd1 ) { +/* Errata 3.1 - PHY initialization */ +phy_write (phydev,MDIO_DEVAD_NONE ,22 ,0x00ff ); +phy_write (phydev,MDIO_DEVAD_NONE ,17 ,0x214b ); +phy_write (phydev,MDIO_DEVAD_NONE ,16 ,0x2144 );
board/gateworks/gw_ventana/gw_ventana.c line 567
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+phy_write (phydev,MDIO_DEVAD_NONE ,17 ,0x0c28 ); +phy_write (phydev,MDIO_DEVAD_NONE ,16 ,0x2146 ); +phy_write (phydev,MDIO_DEVAD_NONE ,17 ,0xb233 ); +phy_write (phydev,MDIO_DEVAD_NONE ,16 ,0x214d ); +phy_write (phydev,MDIO_DEVAD_NONE ,17 ,0xcc0c ); +phy_write (phydev,MDIO_DEVAD_NONE ,16 ,0x2159 ); +phy_write (phydev,MDIO_DEVAD_NONE ,22 ,0x00fb ); +phy_write (phydev,MDIO_DEVAD_NONE ,7 ,0xc00d ); +phy_write (phydev,MDIO_DEVAD_NONE ,22 ,0 ); +
This does not seem to me the best way to do. IMHO you should add support for Marvel 88E1510 in drivers/net/phy/, maybe as Alaska phy.
In board_phy_config() should contain only board specific initialization
- an errata means that the same initialization is common to all boards having this chip.
board/gateworks/gw_ventana/gw_ventana.c line 578
Quoted 11 lines
board/gateworks/gw_ventana/gw_ventana.c new file +11
-0+/* LED configuration (See datasheet section 2.26.4) +* LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link +* LED[1] (LNK:Green) R16_3.7:4 to 0001: on-link, blink-activity +*/ +phy_write (phydev,MDIO_DEVAD_NONE ,22 ,3 ); + val =phy_read (phydev,MDIO_DEVAD_NONE ,16 ); + val &=0xff00 ; + val |=0x0017 ; +phy_write (phydev,MDIO_DEVAD_NONE ,16 , val); +phy_write (phydev,MDIO_DEVAD_NONE ,22 ,0 ); + }
This is also part of the phy driver.
Quoted 80 lines
board/gateworks/gw_ventana/gw_ventana.c new file +80
-0+int board_eth_init (bd_t *bis) +{ +int ret; + +setup_iomux_enet (); + +#ifdef CONFIG_FEC_MXC + ret =cpu_eth_init (bis); +if (ret) +printf ("FEC MXC: %s:failed\n" , __func__); +#endif + +#ifdef CONFIG_MV_UDC +/* For otg ethernet*/ +usb_eth_initialize (bis); +#endif + +return 0 ; +} + +static void setup_board_gpio (const char *model) +{ +const char *s; +char arg[10 ]; +size_t len; +int i; +enum { + GW51xx, + GW52xx, + GW53xx, + GW54xx, +UNKNOWN , + }; +struct dio_cfg { +iomux_v3_cfg_t gpio_padmux; +unsigned gpio_param; +iomux_v3_cfg_t pwm_padmux; +unsigned pwm_param; + }; +int board_type =UNKNOWN ; +struct dio_cfg dio_cfg[] = { +/* GW51xx */ + {MX6_PAD_SD1_DAT0__GPIO1_IO16 ,IMX_GPIO_NR (1 ,16 ), +0 ,0 }, + {MX6_PAD_SD1_DAT2__GPIO1_IO19 ,IMX_GPIO_NR (1 ,19 ), +MX6_PAD_SD1_DAT2__PWM2_OUT ,2 }, + {MX6_PAD_SD1_DAT1__GPIO1_IO17 ,IMX_GPIO_NR (1 ,17 ), +MX6_PAD_SD1_DAT1__PWM3_OUT ,3 }, + {MX6_PAD_SD1_CMD__GPIO1_IO18 ,IMX_GPIO_NR (1 ,18 ), +MX6_PAD_SD1_CMD__PWM4_OUT ,4 }, + +/* GW52xx */ + {MX6_PAD_SD1_DAT0__GPIO1_IO16 ,IMX_GPIO_NR (1 ,16 ), +0 ,0 }, + {MX6_PAD_SD1_DAT2__GPIO1_IO19 ,IMX_GPIO_NR (1 ,19 ), +MX6_PAD_SD1_DAT2__PWM2_OUT ,2 }, + {MX6_PAD_SD1_DAT1__GPIO1_IO17 ,IMX_GPIO_NR (1 ,17 ), +MX6_PAD_SD1_DAT1__PWM3_OUT ,3 }, + {MX6_PAD_SD1_CLK__GPIO1_IO20 ,IMX_GPIO_NR (1 ,20 ), +0 ,0 }, + +/* GW53xx */ + {MX6_PAD_SD1_DAT0__GPIO1_IO16 ,IMX_GPIO_NR (1 ,16 ), +0 ,0 }, + {MX6_PAD_SD1_DAT2__GPIO1_IO19 ,IMX_GPIO_NR (1 ,19 ), +MX6_PAD_SD1_DAT2__PWM2_OUT ,2 }, + {MX6_PAD_SD1_DAT1__GPIO1_IO17 ,IMX_GPIO_NR (1 ,17 ), +MX6_PAD_SD1_DAT1__PWM3_OUT ,3 }, + {MX6_PAD_SD1_CLK__GPIO1_IO20 ,IMX_GPIO_NR (1 ,20 ), +0 ,0 }, + +/* GW54xx */ + {MX6_PAD_GPIO_9__GPIO1_IO09 ,IMX_GPIO_NR (1 ,9 ), +MX6_PAD_GPIO_9__PWM1_OUT ,1 }, + {MX6_PAD_SD1_DAT2__GPIO1_IO19 ,IMX_GPIO_NR (1 ,19 ), +MX6_PAD_SD1_DAT2__PWM2_OUT ,2 }, + {MX6_PAD_SD4_DAT1__GPIO2_IO09 ,IMX_GPIO_NR (2 ,9 ), +MX6_PAD_SD4_DAT1__PWM3_OUT ,3 }, + {MX6_PAD_SD4_DAT2__GPIO2_IO10 ,IMX_GPIO_NR (2 ,10 ), +MX6_PAD_SD4_DAT2__PWM4_OUT ,4 },
board/gateworks/gw_ventana/gw_ventana.c line 675
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ }; + +if (strncasecmp (model,"GW51" ,4 ) ==0 ) { + board_type = GW51xx; + +/* PANLEDG# (GRN off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL0__GPIO4_IO06 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,6 ),1 ); +
Again, this is not straightforward and difficult to read. Use tables for each board variation you want to add and split between common code and specific code.
Quoted 315 lines
board/gateworks/gw_ventana/gw_ventana.c new file +315
-0+/* PANLEDR# (RED off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW0__GPIO4_IO07 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,7 ),1 ); + +/* GPS_SHDN */ +imx_iomux_v3_setup_pad (MX6_PAD_GPIO_2__GPIO1_IO02 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,2 ),1 ); + +/* Analog video codec power enable */ +imx_iomux_v3_setup_pad (MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (5 ,20 ),1 ); + +/* Expansion IO0 - PWREN# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A19__GPIO2_IO19 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (2 ,19 ),0 ); + +/* Expansion IO1 - IRQ# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A20__GPIO2_IO18 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_input (IMX_GPIO_NR (2 ,18 )); + }/* end GW51xx */ + +else if (strncasecmp (model,"GW52" ,4 ) ==0 ) { + board_type = GW52xx; + +/* PANLEDG# (GRN off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL0__GPIO4_IO06 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,6 ),1 ); + +/* PANLEDR# (RED off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW0__GPIO4_IO07 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,7 ),1 ); + +/* MX6_LOCLED# (off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW4__GPIO4_IO15 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,15 ),1 ); + +/* GPS_SHDN */ +imx_iomux_v3_setup_pad (MX6_PAD_ENET_RXD0__GPIO1_IO27 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,27 ),1 ); + +/* Expansion IO0 - PWREN# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A19__GPIO2_IO19 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (2 ,19 ),0 ); + +/* Expansion IO1 - IRQ# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A20__GPIO2_IO18 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_input (IMX_GPIO_NR (2 ,18 )); + +/* MSATA Enable */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT0__GPIO2_IO08 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +if (is_cpu_type (MXC_CPU_MX6Q )) { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ), + (hwconfig ("msata" )) ?1 :0 ); +printf ("MSATA: %s\n" , (hwconfig ("msata" ) ? +"enabled" :"disabled" )); + }else { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ),0 ); + } + +/* USBOTG Select (PCISKT or FrontPanel) */ +imx_iomux_v3_setup_pad (MX6_PAD_GPIO_2__GPIO1_IO02 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,2 ),0 ); + +/* Analog video codec power enable */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_D31__GPIO3_IO31 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (3 ,31 ),1 ); + +/* UART2_EN# */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT3__GPIO2_IO11 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +printf ("RS232: %s\n" , (hwconfig ("rs232" )) ? +"enabled" :"disabled" ); +gpio_direction_output (IMX_GPIO_NR (2 ,11 ), + (hwconfig ("rs232" )) ?0 :1 ); +/* TODO: flush UART RX FIFO after disable */ + }/* end GW52xx */ + +else if (strncasecmp (model,"GW53" ,4 ) ==0 ) { + board_type = GW53xx; + +/* PANLEDG# (GRN off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL0__GPIO4_IO06 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,6 ),1 ); + +/* PANLEDR# (RED off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW0__GPIO4_IO07 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,7 ),1 ); + +/* MX6_LOCLED# (off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW4__GPIO4_IO15 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,15 ),1 ); + +/* GPS_SHDN */ +imx_iomux_v3_setup_pad (MX6_PAD_ENET_RXD0__GPIO1_IO27 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,27 ),1 ); + +/* Expansion IO0 - PWREN# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A19__GPIO2_IO19 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (2 ,19 ),0 ); + +/* Expansion IO1 - IRQ# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A20__GPIO2_IO18 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_input (IMX_GPIO_NR (2 ,18 )); + +/* MSATA Enable */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT0__GPIO2_IO08 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +if (is_cpu_type (MXC_CPU_MX6Q )) { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ), + (hwconfig ("msata" )) ?1 :0 ); +printf ("MSATA: %s\n" , (hwconfig ("msata" ) ? +"enabled" :"disabled" )); + }else { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ),0 ); + } + +/* Analog video codec power enable */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_D31__GPIO3_IO31 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (3 ,31 ),1 ); + +/* UART2_EN# */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT3__GPIO2_IO11 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +printf ("RS232: %s\n" , (hwconfig ("rs232" )) ? +"enabled" :"disabled" ); +gpio_direction_output (IMX_GPIO_NR (2 ,11 ), + (hwconfig ("rs232" )) ?0 :1 ); +/* TODO: flush UART RX FIFO after disable */ + }/* end GW53xx */ + +else if (strncasecmp (model,"GW54" ,4 ) ==0 ) { + board_type = GW54xx; +if (strncasecmp (model,"GW5400-A" ,8 ) ==0 ) { +/* PANLEDG# (GRN off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL0__GPIO4_IO06 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,6 ),1 ); + +/* PANLEDR# (RED off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL2__GPIO4_IO10 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,10 ),1 ); + +/* MX6_LOCLED# (off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW4__GPIO4_IO15 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,15 ),1 ); + +/* MIPI DIO */ +imx_iomux_v3_setup_pad (MX6_PAD_SD1_DAT3__GPIO1_IO21 | +MUX_PAD_CTRL (NO_PAD_CTRL )); + +/* RS485 Transmit Enable */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_D24__GPIO3_IO24 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (3 ,24 ),0 ); + +/* Expansion IO0 - PWREN# */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW0__GPIO4_IO07 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,7 ),0 ); + +/* Expansion IO1 - IRQ# */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW1__GPIO4_IO09 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_input (IMX_GPIO_NR (4 ,9 )); + } + +else if ((strncasecmp (model,"GW5400" ,6 ) ==0 ) || + (strncasecmp (model,"GW5410" ,6 ) ==0 ) + ) { +/* PANLEDG# (GRN off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_COL0__GPIO4_IO06 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,6 ),1 ); + +/* PANLEDR# (RED off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW0__GPIO4_IO07 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,7 ),1 ); + +/* MX6_LOCLED# (off) */ +imx_iomux_v3_setup_pad (MX6_PAD_KEY_ROW4__GPIO4_IO15 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,15 ),1 ); + +/* RS485 Transmit Enable */ +imx_iomux_v3_setup_pad (MX6_PAD_SD3_DAT4__GPIO7_IO01 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (7 ,1 ),0 ); + +/* Expansion IO0 - PWREN# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A19__GPIO2_IO19 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (2 ,19 ),0 ); + +/* Expansion IO1 - IRQ# */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_A20__GPIO2_IO18 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_input (IMX_GPIO_NR (2 ,18 )); + +/* MSATA Enable */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT0__GPIO2_IO08 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +if (is_cpu_type (MXC_CPU_MX6Q )) { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ), + (hwconfig ("msata" )) ? +1 :0 ); +printf ("MSATA: %s\n" , (hwconfig ("msata" ) ? +"enabled" :"disabled" )); + }else { +gpio_direction_output (IMX_GPIO_NR (2 ,8 ),0 ); + } + +/* Analog video codec power enable */ +imx_iomux_v3_setup_pad (MX6_PAD_EIM_D31__GPIO3_IO31 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (3 ,31 ),1 ); + } + +/* UART2_EN# */ +imx_iomux_v3_setup_pad (MX6_PAD_SD4_DAT3__GPIO2_IO11 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +printf ("RS232: %s\n" , (hwconfig ("rs232" )) ? +"enabled" :"disabled" ); +gpio_direction_output (IMX_GPIO_NR (2 ,11 ), + (hwconfig ("rs232" )) ?0 :1 ); +/* TODO: flush UART RX FIFO after disable */ + +/* DIOI2C_DIS# */ +imx_iomux_v3_setup_pad (MX6_PAD_GPIO_19__GPIO4_IO05 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (4 ,5 ),0 ); + }/* end GW54xx */ + +/* Configure DIO pinmux/padctl registers +* see IMX6DQRM/IMX6SDLRM IOMUXC_SW_PAD_CTL_PAD_* register definitions +*/ +if (board_type >UNKNOWN ) +return ; +for (i =0 ; i <4 ; i++) { +struct dio_cfg *cfg = &dio_cfg[(4 *board_type)+i]; +unsigned ctrl =DIO_PAD_CTRL ; + +sprintf (arg,"dio%d" , i); +if (hwconfig (arg)) { + s =hwconfig_subarg (arg,"padctrl" , &len); +if (s) + ctrl =simple_strtoul (s,NULL ,16 ) &0x3ffff ; +if (hwconfig_subarg_cmp (arg,"mode" ,"gpio" )) { +printf ("DIO%d: GPIO%d_IO%02d (gpio-%d)\n" , i, + (cfg->gpio_param/32 )+1 , + cfg->gpio_param%32 , + cfg->gpio_param); +imx_iomux_v3_setup_pad (cfg->gpio_padmux | +MUX_PAD_CTRL (ctrl)); +gpio_direction_input (cfg->gpio_param); + }else if (hwconfig_subarg_cmp ("dio2" ,"mode" ,"pwm" ) && + cfg->pwm_padmux) { +printf ("DIO%d: pwm%d\n" , i, cfg->pwm_param); +imx_iomux_v3_setup_pad (cfg->pwm_padmux | +MUX_PAD_CTRL (ctrl)); + } + } + } +} + +static int setup_pcie (void ) +{ +struct ventana_board_info *info = &ventana_info; + +if ((strncasecmp ((const char *)info->model,"GW51" ,4 ) ==0 )) { +/* assert PCI_RST# +* (will be released by OS when clock is valid) */ +imx_iomux_v3_setup_pad (MX6_PAD_GPIO_0__GPIO1_IO00 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,0 ),0 ); + }else if ((strncasecmp ((const char *)info->model,"GW52" ,4 ) ==0 )) { +/* assert PCI_RST# +* (will be released by OS when clock is valid) */ +imx_iomux_v3_setup_pad (MX6_PAD_ENET_TXD1__GPIO1_IO29 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,29 ),0 ); + }else if ((strncasecmp ((const char *)info->model,"GW53" ,4 ) ==0 )) { +/* assert PCI_RST# +* (will be released by OS when clock is valid) */ +imx_iomux_v3_setup_pad (MX6_PAD_ENET_TXD1__GPIO1_IO29 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,29 ),0 ); + }else if ((strncasecmp ((const char *)info->model,"GW54" ,4 ) ==0 )) { +/* PCICK_SSON: disable spread-spectrum clock */ +imx_iomux_v3_setup_pad (MX6_PAD_SD1_CLK__GPIO1_IO20 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,20 ),0 );
board/gateworks/gw_ventana/gw_ventana.c line 1000
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ +/* assert PCI_RST# +* (will be released by OS when clock is valid) */ +imx_iomux_v3_setup_pad (MX6_PAD_ENET_TXD1__GPIO1_IO29 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,29 ),0 ); + } + +return 0 ; +}
Please take a look at Marek's later merged patches that add PCI-E support for i.MX6 to U-Boot, and rebase on top of it. I can suggest to use u-boot-imx as base for your patches, because patches are already merged.
Generally, I think you should change the behavior of selecting data on depend of the board. Instead of checkig in each function which is the board, you should add table containinig all required values, and choose one of them in only one function.
Quoted 139 lines
board/gateworks/gw_ventana/gw_ventana.c new file +139
-0+ +#if defined(CONFIG_VIDEO_IPUV3 ) + +static iomux_v3_cfg_t const backlight_pads[] = { +/* Backlight on MIPI connector: J16 */ +MX6_PAD_SD2_CMD__GPIO1_IO11 |MUX_PAD_CTRL (NO_PAD_CTRL ), + +/* Backlight CABEN on LVDS connector: J6 */ +MX6_PAD_SD2_CLK__GPIO1_IO10 |MUX_PAD_CTRL (NO_PAD_CTRL ), +}; + +struct display_info_t { +int bus; +int addr; +int pixfmt; +int (*detect)(struct display_info_t const *dev); +void (*enable)(struct display_info_t const *dev); +struct fb_videomode mode; +}; + + +static int detect_hdmi (struct display_info_t const *dev) +{ +struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR ; +return readb (&hdmi->phy_stat0) &HDMI_PHY_HPD ; +} + +static void do_enable_hdmi (struct display_info_t const *dev) +{ +imx_enable_hdmi_phy (); +} + +static int detect_i2c (struct display_info_t const *dev) +{ +return ((0 ==i2c_set_bus_num (dev->bus)) && + (0 ==i2c_probe (dev->addr))); +} + +static void enable_lvds (struct display_info_t const *dev) +{ +struct iomuxc *iomux = (struct iomuxc *) +IOMUXC_BASE_ADDR ; + +/* set CH0 data width to 24bit (IOMUXC_GPR2:5 0=18bit, 1=24bit) */ +u32 reg =readl (&iomux->gpr[2 ]); + reg |=IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT ; +writel (reg, &iomux->gpr[2 ]); + +/* Disable CABC: +* when enabled this feature sets backlight automatically according +* to content which may cause annoying unstable backlight issue +*/ +gpio_direction_output (IMX_GPIO_NR (1 ,10 ),0 ); + +/* Enable Backlight */ +imx_iomux_v3_setup_pad (MX6_PAD_SD1_CMD__GPIO1_IO18 | +MUX_PAD_CTRL (NO_PAD_CTRL )); +gpio_direction_output (IMX_GPIO_NR (1 ,18 ),1 ); +} + +static struct display_info_t const displays[] = {{ +/* HDMI Output */ + .bus =-1 , + .addr =0 , + .pixfmt =IPU_PIX_FMT_RGB24 , + .detect = detect_hdmi, + .enable = do_enable_hdmi, + .mode = { + .name ="HDMI" , + .refresh =60 , + .xres =1024 , + .yres =768 , + .pixclock =15385 , + .left_margin =220 , + .right_margin =40 , + .upper_margin =21 , + .lower_margin =7 , + .hsync_len =60 , + .vsync_len =10 , + .sync =FB_SYNC_EXT , + .vmode =FB_VMODE_NONINTERLACED +} }, { +/* HannStar HSD100PXN1-A00 with egalx_ts controller +* (aka Freescale MXC-LVDS1 10" 1024x768 60Hz LCD touchscreen) +*/ + .bus =2 , + .addr =0x4 , + .pixfmt =IPU_PIX_FMT_LVDS666 , + .detect = detect_i2c, + .enable = enable_lvds, + .mode = { + .name ="Hannstar-XGA" , + .refresh =60 , + .xres =1024 , + .yres =768 , + .pixclock =15385 , + .left_margin =220 , + .right_margin =40 , + .upper_margin =21 , + .lower_margin =7 , + .hsync_len =60 , + .vsync_len =10 , + .sync =FB_SYNC_EXT , + .vmode =FB_VMODE_NONINTERLACED +} } }; + +int board_video_skip (void ) +{ +int i; +int ret; +char const *panel =getenv ("panel" ); +if (!panel) { +for (i =0 ; i <ARRAY_SIZE (displays); i++) { +struct display_info_t const *dev = displays+i; +if (dev->detect (dev)) { + panel = dev->mode.name; +printf ("auto-detected panel %s\n" , panel); +break ; + } + } +if (!panel) { + panel = displays[0 ].mode.name; + i =0 ; +printf ("No panel detected: default to %s\n" , panel); + } + }else { +for (i =0 ; i <ARRAY_SIZE (displays); i++) { +if (!strcmp (panel, displays[i].mode.name)) +break ; + } + } +if (i <ARRAY_SIZE (displays)) { + ret =ipuv3_fb_init (&displays[i].mode,0 , + displays[i].pixfmt); +if (!ret) { + displays[i].enable (displays+i); + printf("DISP: %s (%ux%u)\n", + displays[i].mode.name, + displays[i].mode.xres,
board/gateworks/gw_ventana/gw_ventana.c line 1150
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ displays[i].mode.yres); + }else +printf ("LCD %s cannot be configured: %d\n" , + displays[i].mode.name, ret); + }else { +printf ("unsupported panel %s\n" , panel); + ret = -EINVAL ; + } +return (0 != ret); +
}
Nak. This function is more or less copied from another board. There is still a patch doing this and my suggestion is to factorize the part in board_video_skip(), taht is not really strict bound to the board.
Quoted 56 lines
board/gateworks/gw_ventana/gw_ventana.c new file +56
-0+ +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; + +enable_ipu_clock (); +imx_setup_hdmi (); + +/* Turn on LDB0,IPU,IPU DI0 clocks */ + reg =readl (&mxc_ccm->CCGR3); + reg |=MXC_CCM_CCGR3_LDB_DI0_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 ); + reg |= (3 <<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET ) + |(3 <<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 ; +writel (reg, &mxc_ccm->cscmr2); + + reg =readl (&mxc_ccm->chsccdr); + reg |= (CHSCCDR_CLK_SEL_LDB_DI0 + <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET ); +writel (reg, &mxc_ccm->chsccdr); + + reg =IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES + |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH + |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_18BIT + |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED + |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 ; +writel (reg, &iomux->gpr[2 ]); + + reg =readl (&iomux->gpr[3 ]); + reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK ) + | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 + <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET ); +writel (reg, &iomux->gpr[3 ]); + +/* backlights off until needed */ +imx_iomux_v3_setup_multiple_pads (backlight_pads, +ARRAY_SIZE (backlight_pads)); +gpio_direction_input (IMX_GPIO_NR (1 ,10 ));/* LVDS */ +gpio_direction_input (IMX_GPIO_NR (1 ,11 ));/* MIPI */ +} +#endif /* CONFIG_VIDEO_IPUV3 */
board/gateworks/gw_ventana/gw_ventana.c line 1215
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ +static int setup_pmic_voltages (void ) +{ +int ret; +unsigned char value, rev_id =0 ; + + ret =i2c_set_bus_num (1 ); +if (ret) +return ret; +if (!i2c_probe (0x8 )) {
Nak. We have a generic PMIX framework. Please use it.
board/gateworks/gw_ventana/gw_ventana.c line 1279
Quoted 9 lines
board/gateworks/gw_ventana/gw_ventana.c new file +9
-0+/* +* Board Support +*/ + +/* +* Do not overwrite the console +* Use always serial for U-Boot console +*/ +int overwrite_console (void )
This is not required, please drop it.
Quoted 4 lines
board/gateworks/gw_ventana/gw_ventana.c new file +4
-0+{ +return 1 ; +} +
board/gateworks/gw_ventana/gw_ventana.c line 1293
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ +/* +* very early in the call chain - setup SoC peripherals +* (NB: Can not printf from here) +*/ +int board_early_init_f (void ) +{ +setup_iomux_uart (); +#ifdef CONFIG_MXC_SPI +setup_spi ();
board_early_init_f() is called before relocation and malloc() is not
available. SPI uses malloc(), then you should move setup_spi to a later point.
board/gateworks/gw_ventana/gw_ventana.c line 1299
Quoted 6 lines
board/gateworks/gw_ventana/gw_ventana.c new file +6
-0+#endif +gpio_direction_output (IMX_GPIO_NR (3 ,22 ),0 );/* OTG power off */ + +/* Note this gets called again later, +* but needed in case i2c bus is stuck */ +timer_init ();
timer_init() ? I think this is called by generic code.
Quoted 8 lines
board/gateworks/gw_ventana/gw_ventana.c new file +8
-0+setup_i2c (0 ,CONFIG_SYS_I2C_SPEED ,0x7f , &i2c_pad_info0); +setup_i2c (1 ,CONFIG_SYS_I2C_SPEED ,0x7f , &i2c_pad_info1); +setup_i2c (2 ,CONFIG_SYS_I2C_SPEED ,0x7f , &i2c_pad_info2); +#if defined(CONFIG_VIDEO_IPUV3 ) +setup_display (); +#endif + +return 0 ;
board/gateworks/gw_ventana/gw_ventana.c line 1317
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+} + +#if defined(CONFIG_DISPLAY_BOARDINFO ) +/* Identify board and display banner/info +*/ +#define SRC_SBMR1 0x020d8004/* holds BOOT_CFG1-BOOT_CFG4 from eFuse/pins */ +#define SRC_SBMR2 0x020d801c +#define SRC_GPR9 0x020d8040/* holds copy of BOOT_CFG1-BOOT_CFG4 acted on */ +#define SRC_GPR10 0x020d8044 +
No access to internal register using absolute addresses. Use structures in imx_regs.h. that is struct src->sbmrX
Quoted 21 lines
board/gateworks/gw_ventana/gw_ventana.c new file +21
-0+/* this reads boot_cfg efuse/pins - does not reflect what actually booted +*/ +void show_boot_mode (uint boot_cfg) +{ +switch ((boot_cfg &0x000000ff ) >>4 ) { +case 0x2 : +printf ("SATA" ); +break ; +case 0x3 : +printf ("SPI NOR" ); +break ; +case 0x4 : +case 0x5 : +/* BOOT_CFG2[3:4] is devno */ +printf (" SD%d" , (boot_cfg &0x00001800 ) >>11 ); +break ; +case 0x6 : +case 0x7 : +/* BOOT_CFG2[3:4] is devno */ +printf (" MMC%d" , (boot_cfg &0x00001800 ) >>11 ); +break ;
board/gateworks/gw_ventana/gw_ventana.c line 1348
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ case 0x8 ... 0xf: +printf ("NAND" ); +break ; +default : +printf ("Unknown" ); +break ; + } +printf (" 0x%08x\n" , boot_cfg); +} +
This does not belog here. Please move this code in a separate patch and make it available to all boards. Code should flow into ./arch/arm/imx-common. Please add a function getting an enumated value as return value, not only a function that output the result.
Use puts() instead of printf() if you print a constant string.
Instead of:
printf("NAND");Use:
puts("NAND");board/gateworks/gw_ventana/gw_ventana.c line 1360
Quoted 12 lines
board/gateworks/gw_ventana/gw_ventana.c new file +12
-0+ +int checkboard (void ) +{ +struct ventana_board_info *info = &ventana_info; +uint src_sbmr2 =readl (SRC_SBMR2 ); +uint src_gpr10 =readl (SRC_GPR10 ); + +/* check for valid i2c busses - if one was 'stuck' it did not get +* initialized +*/ +if (i2c_set_bus_num (0 )) +printf ("invalid /dev/i2c-0\n" );
/dev has no meaning in U-Boot.
Quoted 37 lines
board/gateworks/gw_ventana/gw_ventana.c new file +37
-0+if (i2c_set_bus_num (1 )) +printf ("invalid /dev/i2c-1\n" ); +if (i2c_set_bus_num (2 )) +printf ("invalid /dev/i2c-2\n" ); +read_eeprom (); +if (!(src_sbmr2 &1 <<4 )) { +/* can consider this 'manufacturing mode' if needed */ +printf ("First boot - eFUSE not blown\n" ); + } + +printf ("APP_IMAGE: %s\n" , (src_gpr10 &1 <<30 ) ? +"Secondary" :"Primary" ); +if (src_gpr10 &1 <<29 ) +printf ("NAND: bad blocks in application image\n" ); + +#if defined(CONFIG_ENV_IS_IN_SPI_FLASH ) +printf ("Env: SPI FLASH\n" ); +#elif defined(CONFIG_ENV_IS_IN_MMC ) +printf ("Env: MMC\n" ); +#elif defined(CONFIG_ENV_IS_IN_NAND ) +printf ("Env: NAND FLASH\n" ); +#endif + +/* SRC_SBMR1 reflects eFUSE/pin */ +printf ("BOOT_CFG: " ); +show_boot_mode (readl (SRC_SBMR1 )); +/* SRC_GPR9 reflects what was actually booted off of if not 0 +* (ie if bmode was used) */ +if (readl (SRC_GPR9 )) { +printf ("BMODE: " ); +show_boot_mode (readl (SRC_GPR9 )); + } +printf ("\n" ); +printf ("Gateworks Corporation Copyright 2014\n" ); +if (info->model[0 ]) { +printf ("Model: %s\n" , info->model); + printf("MFGDate: %02x-%02x-%02x%02x\n",
board/gateworks/gw_ventana/gw_ventana.c line 1407
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+ info->mfgdate[0 ], info->mfgdate[1 ], + info->mfgdate[2], info->mfgdate[3]); + printf("Serial:%d\n", info->serial); + }else { +printf ("Invalid EEPROM - board will not function fully\n" ); + } + +return 0 ; +} +#endif
General remak: you print a lot of stuff by booting. This can slow down your boot process significantly adding several seconds to your start up, before the kernel is loaded.
Quoted 4 lines
board/gateworks/gw_ventana/gw_ventana.c new file +4
-0+ +/* Set gd->ram_size +*/ +int dram_init (void )
board/gateworks/gw_ventana/gw_ventana.c line 1421
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+{ +struct ventana_board_info *info = &ventana_info; + + gd->ram_size = ((ulong )CONFIG_DDR_MB *1024 *1024 ); +if (info->model[0 ] && info->sdram_size >0 && info->sdram_size <9 ) { +int i = info->sdram_size; + gd->ram_size =32 *1024 *1024 ; +while (--i) + gd->ram_size *=2 ; + }
Use get_ramsize to dynamically find the size of the installed RAM.
Quoted 31 lines
board/gateworks/gw_ventana/gw_ventana.c new file +31
-0+/* initialize periperhals +*/ +int board_init (void ) +{ +int ret =0 ; +struct iomuxc_base_regs *const iomuxc_regs + = (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR ; + +#ifdef CONFIG_CMD_NAND +setup_gpmi_nand (); +#endif + +clrsetbits_le32 (&iomuxc_regs->gpr[1 ], +IOMUXC_GPR1_OTG_ID_MASK , +IOMUXC_GPR1_OTG_ID_GPIO1 ); + +imx_iomux_v3_setup_multiple_pads (usb_pads,ARRAY_SIZE (usb_pads)); + +/* address of linux boot parameters */ + gd->bd->bi_boot_params =PHYS_SDRAM +0x100 ; + +#ifdef CONFIG_SYS_I2C_MXC + ret =setup_pmic_voltages (); +if (ret) +return -1 ; +#endif + +setup_pcie (); + +#ifdef CONFIG_CMD_SATA +setup_sata ();
board/gateworks/gw_ventana/gw_ventana.c line 1466
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+#endif + +if (!i2c_set_bus_num (0 )) { +unsigned char buf[4 ]; +if (!gsc_i2c_read (0x20 ,14 ,1 , buf,1 )) { +printf ("GSC: v%d" , buf[0 ]); +if (!gsc_i2c_read (0x20 ,10 ,1 , buf,4 )) { +/* show firmware revision and CRC */ +printf (" 0x%04x" , buf[2 ] | buf[3 ]<<8 ); +/* show status register */
I do not understand the code here. This should belong to checkboard().
Quoted 65 lines
board/gateworks/gw_ventana/gw_ventana.c new file +65
-0+/* late init +*/ +int misc_init_r (void ) +{ +/* set env vars based on board model from EEPROM */ +if (ventana_info.model[0 ]) { +char str[sizeof (ventana_info.model)]; +char fdt[sizeof (ventana_info.model)+20 ]; +char *p; +int i; +const char *prefix ="" ; + +if (is_cpu_type (MXC_CPU_MX6Q )) + prefix ="imx6q" ; +else if (is_cpu_type (MXC_CPU_MX6DL )) + prefix ="imx6dl" ; + +memset (str,0 ,sizeof (str)); +for (i =0 ; i < (sizeof (ventana_info.model)-1 ) && + ventana_info.model[i]; i++) + str[i] =tolower (ventana_info.model[i]); +if (!getenv ("model" )) +setenv ("model" , str); +if (!getenv ("fdt_file" )) { +sprintf (fdt,"%s-%s.dtb" , prefix, str); +setenv ("fdt_file" , fdt); + } + p =strchr (str,'-' ); +if (p) { + *p++ =0 ; + +setenv ("model_base" , str); +if (!getenv ("fdt_file1" )) { +sprintf (fdt,"%s-%s.dtb" , prefix, str); +setenv ("fdt_file1" , fdt); + } + str[4 ] ='x' ; + str[5 ] ='x' ; + str[6 ] =0 ; +if (!getenv ("fdt_file2" )) { +sprintf (fdt,"%s-%s.dtb" , prefix, str); +setenv ("fdt_file2" , fdt); + } + } +get_mac ("ethaddr" , ventana_info.mac0); +get_mac ("eth1addr" , ventana_info.mac1); +sprintf (str,"%6d" , ventana_info.serial); +setenv ("serial#" , str); +setup_board_gpio (getenv ("model" )); + } + +/* generate a random eth mac if no EEPROM (1st boot - mfg mode) */ +else { +u32 ethaddr_low, ethaddr_high; +char str[20 ]; + +/* use Device Unique ID bits 0-64 from eFUSE +* (OCOTP_CFG1/OCOTP_CFG2) */ +fuse_read (0 ,1 , ðaddr_low); +fuse_read (0 ,2 , ðaddr_high); + +/* +* setting the 2nd LSB in the most significant byte of +* the address makes it a locally administered ethernet +* address
board/gateworks/gw_ventana/gw_ventana.c line 1568
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+*/ + ethaddr_high &=0xfeff ; + ethaddr_high |=0x0200 ; +sprintf (str,"%02X:%02X:%02X:%02X:%02X:%02X" , + ethaddr_high >>8 , ethaddr_high &0xff , + ethaddr_low >>24 , (ethaddr_low >>16 ) &0xff , + (ethaddr_low >>8 ) &0xff , ethaddr_low &0xff ); +printf ("### Setting random MAC address = \"%s\"\n" , str); +setenv ("ethaddr" , str); + }
Apart that this functionality should not be added to misc_init(), but to the corresponding entry point (board_eth_init for example), I do not think it is correct. If a random address can be generated, it should be part of the FEC driver. The FEC already reads from fuses, that makes the code here useless.
Quoted 148 lines
board/gateworks/gw_ventana/gw_ventana.c new file +148
-0+ +#ifdef CONFIG_CMD_BMODE +add_board_boot_modes (board_boot_modes); +#endif + +/* disable GSC boot watchdog +* +* The Gateworks System Controller implements a boot +* watchdog (always enabled) to cover things like ERR006282 which can +* lead to random boot failures. +*/ +if (!i2c_set_bus_num (0 )) { +unsigned char val; +if (!gsc_i2c_read (0x20 ,1 ,1 , &val,1 )) { + val |=0x80 ; +if (gsc_i2c_write (0x20 ,1 ,1 , &val,1 )) +printf ("Error: could not disable GSC Watchdog\n" ); + }else { +printf ("Error: could not disable GSC Watchdog\n" ); + } + } + +return 0 ; +} + +#if defined(CONFIG_OF_LIBFDT ) && defined(CONFIG_OF_BOARD_SETUP ) +void ft_board_setup (void *blob,bd_t *bd) +{ +struct ventana_board_info *info = &ventana_info; +struct node_info nodes[] = { + {"sst,w25q256" ,MTD_DEV_TYPE_NOR , },/* SPI flash */ + {"fsl,imx6q-gpmi-nand" ,MTD_DEV_TYPE_NAND , },/* NAND flash */ + }; +const char *model =getenv ("model" ); + +if (getenv ("fdt_noauto" )) { +printf (" Skiping ft_board_setup (fdt_noauto defined)\n" ); +return ; + } + +/* MTD partitions +* Update partition nodes using info from mtdparts env var +*/ +printf (" Updating MTD partitions...\n" ); +fdt_fixup_mtdparts (blob, nodes,ARRAY_SIZE (nodes)); + +if (!model) { +printf ("invalid board info: Leaving FDT fully enabled\n" ); +return ; + } +printf (" Adjusting FDT per EEPROM for %s...\n" , model); + +/* Note that fdt_fixup_ethernet is called in arm/lib/bootm before this +* which sets mac-address and local-mac-address properties of +* ethernet<n> aliases to ethaddr...eth<n>addr env +*/ + +/* board serial number */ +fdt_setprop (blob,0 ,"system-serial" ,getenv ("serial#" ), +strlen (getenv ("serial#" ) +1 )); + +/* board (model contains model from device-tree) */ +fdt_setprop (blob,0 ,"board" , info->model, +strlen ((const char *)info->model) +1 ); + +/* Peripheral Config */ +if (!info->config_eth0) +fdt_del_node_and_alias (blob,"ethernet0" ); +if (!info->config_eth1) +fdt_del_node_and_alias (blob,"ethernet1" ); +if (!info->config_hdmi_out) +fdt_del_node_and_alias (blob,"hdmi_out" ); +if (!info->config_sata) +fdt_del_node_and_alias (blob,"ahci0" ); +if (!info->config_pcie) +fdt_del_node_and_alias (blob,"pcie" ); +if (!info->config_ssi0) +fdt_del_node_and_alias (blob,"ssi0" ); +if (!info->config_ssi1) +fdt_del_node_and_alias (blob,"ssi1" ); +if (!info->config_lcd) +fdt_del_node_and_alias (blob,"lcd0" ); +if (!info->config_lvds0) +fdt_del_node_and_alias (blob,"lvds0" ); +if (!info->config_lvds1) +fdt_del_node_and_alias (blob,"lvds1" ); +if (!info->config_usb0) +fdt_del_node_and_alias (blob,"usb0" ); +if (!info->config_usb1) +fdt_del_node_and_alias (blob,"usb1" ); +if (!info->config_sd0) +fdt_del_node_and_alias (blob,"usdhc0" ); +if (!info->config_sd1) +fdt_del_node_and_alias (blob,"usdhc1" ); +if (!info->config_sd2) +fdt_del_node_and_alias (blob,"usdhc2" ); +if (!info->config_sd3) +fdt_del_node_and_alias (blob,"usdhc3" ); +if (!info->config_uart0) +fdt_del_node_and_alias (blob,"serial0" ); +if (!info->config_uart1) +fdt_del_node_and_alias (blob,"serial1" ); +if (!info->config_uart2) +fdt_del_node_and_alias (blob,"serial2" ); +if (!info->config_uart3) +fdt_del_node_and_alias (blob,"serial3" ); +if (!info->config_uart4) +fdt_del_node_and_alias (blob,"serial4" ); +if (!info->config_ipu0) +fdt_del_node_and_alias (blob,"ipu0" ); +if (!info->config_ipu1) +fdt_del_node_and_alias (blob,"ipu1" ); +if (!info->config_flexcan) +fdt_del_node_and_alias (blob,"can0" ); +if (!info->config_mipi_dsi) +fdt_del_node_and_alias (blob,"mipi_dsi" ); +if (!info->config_mipi_csi) +fdt_del_node_and_alias (blob,"mipi_csi" ); +if (!info->config_tzasc0) +fdt_del_node_and_alias (blob,"tzasc0" ); +if (!info->config_tzasc1) +fdt_del_node_and_alias (blob,"tzasc1" ); +if (!info->config_i2c0) +fdt_del_node_and_alias (blob,"i2c0" ); +if (!info->config_i2c1) +fdt_del_node_and_alias (blob,"i2c1" ); +if (!info->config_i2c2) +fdt_del_node_and_alias (blob,"i2c2" ); +if (!info->config_vpu) +fdt_del_node_and_alias (blob,"vpu" ); +if (!info->config_csi0) +fdt_del_node_and_alias (blob,"csi0" ); +if (!info->config_csi1) +fdt_del_node_and_alias (blob,"csi1" ); +if (!info->config_caam) +fdt_del_node_and_alias (blob,"caam" ); +if (!info->config_espci0) +fdt_del_node_and_alias (blob,"spi0" ); +if (!info->config_espci1) +fdt_del_node_and_alias (blob,"spi1" ); +if (!info->config_espci2) +fdt_del_node_and_alias (blob,"spi2" ); +if (!info->config_espci3) +fdt_del_node_and_alias (blob,"spi3" ); +if (!info->config_espci4) +fdt_del_node_and_alias (blob,"spi4" ); +if (!info->config_espci5) +fdt_del_node_and_alias (blob,"spi5" );
board/gateworks/gw_ventana/gw_ventana.c line 1726
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.c new file +10
-0+if (!info->config_hdmi_in) +fdt_del_node_and_alias (blob,"hdmi_in" ); +if (!info->config_vid_out) +fdt_del_node_and_alias (blob,"cvbs_out" ); +if (!info->config_vid_in) +fdt_del_node_and_alias (blob,"cvbs_in" ); +if (!info->config_nand) +fdt_del_node_and_alias (blob,"nand" ); +if (!info->config_gps) +fdt_del_node_and_alias (blob,"pps" );
I find the way quite singular. It seems you have a full-blown .dts file and you want to drop the features that you do not find in eeprom. A more conventional way is to have a simpler or not fully configured dts and add only the feature you want.
dts has the keyword "disabled", that let you enable or disable a specific feature. Maybe you could exchange the "status" field in dts instead of adding/dropping nodes.
Quoted 22 lines
board/gateworks/gw_ventana/gw_ventana.c new file +3
-0+} +#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */ +board/gateworks/gw_ventana/gw_ventana.cfg new file +13
-0@@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Gateworks Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer doc/README.imximage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ +IMAGE_VERSION 2
board/gateworks/gw_ventana/gw_ventana.cfg line 23
Quoted 10 lines
board/gateworks/gw_ventana/gw_ventana.cfg new file +10
-0+ +/* + * Boot Device : one of + * spi, sd, nand, sata + */ +#ifdef CONFIG_SPI_FLASH +BOOT_FROM spi +#else +BOOT_FROM nand +#endif
Do you boot also from SPI ?
Quoted 51 lines
board/gateworks/gw_ventana/gw_ventana.cfg new file +19
-0+ +#define __ASSEMBLY__ +#include <config.h> +#include "asm/arch/mx6-ddr.h" +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +/* Memory configuration (size is overridden via eeprom config) */ +#include "ddr-setup.cfg" +#if defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 1024 + #include "1066mhz_4x128mx16.cfg" +#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 1024 + #include "800mhz_4x128mx16.cfg" +#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 512 + #include "800mhz_2x128mx16.cfg" +#else + #error "Unsupported CPU/Memory configuration" +#endif +#include "clocks.cfg"board/gateworks/gw_ventana/ventana_eeprom.h new file +26
-0@@ -0,0 +1,107 @@ +/* +* ventana_eeprom.h - Gateworks Ventana EEPROM Configuration +* v1.00 +*/ +#ifndef _VENTANA_EEPROM_ +#define _VENTANA_EEPROM_ + +struct ventana_board_info { + u8 mac0[6]; /* 0x00: MAC1 */ + u8 mac1[6]; /* 0x06: MAC2 */ + u8 res0[12]; /* 0x0C: reserved */ + u32 serial; /* 0x18: Serial Number (read only) */ + u8 res1[4]; /* 0x1C: reserved */ + u8 mfgdate[4]; /* 0x20: MFG date (read only) */ + u8 res2[7]; /* 0x24 */ + /* sdram config */ + u8 sdram_size; /* 0x2B: enum (512,1024,2048) MB */ + u8 sdram_speed; /* 0x2C: enum (100,133,166,200,267,333,400) MHz */ + u8 sdram_width; /* 0x2D: enum (32,64) bit */ + /* cpu config */ + u8 cpu_speed; /* 0x2E: enum (800,1000,1200) MHz */ + u8 cpu_type; /* 0x2F: enum (imx6q,imx6d,imx6dl,imx6s) */ + u8 model[16]; /* 0x30: model string */ + /* FLASH config */ + u8 nand_flash_size; /* 0x40: enum (4,8,16,32,64,128) MB */ + u8 spi_flash_size; /* 0x41: enum (4,8,16,32,64,128) MB */
board/gateworks/gw_ventana/ventana_eeprom.h line 36
Quoted 10 lines
board/gateworks/gw_ventana/ventana_eeprom.h new file +10
-0+ +/* Config1: SoC Peripherals */ + u8 config_eth0:1; /* 0: 0x42 */ + u8 config_eth1:1; /* 1 */ + u8 config_hdmi_out:1;/* 2 */ + u8 config_sata:1; /* 3 */ + u8 config_pcie:1; /* 4 */ + u8 config_ssi0:1; /* 5 */ + u8 config_ssi1:1; /* 6 */ + u8 config_lcd:1; /* 7 */
Generally, using bitwise fields is deprecated in favour of using maks. This because there is no conventions how the compiler should assign (MSB or LSB) the single bits.
Quoted 76 lines
board/gateworks/gw_ventana/ventana_eeprom.h new file +71
-0+ + u8 config_lvds0:1; /* 0: 0x43 */ + u8 config_lvds1:1; /* 1 */ + u8 config_usb0:1; /* 2 (USB EHCI) */ + u8 config_usb1:1; /* 3 (USB OTG) */ + u8 config_sd0:1; /* 4 */ + u8 config_sd1:1; /* 5 */ + u8 config_sd2:1; /* 6 */ + u8 config_sd3:1; /* 7 */ + + u8 config_uart0:1; /* 0: 0x44 */ + u8 config_uart1:1; /* 1 */ + u8 config_uart2:1; /* 2 */ + u8 config_uart3:1; /* 3 */ + u8 config_uart4:1; /* 4 */ + u8 config_ipu0:1; /* 5 */ + u8 config_ipu1:1; /* 6 */ + u8 config_flexcan:1; /* 7 */ + + u8 config_mipi_dsi:1;/* 0: 0x45 */ + u8 config_mipi_csi:1;/* 1 */ + u8 config_tzasc0:1; /* 2 */ + u8 config_tzasc1:1; /* 3 */ + u8 config_i2c0:1; /* 4 */ + u8 config_i2c1:1; /* 5 */ + u8 config_i2c2:1; /* 6 */ + u8 config_vpu:1; /* 7 */ + + u8 config_csi0:1; /* 0: 0x46 */ + u8 config_csi1:1; /* 1 */ + u8 config_caam:1; /* 2 */ + u8 config_mezz:1; /* 3 */ + u8 config_res1:1; /* 4 */ + u8 config_res2:1; /* 5 */ + u8 config_res3:1; /* 6 */ + u8 config_res4:1; /* 7 */ + + u8 config_espci0:1; /* 0: 0x47 */ + u8 config_espci1:1; /* 1 */ + u8 config_espci2:1; /* 2 */ + u8 config_espci3:1; /* 3 */ + u8 config_espci4:1; /* 4 */ + u8 config_espci5:1; /* 5 */ + u8 config_res5:1; /* 6 */ + u8 config_res6:1; /* 7 */ + +/* Config2: Other Peripherals */ + u8 config_gps:1; /* 0: 0x48 */ + u8 config_spifl0:1; /* 1 */ + u8 config_spifl1:1; /* 2 */ + u8 config_gspbatt:1; /* 3 */ + u8 config_hdmi_in:1; /* 4 */ + u8 config_vid_out:1; /* 5 */ + u8 config_vid_in:1; /* 6 */ + u8 config_nand:1; /* 7 */ + + u8 config_res8:1; /* 0: 0x49 */ + u8 config_res9:1; /* 1 */ + u8 config_res10:1; /* 2 */ + u8 config_res11:1; /* 3 */ + u8 config_res12:1; /* 4 */ + u8 config_res13:1; /* 5 */ + u8 config_res14:1; /* 6 */ + u8 config_res15:1; /* 7 */ + +u8 res3[4 ];/* 0x4A */ + + u8 chksum[2]; /* 0x4E */ +}; + +#endif boards.cfg +0
-0
boards.cfg Active arm armv7 mx6 - udoo udoo_qua · line 298
Quoted 4 lines
boards.cfg +1
-0@@ -295,6 +295,7 @@ Active arm armv7 mx6 - udoo udoo_qua Active arm armv7 mx6 - wandboard wandboard_dl wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_quad wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_solo wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512 Fabio Estevam <[email protected]> +Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]>
Why do you touch the titanium ?
boards.cfg Active arm armv7 mx6 freescale mx6qsabreauto · line 312
Quoted 9 lines
boards.cfg +1
-1Active arm armv7 mx6 boundary nitrogen6x mx6qsabrelite nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024,SABRELITE Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl2g nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl2g.cfg,MX6DL,DDR_MB=2048 Eric Nelson <[email protected]>@@ -308,7 +309,11 @@ Active arm armv7 mx6 freescale mx6qsabreauto Active arm armv7 mx6 freescale mx6sabresd mx6dlsabresd mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6sabresd mx6qsabresd mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6slevk mx6slevk mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL Fabio Estevam <[email protected]> -Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanaq1gspi gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH Tim Harvey <[email protected]>
Please let the list sorted.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel 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 =====================================================================
PATCH 1/1 ventana: Add Gateworks Ventana family support
Quoted 1 line · Stefano Babic
Hi Tim,
Hi Stefano - thanks for the review!
Quoted 4 lines
please run script/checkpatch on your patch before next submit. The tool reports plenty of issues that must be solved for mainlining.
It looks like I missed some >80 char formatting issues regarding the env vars in the config file. I'll fix those up.
Quoted 12 lines · Tim Harvey
Quoted 10 lines
Gateworks Ventana is a product family based on the i.MX6. This patch adds support for all boards in the Ventana family. Where possible, data from the boards EEPROM is used to determine various details about the board at runtime.
Signed-off-by Tim Harvey <[email protected]>--- board/gateworks/gw_ventana/1066mhz_4x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_2x128mx16.cfg | 42 + board/gateworks/gw_ventana/800mhz_4x128mx16.cfg | 42 +
Quoted 7 lines
These three files to set up the DDR are *identical* to the files with the same name in /board/boundary/nitrogen6x.
A such as duplication is not allowed. There should be a good reason to have new files - for solidrun, different values are requested for DDR.
Please consider to refer to supplied files instead of copying.
I will include the ddr config files from boundary with a ../../boundary/... where they do not differ. The clocks.cfg does differ (see below) but I liked the way Boundary broke these files out do want to re-use as much as possible.
Quoted 19 lines
Quoted 19 lines
board/gateworks/gw_ventana/README new file +11
-0@@ -0,0 +1,49 @@ +U-Boot for the Gateworks Ventana Product Family boards + +This file contains information for the port of U-Boot to the Gateworks +Ventana Product family boards. + +1. Boot source, boot from NAND +------------------------------ + +The i.MX6 BOOT ROM expects some headers that provide details of NAND layout +and bad block information (referred to as 'bootstreams') which are replicated +multiple times in NAND.
Quoted 8 lines
board/gateworks/gw_ventana/README line 14
Quoted 4 lines
The number of replications is configurable through
board/gateworks/gw_ventana/README new file +3
-0+board strapping options and eFUSE settings. The Freescale 'kobs-ng' +application from the Freescale LTIB BSP, which runs under Linux, must be used +to program the bootstream in order to setup the replicated headers correctly.The behavior is quite different as we have currently in mainline. With kobs-ng you flash u-boot.bin, while the result image for i.MXes in mailine is u-boot.imx (u-boot.bin with imx header).
I'm not familiar with the IMX family other than IMX6 but for IMX6 kobs-ng does use u-boot.imx and not u-boot.bin. kobs needs the headers which are not part of u-boot.bin. Are you sure you are not mistaken here? Can you point me to some references?
Quoted 4 lines
This behavior is also different to the roadmap we have discussed some times ago for the i.MX6. We will move i.MX to use SPL, and the bad blocks handling, not managed by the BOOT ROM, will be done inside SPL.
Yes - I would also like to an SPL bootloader, but have not quite gotten that working yet for NAND. I felt it was a good start to get my current patchset mainlined as a starting point.
Regardless of what is loading the next level (u-boot.bin) the initial flashing of NAND is still currently handled only by kobs-ng so I'm not sure how this differs in this respect. I plan to look at adding the functionality of kobs-ng to u-boot at some point.
Quoted 15 lines
board/gateworks/gw_ventana/README line 26
Quoted 13 lines
board/gateworks/gw_ventana/README new file +12
-0+ +The Gateworks Ventana boards with NAND flash have been factory programmed +such that their eFUSE settings expect 2 copies of the boostream (this is +specified by providing kobs-ng with the --search_exponent=1 argument). Once in +Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream +with: + +kobs-ng init -v -x --search_exponent=1 u-boot.imx + +This information is taken from + +https://trac.gateworks.com/wiki/ventana%3Abuild_ubootThe link is broken - there is no permission with https, while http works.
Thanks for catching this. The correct link is
http://trac.gateworks.com/wiki/ventana/bootloader#BuildingfromSource
and I will fix it in the next patch version.
Quoted 14 lines
board/gateworks/gw_ventana/README line 36
Quoted 11 lines
board/gateworks/gw_ventana/README new file +10
-0+ +2. Build +-------- + +There are several Gateworks Ventana boards that share a simliar design but +vary based on CPU, Memory configuration, and subloaded devices. Although +the subloaded devices are handled dynamically in the bootloader using +factory configured EEPROM data to modify the device-tree, the CPU choice +(IMX6Q vs IMX6DL) and memory configurations are currently compile-time +options.We will have another advantage with SPL, that is we can have a single image working on different i.MX6 variants (Solo/Dual/Quad).
agreed.
I really wanted to get to SPL before posting but felt I have a good starting point equivalent with the other IMX6 boards currently in mainline. For SPL I need nand and i2c support (as we use i2c to access the EEPROM which contains details about DDR configuration) and currently both of those are creating some dependency issues that keep the SPL from building for me. I haven't had time to dig into that yet.
Quoted 16 lines
board/gateworks/gw_ventana/README line 48
Quoted 13 lines
board/gateworks/gw_ventana/README new file +12
-0+ +The following Gateworks Ventana configurations exist: + gwventanaq1gspi: MX6Q,1GB,SPI FLASH + gwventanaq : MX6Q,512MB,NAND FLASH + gwventanaq1g : MX6Q,1GB,NAND FLASH + gwventanadl : MX6DL,512MB,NAND FLASH + gwventanadl1g : MX6DL,1GB,NAND FLASH + +To build U-Boot for the MX6Q,1GB,NAND FLASH for example: + + make gwventanaq1g_config + make u-boot.imxu-boot.imx should be the default target. But it seems weird you build u-boot.imx and then discard it (or am I wrong ?) to take u-boot.bin.
u-boot.imx is the default target. We don't discard it. I will change the instructions to just 'make gwventanaq1g_config; make' to avoid confusion.
Quoted 16 lines
board/gateworks/gw_ventana/clocks.cfg line 3
Quoted 11 lines
board/gateworks/gw_ventana/README new file +1
-0+board/gateworks/gw_ventana/clocks.cfg new file +3
-0@@ -0,0 +1,41 @@ +/* + * Copyright (C) 2013 Gateworks Corporation + *This is the only change in the file. The original file has a Boundary Device Copyright. You cannot simply substitute the original Copyright with your own.
Quoted 2 lines
clocks.cfg is then (apart some whitespaces) identical to clocks.cfg in nitrogen. Please do not duplicate files.
I agree that the original copyright should be there and I'll add it, but there is an important difference between the two so I cannot use the original. The Gateworks board uses NAND flash thus the CCM_CCGR4 register differs by a few bits.
- DATA 4, CCM_CCGR4, 0x00FFF300
+ DATA 4, CCM_CCGR4, 0xFFFFF300 /* enable NAND/GPMI/BCH clocks */
Quoted 16 lines
Quoted 16 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +11
-0@@ -0,0 +1,96 @@ +/* + * Copyright (C) 2013 Boundary Devices + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Device Configuration Data (DCD) + * + * Each entry must have the format: + * Addr-type Address Value + * + * where:
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg line 16
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ * Addr-type register length (1,2 or 4 bytes) + * Address absolute address of the register + * value value to be stored in the register + */ +even ddr-setup.cfg is identical (but here Copyright is untouched). It seems we do not need any special .cfg file for the board.
just clocks.cfg at this point must differ.
Quoted 1 line
<snip>
Quoted 8 lines
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +8
-0+ +int board_mmc_init(bd_t *bis) +{ + s32 status = 0; + u32 index = 0; + + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[0].max_bus_width = 4;
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ + for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { + switch (index) { + case 0:I know I am the first responsible for this code. But if
CONFIG_SYS_FSL_USDHC_NUM= 1 (and this is not easy changable without modifying the board), why do we need a loop ?
Agreed - a loop is silly here, I'll remove it.
Quoted 9 lines
Quoted 2 lines
+/* Gateworks System Controller I2C access may NAK when busy - use
Wrong multiline comment. It should be:
/*
* your comment
* here
*/
will fix thanks. Someone else mentioned that to me and I have not been able to find a style guide for multi-line comments. Looks like opening and closing should contain no text.
Quoted 13 lines
Quoted 13 lines
+ * retries.
+ */board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + int retry = 3; + int n = 0; + int ret; + + while (n++ < retry) { + ret = i2c_read(chip, addr, alen, buf, len); + if (!ret) + break;
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+ printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, + n, ret); + if (ret != -ENODEV) + break; + mdelay(10); + }Whcih is the benefit of trying three times ?
it provides a little more redundancy than 2 times, and a little less than 4 ;)
Our GSC can occasionally be 'busy' and NAK (every 1Hz it does some internal processing). As there are several places where I perform an i2c transaction to one of the GSC's slave devices (it emulates several i2c devices) I wanted to consolidate where I had retry logic. There is nothing magic about 3 tries necessarily but I have found that with the speed of the SoC we never fail more than 2 successive reads due to the periodic loading of the GSC.
If you want more info on the GSC you can read about it here:
http://trac.gateworks.com/wiki/gsc
Quoted 15 lines
Quoted 15 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +14
-0+int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + int retry = 3; + int n = 0; + int ret; + + while (n++ < retry) { + ret = i2c_write(chip, addr, alen, buf, len); + if (!ret) + break; + printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, + n, ret); + if (ret != -ENODEV) + break;
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ mdelay(10); + } + mdelay(1); + return ret; +}Same here. If first time fails, something happens. It makes no sense to try multiple times.
in our case I feel it does - see above.
Quoted 9 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ +/* + * For SPL boot some boards need i2c before SDRAM is initialized so force + * variables to live in SRAM + */Agree - but then I will see SPL...
Quoted 3 lines
Quoted 1 line
+static struct
ventana_board_info__attribute__((section(".data")))ventana_info;Can you explain why do you need this ?
This was in preparation for SPL. I'm not clear if the struct needs any special attributes at this time to be available to all the functions that use it. Because currently the BOOTROM sets up DDR I'm thinking perhaps not, but I seem to recall before I added the attribute I ran into some issues.
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 3 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +2
-0+ +/* read ventana EEPROM and return structure or NULL on errorMultiline comment
ack
Quoted 11 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
+ * should be called once, the first time eeprom data is needed
+ */board/gateworks/gw_ventana/ddr-setup.cfg new file +3
-0+static void +read_eeprom(void) +{You have a I2C eprom. This is supported in U-Boot. Why do you not set
CONFIG_SYS_I2C_EEPROM_ADDRin your config file and use general code ?It seems to me you can drop your own read/write_eeprom() function.
I considered this before (using common/cmd_eeprom.c), but the fact that I want to be able to handle retries on NAK's would keep me from using a generic read_eeprom feature. Also, that common support only just replaces my gsc_i2c_read function - inside read_eeprom I verify checksum and some other sanity checks. Grepping for CONFIG_SYS_I2C_EEPROM_ADDR there are a lot of boards that implement their own read_eeprom functionality for one reason or another.
Quoted 25 lines
Quoted 25 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +24
-0+ int i; + int chksum; + struct ventana_board_info *info = &ventana_info; + unsigned char *buf = (unsigned char *)&ventana_info; + int n = 0; + + memset(info, 0, sizeof(ventana_info)); + + /* wait for bus and device exist - we will not boot w/o our EEPROM */ + while (1) { + if (0 == i2c_set_bus_num(0) && 0 == i2c_probe(0x51)) + break; + mdelay(1); + n++; + } + + /* read eeprom config section */ + if (gsc_i2c_read(0x51, 0x00, 1, buf, sizeof(ventana_info))) { + printf("EEPROM: Failed to read EEPROM\n"); + info->model[0] = 0; + return; + } + + /* sanity checks */
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ if (info->model[0] != 'G' || info->model[1] != 'W') { + printf("EEPROM: Invalid Model in EEPROM\n"); + info->model[0] = 0; + return; + }You can do your checks on the pyload after reading from the storage and using common functions.
Agreed, if I could use the common functions. However here I am reading from a device that requires some special handling (retry on NAK).
Quoted 28 lines
Quoted 28 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +27
-0+#ifdef CONFIG_CMD_GSC +int read_hwmon(const char *name, uint reg, uint size, uint low, uint high) +{ + unsigned char buf[3]; + uint ui; + int ret; + + printf("%-8s:", name); + memset(buf, 0, sizeof(buf)); + if (gsc_i2c_read(0x29, reg, 1, buf, size)) { + printf("fRD\n"); + ret = -1; + } else { + ret = 0; + ui = buf[0] | (buf[1]<<8) | (buf[2]<<16); + if (ui == 0xffffff) { + printf("fVL"); + } else if (ui < low) { + printf("%d fLO", ui); + ret = -2; + } else if (ui > high) { + printf("%d fHI", ui); + ret = -3; + } else { + printf("%d", ui); + } + }
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ printf("\n"); + + return ret; +}I need help - I have not understood. This functions prints only something - return values is discarded when function is called. Buf is filled, but can you better explain the purpose of the function.
The gsc command (below) is currently just showing the values from the hardware monitor (temp and various voltage rails). The read_hwmon function above is a helper function to display the value, or a failure high, or failure low in a standard fashion.
Quoted 59 lines
Quoted 59 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +58
-0+ +int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct ventana_board_info *info = &ventana_info; + + i2c_set_bus_num(0); + if ((strncasecmp((const char *)info->model, "GW51", 4) == 0)) { + read_hwmon("Temp", 0x00, 2, 0, 9000); + read_hwmon("VIN", 0x02, 3, 8000, 60000); + read_hwmon("VDD_3P3", 0x05, 3, 3300*0.9, 3300*1.1); + read_hwmon("VBATT", 0x08, 3, 2000*0.9, 3000*1.1); + read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_SOC", 0x11, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1); + read_hwmon("VDD_DDR", 0x17, 3, 1500*0.9, 1500*1.1); + read_hwmon("VDD_5P0", 0x0b, 3, 5000*0.9, 5000*1.1); + read_hwmon("VDD_2P5", 0x23, 3, 2500*0.9, 2500*1.1); + read_hwmon("VDD_1P8", 0x1d, 3, 1800*0.9, 1800*1.1); + } else if ((strncasecmp((const char *)info->model, "GW52", 4) == 0)) { + read_hwmon("Temp", 0x00, 2, 0, 9000); + read_hwmon("VIN", 0x02, 3, 8000, 60000); + read_hwmon("VDD_3P3", 0x05, 3, 3300*0.9, 3300*1.1); + read_hwmon("VBATT", 0x08, 3, 2000*0.9, 3000*1.1); + read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_SOC", 0x11, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1); + read_hwmon("VDD_DDR", 0x17, 3, 1500*0.9, 1500*1.1); + read_hwmon("VDD_5P0", 0x0b, 3, 5000*0.9, 5000*1.1); + read_hwmon("VDD_2P5", 0x23, 3, 2500*0.9, 2500*1.1); + read_hwmon("VDD_1P8", 0x1d, 3, 1800*0.9, 1800*1.1); + read_hwmon("VDD_1P0", 0x20, 3, 1000*0.9, 1000*1.1); + } else if ((strncasecmp((const char *)info->model, "GW53", 4) == 0)) { + read_hwmon("Temp", 0x00, 2, 0, 9000); + read_hwmon("VIN", 0x02, 3, 8000, 60000); + read_hwmon("VDD_3P3", 0x05, 3, 3300*0.9, 3300*1.1); + read_hwmon("VBATT", 0x08, 3, 2000*0.9, 3000*1.1); + read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_SOC", 0x11, 3, 1175*0.9, 1175*1.1); + read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1); + read_hwmon("VDD_DDR", 0x17, 3, 1500*0.9, 1500*1.1); + read_hwmon("VDD_5P0", 0x0b, 3, 5000*0.9, 5000*1.1); + read_hwmon("VDD_2P5", 0x23, 3, 2500*0.9, 2500*1.1); + read_hwmon("VDD_1P8", 0x1d, 3, 1800*0.9, 1800*1.1); + read_hwmon("VDD_1P0", 0x20, 3, 1000*0.9, 1000*1.1); + } else if ((strncasecmp((const char *)info->model, "GW54", 4) == 0)) { + read_hwmon("Temp", 0x00, 2, 0, 9000); + read_hwmon("VIN", 0x02, 3, 8000, 60000); + read_hwmon("VDD_3P3", 0x05, 3, 3300*0.9, 3300*1.1); + read_hwmon("VBATT", 0x08, 3, 2000*0.9, 3000*1.1); + read_hwmon("VDD_CORE", 0x0e, 3, 1375*0.9, 1375*1.1); + read_hwmon("VDD_SOC", 0x11, 3, 1375*0.9, 1375*1.1); + read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1); + read_hwmon("VDD_DDR", 0x17, 3, 1500*0.9, 1500*1.1); + read_hwmon("VDD_5P0", 0x0b, 3, 5000*0.9, 5000*1.1); + read_hwmon("VDD_2P5", 0x23, 3, 2500*0.9, 2500*1.1); + read_hwmon("VDD_1P8", 0x1d, 3, 1800*0.9, 1800*1.1); + read_hwmon("VDD_1P0", 0x20, 3, 1000*0.9, 1000*1.1); + }
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 2 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +2
-0+ return 0; +}I think we can do better. Most cases are duplicated. Please split into
common calls (for example,read_hwmon("Temp", 0x00, 2, 0, 9000)is
always called) and board-variations. The identification is done on a single byte (GW51-GW54): you can use a more readable switch..case instead of multiplestrncmp()
Agreed that there is a lot of duplication here. I'll revise as the only voltage rails not common across the 4 baseboards are VDD_SOC, VDD_ARM, VDD_1P0.
I'm not sure I agree the switch-case is more readable although it would be higher performance if that was something desirable. The 4 gateworks baseboards get customized into 'specials' and sometimes these specials end up with special handling based on models which is why I like to keep the comparisons done as strings, but I suppose I could cross that bridge if we come to it later.
Quoted 11 lines
Quoted 11 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+ + +/* get_mac from env string, with default + */ +static void get_mac(char *envvar, unsigned char *def) +{ + char str[20]; + char *env = getenv(envvar); + + if (!env) {
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", + def[0], def[1], def[2], def[3], def[4], def[5]); + setenv(envvar, str); + } +}No idea why you need it. The FEC driver takes care of MAC address and set the ethaddr variable. This seems to me wrong.
Agreed - I think this is a hold-over from when I started u-boot support early last year. I will remove.
Quoted 1 line
<snip>
Quoted 16 lines
Quoted 16 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +16
-0+ +int board_phy_config(struct phy_device *phydev) +{ + unsigned short val; + + /* Marvel 88E1510 */ + if (phydev->phy_id == 0x1410dd1) { + /* Errata 3.1 - PHY initialization */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214b); + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0c28); + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2146); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xb233); + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214d); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xcc0c);
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+ phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159); + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00fb); + phy_write(phydev, MDIO_DEVAD_NONE, 7, 0xc00d); + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); +This does not seem to me the best way to do. IMHO you should add support for Marvel 88E1510 in
drivers/net/phy/, maybe as Alaska phy.
ok - I can do that.
Quoted 17 lines
In
board_phy_config()should contain only board specific initialization
- an errata means that the same initialization is common to all boards having this chip.board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 11 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +11
-0+ /* LED configuration (See datasheet section 2.26.4) + * LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link + * LED[1] (LNK:Green) R16_3.7:4 to 0001: on-link, blink-activity + */ + phy_write(phydev, MDIO_DEVAD_NONE, 22, 3); + val = phy_read(phydev, MDIO_DEVAD_NONE, 16); + val &= 0xff00; + val |= 0x0017; + phy_write(phydev, MDIO_DEVAD_NONE, 16, val); + phy_write(phydev, MDIO_DEVAD_NONE, 22, 0); + }
Quoted 1 line
This is also part of the phy driver.
I would think LED configuration should be a board specific config as its up to the board vendor what they want their LED's to do.
Quoted 1 line
<snip>
Quoted 67 lines
Quoted 67 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +67
-0+ +static void setup_board_gpio(const char *model) +{ + const char *s; + char arg[10]; + size_t len; + int i; + enum { + GW51xx, + GW52xx, + GW53xx, + GW54xx, + UNKNOWN, + }; + struct dio_cfg { + iomux_v3_cfg_t gpio_padmux; + unsigned gpio_param; + iomux_v3_cfg_t pwm_padmux; + unsigned pwm_param; + }; + int board_type = UNKNOWN; + struct dio_cfg dio_cfg[] = { + /* GW51xx */ + { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16), + 0, 0 }, + { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19), + MX6_PAD_SD1_DAT2__PWM2_OUT, 2 }, + { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17), + MX6_PAD_SD1_DAT1__PWM3_OUT, 3 }, + { MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18), + MX6_PAD_SD1_CMD__PWM4_OUT, 4 }, + + /* GW52xx */ + { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16), + 0, 0 }, + { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19), + MX6_PAD_SD1_DAT2__PWM2_OUT, 2 }, + { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17), + MX6_PAD_SD1_DAT1__PWM3_OUT, 3 }, + { MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20), + 0, 0 }, + + /* GW53xx */ + { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16), + 0, 0 }, + { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19), + MX6_PAD_SD1_DAT2__PWM2_OUT, 2 }, + { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17), + MX6_PAD_SD1_DAT1__PWM3_OUT, 3 }, + { MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20), + 0, 0 }, + + /* GW54xx */ + { MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9), + MX6_PAD_GPIO_9__PWM1_OUT, 1 }, + { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19), + MX6_PAD_SD1_DAT2__PWM2_OUT, 2 }, + { MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9), + MX6_PAD_SD4_DAT1__PWM3_OUT, 3 }, + { MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10), + MX6_PAD_SD4_DAT2__PWM4_OUT, 4 }, + }; + + if (strncasecmp(model, "GW51", 4) == 0) { + board_type = GW51xx; + + /* PANLEDG# (GRN off) */
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL0__GPIO4_IO06 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 6), 1); +Again, this is not straightforward and difficult to read. Use tables for each board variation you want to add and split between common code and specific code.
Ok - I'll put all the pad config in a model specific array at least.
Quoted 322 lines
Quoted 322 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +321
-0+ /* PANLEDR# (RED off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW0__GPIO4_IO07 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 7), 1); + + /* GPS_SHDN */ + imx_iomux_v3_setup_pad(MX6_PAD_GPIO_2__GPIO1_IO02 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 2), 1); + + /* Analog video codec power enable */ + imx_iomux_v3_setup_pad(MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(5, 20), 1); + + /* Expansion IO0 - PWREN# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A19__GPIO2_IO19 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(2, 19), 0); + + /* Expansion IO1 - IRQ# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A20__GPIO2_IO18 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_input(IMX_GPIO_NR(2, 18)); + } /* end GW51xx */ + + else if (strncasecmp(model, "GW52", 4) == 0) { + board_type = GW52xx; + + /* PANLEDG# (GRN off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL0__GPIO4_IO06 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 6), 1); + + /* PANLEDR# (RED off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW0__GPIO4_IO07 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 7), 1); + + /* MX6_LOCLED# (off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW4__GPIO4_IO15 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 15), 1); + + /* GPS_SHDN */ + imx_iomux_v3_setup_pad(MX6_PAD_ENET_RXD0__GPIO1_IO27 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 27), 1); + + /* Expansion IO0 - PWREN# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A19__GPIO2_IO19 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(2, 19), 0); + + /* Expansion IO1 - IRQ# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A20__GPIO2_IO18 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_input(IMX_GPIO_NR(2, 18)); + + /* MSATA Enable */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT0__GPIO2_IO08 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + if (is_cpu_type(MXC_CPU_MX6Q)) { + gpio_direction_output(IMX_GPIO_NR(2, 8), + (hwconfig("msata")) ? 1 : 0); + printf("MSATA: %s\n", (hwconfig("msata") ? + "enabled" : "disabled")); + } else { + gpio_direction_output(IMX_GPIO_NR(2, 8), 0); + } + + /* USBOTG Select (PCISKT or FrontPanel) */ + imx_iomux_v3_setup_pad(MX6_PAD_GPIO_2__GPIO1_IO02 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 2), 0); + + /* Analog video codec power enable */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_D31__GPIO3_IO31 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(3, 31), 1); + + /* UART2_EN# */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT3__GPIO2_IO11 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + printf("RS232: %s\n", (hwconfig("rs232")) ? + "enabled" : "disabled"); + gpio_direction_output(IMX_GPIO_NR(2, 11), + (hwconfig("rs232")) ? 0 : 1); + /* TODO: flush UART RX FIFO after disable */ + } /* end GW52xx */ + + else if (strncasecmp(model, "GW53", 4) == 0) { + board_type = GW53xx; + + /* PANLEDG# (GRN off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL0__GPIO4_IO06 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 6), 1); + + /* PANLEDR# (RED off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW0__GPIO4_IO07 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 7), 1); + + /* MX6_LOCLED# (off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW4__GPIO4_IO15 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 15), 1); + + /* GPS_SHDN */ + imx_iomux_v3_setup_pad(MX6_PAD_ENET_RXD0__GPIO1_IO27 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 27), 1); + + /* Expansion IO0 - PWREN# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A19__GPIO2_IO19 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(2, 19), 0); + + /* Expansion IO1 - IRQ# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A20__GPIO2_IO18 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_input(IMX_GPIO_NR(2, 18)); + + /* MSATA Enable */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT0__GPIO2_IO08 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + if (is_cpu_type(MXC_CPU_MX6Q)) { + gpio_direction_output(IMX_GPIO_NR(2, 8), + (hwconfig("msata")) ? 1 : 0); + printf("MSATA: %s\n", (hwconfig("msata") ? + "enabled" : "disabled")); + } else { + gpio_direction_output(IMX_GPIO_NR(2, 8), 0); + } + + /* Analog video codec power enable */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_D31__GPIO3_IO31 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(3, 31), 1); + + /* UART2_EN# */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT3__GPIO2_IO11 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + printf("RS232: %s\n", (hwconfig("rs232")) ? + "enabled" : "disabled"); + gpio_direction_output(IMX_GPIO_NR(2, 11), + (hwconfig("rs232")) ? 0 : 1); + /* TODO: flush UART RX FIFO after disable */ + } /* end GW53xx */ + + else if (strncasecmp(model, "GW54", 4) == 0) { + board_type = GW54xx; + if (strncasecmp(model, "GW5400-A", 8) == 0) { + /* PANLEDG# (GRN off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL0__GPIO4_IO06 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 6), 1); + + /* PANLEDR# (RED off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL2__GPIO4_IO10 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 10), 1); + + /* MX6_LOCLED# (off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW4__GPIO4_IO15 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 15), 1); + + /* MIPI DIO */ + imx_iomux_v3_setup_pad(MX6_PAD_SD1_DAT3__GPIO1_IO21 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + + /* RS485 Transmit Enable */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_D24__GPIO3_IO24 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(3, 24), 0); + + /* Expansion IO0 - PWREN# */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW0__GPIO4_IO07 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 7), 0); + + /* Expansion IO1 - IRQ# */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW1__GPIO4_IO09 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_input(IMX_GPIO_NR(4, 9)); + } + + else if ((strncasecmp(model, "GW5400", 6) == 0) || + (strncasecmp(model, "GW5410", 6) == 0) + ) { + /* PANLEDG# (GRN off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_COL0__GPIO4_IO06 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 6), 1); + + /* PANLEDR# (RED off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW0__GPIO4_IO07 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 7), 1); + + /* MX6_LOCLED# (off) */ + imx_iomux_v3_setup_pad(MX6_PAD_KEY_ROW4__GPIO4_IO15 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 15), 1); + + /* RS485 Transmit Enable */ + imx_iomux_v3_setup_pad(MX6_PAD_SD3_DAT4__GPIO7_IO01 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(7, 1), 0); + + /* Expansion IO0 - PWREN# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A19__GPIO2_IO19 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(2, 19), 0); + + /* Expansion IO1 - IRQ# */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_A20__GPIO2_IO18 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_input(IMX_GPIO_NR(2, 18)); + + /* MSATA Enable */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT0__GPIO2_IO08 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + if (is_cpu_type(MXC_CPU_MX6Q)) { + gpio_direction_output(IMX_GPIO_NR(2, 8), + (hwconfig("msata")) ? + 1 : 0); + printf("MSATA: %s\n", (hwconfig("msata") ? + "enabled" : "disabled")); + } else { + gpio_direction_output(IMX_GPIO_NR(2, 8), 0); + } + + /* Analog video codec power enable */ + imx_iomux_v3_setup_pad(MX6_PAD_EIM_D31__GPIO3_IO31 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(3, 31), 1); + } + + /* UART2_EN# */ + imx_iomux_v3_setup_pad(MX6_PAD_SD4_DAT3__GPIO2_IO11 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + printf("RS232: %s\n", (hwconfig("rs232")) ? + "enabled" : "disabled"); + gpio_direction_output(IMX_GPIO_NR(2, 11), + (hwconfig("rs232")) ? 0 : 1); + /* TODO: flush UART RX FIFO after disable */ + + /* DIOI2C_DIS# */ + imx_iomux_v3_setup_pad(MX6_PAD_GPIO_19__GPIO4_IO05 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(4, 5), 0); + } /* end GW54xx */ + + /* Configure DIO pinmux/padctl registers + * see IMX6DQRM/IMX6SDLRM IOMUXC_SW_PAD_CTL_PAD_* register definitions + */ + if (board_type > UNKNOWN) + return; + for (i = 0; i < 4; i++) { + struct dio_cfg *cfg = &dio_cfg[(4*board_type)+i]; + unsigned ctrl = DIO_PAD_CTRL; + + sprintf(arg, "dio%d", i); + if (hwconfig(arg)) { + s = hwconfig_subarg(arg, "padctrl", &len); + if (s) + ctrl = simple_strtoul(s, NULL, 16) & 0x3ffff; + if (hwconfig_subarg_cmp(arg, "mode", "gpio")) { + printf("DIO%d: GPIO%d_IO%02d (gpio-%d)\n", i, + (cfg->gpio_param/32)+1, + cfg->gpio_param%32, + cfg->gpio_param); + imx_iomux_v3_setup_pad(cfg->gpio_padmux | + MUX_PAD_CTRL(ctrl)); + gpio_direction_input(cfg->gpio_param); + } else if (hwconfig_subarg_cmp("dio2", "mode", "pwm") && + cfg->pwm_padmux) { + printf("DIO%d: pwm%d\n", i, cfg->pwm_param); + imx_iomux_v3_setup_pad(cfg->pwm_padmux | + MUX_PAD_CTRL(ctrl)); + } + } + } +} + +static int setup_pcie(void) +{ + struct ventana_board_info *info = &ventana_info; + + if ((strncasecmp((const char *)info->model, "GW51", 4) == 0)) { + /* assert PCI_RST# + * (will be released by OS when clock is valid) */ + imx_iomux_v3_setup_pad(MX6_PAD_GPIO_0__GPIO1_IO00 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 0), 0); + } else if ((strncasecmp((const char *)info->model, "GW52", 4) == 0)) { + /* assert PCI_RST# + * (will be released by OS when clock is valid) */ + imx_iomux_v3_setup_pad(MX6_PAD_ENET_TXD1__GPIO1_IO29 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 29), 0); + } else if ((strncasecmp((const char *)info->model, "GW53", 4) == 0)) { + /* assert PCI_RST# + * (will be released by OS when clock is valid) */ + imx_iomux_v3_setup_pad(MX6_PAD_ENET_TXD1__GPIO1_IO29 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 29), 0); + } else if ((strncasecmp((const char *)info->model, "GW54", 4) == 0)) { + /* PCICK_SSON: disable spread-spectrum clock */ + imx_iomux_v3_setup_pad(MX6_PAD_SD1_CLK__GPIO1_IO20 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 20), 0); + + /* assert PCI_RST# + * (will be released by OS when clock is valid) */ + imx_iomux_v3_setup_pad(MX6_PAD_ENET_TXD1__GPIO1_IO29 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ } + + return 0; +}Please take a look at Marek's later merged patches that add PCI-E support for i.MX6 to U-Boot, and rebase on top of it. I can suggest to use u-boot-imx as base for your patches, because patches are already merged.
I'm aware of Marek's patches but wasn't sure when they were scheduled to go in. I will rebase against u-boot-imx and put the above in the new imx6_pcie_toggle_reset function.
Quoted 5 lines
Generally, I think you should change the behavior of selecting data on depend of the board. Instead of checkig in each function which is the board, you should add table containinig all required values, and choose one of them in only one function.
pcie reset, gpio default configuration (pinmux and direction/level), and the hwmon registers are the only places that are model dependent. I feel it is more readable to leave the model checks in place instead of trying to create structures that have all of that in them.
Quoted 152 lines
Quoted 140 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +139
-0+ +#if defined(CONFIG_VIDEO_IPUV3) + +static iomux_v3_cfg_t const backlight_pads[] = { + /* Backlight on MIPI connector: J16 */ + MX6_PAD_SD2_CMD__GPIO1_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL), + + /* Backlight CABEN on LVDS connector: J6 */ + MX6_PAD_SD2_CLK__GPIO1_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), +}; + +struct display_info_t { + int bus; + int addr; + int pixfmt; + int (*detect)(struct display_info_t const *dev); + void (*enable)(struct display_info_t const *dev); + struct fb_videomode mode; +}; + + +static int detect_hdmi(struct display_info_t const *dev) +{ + struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; + return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD; +} + +static void do_enable_hdmi(struct display_info_t const *dev) +{ + imx_enable_hdmi_phy(); +} + +static int detect_i2c(struct display_info_t const *dev) +{ + return ((0 == i2c_set_bus_num(dev->bus)) && + (0 == i2c_probe(dev->addr))); +} + +static void enable_lvds(struct display_info_t const *dev) +{ + struct iomuxc *iomux = (struct iomuxc *) + IOMUXC_BASE_ADDR; + + /* set CH0 data width to 24bit (IOMUXC_GPR2:5 0=18bit, 1=24bit) */ + u32 reg = readl(&iomux->gpr[2]); + reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT; + writel(reg, &iomux->gpr[2]); + + /* Disable CABC: + * when enabled this feature sets backlight automatically according + * to content which may cause annoying unstable backlight issue + */ + gpio_direction_output(IMX_GPIO_NR(1, 10), 0); + + /* Enable Backlight */ + imx_iomux_v3_setup_pad(MX6_PAD_SD1_CMD__GPIO1_IO18 | + MUX_PAD_CTRL(NO_PAD_CTRL)); + gpio_direction_output(IMX_GPIO_NR(1, 18), 1); +} + +static struct display_info_t const displays[] = {{ + /* HDMI Output */ + .bus = -1, + .addr = 0, + .pixfmt = IPU_PIX_FMT_RGB24, + .detect = detect_hdmi, + .enable = do_enable_hdmi, + .mode = { + .name = "HDMI", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} }, { + /* HannStar HSD100PXN1-A00 with egalx_ts controller + * (aka Freescale MXC-LVDS1 10" 1024x768 60Hz LCD touchscreen) + */ + .bus = 2, + .addr = 0x4, + .pixfmt = IPU_PIX_FMT_LVDS666, + .detect = detect_i2c, + .enable = enable_lvds, + .mode = { + .name = "Hannstar-XGA", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = 15385, + .left_margin = 220, + .right_margin = 40, + .upper_margin = 21, + .lower_margin = 7, + .hsync_len = 60, + .vsync_len = 10, + .sync = FB_SYNC_EXT, + .vmode = FB_VMODE_NONINTERLACED +} } }; + +int board_video_skip(void) +{ + int i; + int ret; + char const *panel = getenv("panel"); + if (!panel) { + for (i = 0; i < ARRAY_SIZE(displays); i++) { + struct display_info_t const *dev = displays+i; + if (dev->detect(dev)) { + panel = dev->mode.name; + printf("auto-detected panel %s\n", panel); + break; + } + } + if (!panel) { + panel = displays[0].mode.name; + i = 0; + printf("No panel detected: default to %s\n", panel); + } + } else { + for (i = 0; i < ARRAY_SIZE(displays); i++) { + if (!strcmp(panel, displays[i].mode.name)) + break; + } + } + if (i < ARRAY_SIZE(displays)) { + ret = ipuv3_fb_init(&displays[i].mode, 0, + displays[i].pixfmt); + if (!ret) { + displays[i].enable(displays+i); + printf("DISP: %s (%ux%u)\n", + displays[i].mode.name, + displays[i].mode.xres,board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 10 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+ displays[i].mode.yres); + } else + printf("LCD %s cannot be configured: %d\n", + displays[i].mode.name, ret); + } else { + printf("unsupported panel %s\n", panel); + ret = -EINVAL; + } + return (0 != ret); +}
Quoted 3 lines
Nak. This function is more or less copied from another board. There is still a patch doing this and my suggestion is to factorize the part in
board_video_skip(), taht is not really strict bound to the board.
Yes, both mx6sabresd and nitrogen6x use this common code and I saw the proposed patch to add it to wandboard as well with your response asking for it to be made common. I'll check with Otavio to see if he is working on something already. I agree some common support could help here.
Quoted 61 lines
Quoted 61 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +60
-0+ +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; + + enable_ipu_clock(); + imx_setup_hdmi(); + + /* Turn on LDB0,IPU,IPU DI0 clocks */ + reg = readl(&mxc_ccm->CCGR3); + reg |= MXC_CCM_CCGR3_LDB_DI0_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); + reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) + |(3<<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; + writel(reg, &mxc_ccm->cscmr2); + + reg = readl(&mxc_ccm->chsccdr); + reg |= (CHSCCDR_CLK_SEL_LDB_DI0 + <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET); + writel(reg, &mxc_ccm->chsccdr); + + reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES + |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH + |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_18BIT + |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED + |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0; + writel(reg, &iomux->gpr[2]); + + reg = readl(&iomux->gpr[3]); + reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK) + | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 + <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET); + writel(reg, &iomux->gpr[3]); + + /* backlights off until needed */ + imx_iomux_v3_setup_multiple_pads(backlight_pads, + ARRAY_SIZE(backlight_pads)); + gpio_direction_input(IMX_GPIO_NR(1, 10)); /* LVDS */ + gpio_direction_input(IMX_GPIO_NR(1, 11)); /* MIPI */ +} +#endif /* CONFIG_VIDEO_IPUV3 */ + +static int setup_pmic_voltages(void) +{ + int ret;
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+ unsigned char value, rev_id = 0; + + ret = i2c_set_bus_num(1); + if (ret) + return ret; + if (!i2c_probe(0x8)) {Nak. We have a generic PMIX framework. Please use it.
agreed - I see that now and will revise.
Quoted 12 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 10 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +9
-0+/* + * Board Support + */ + +/* + * Do not overwrite the console + * Use always serial for U-Boot console + */ +int overwrite_console(void)This is not required, please drop it.
will do
Quoted 11 lines
Quoted 11 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+{ + return 1; +} + + +/* + * very early in the call chain - setup SoC peripherals + * (NB: Can not printf from here) + */ +int board_early_init_f(void)
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+{ + setup_iomux_uart(); +#ifdef CONFIG_MXC_SPI + setup_spi();
board_early_init_f()is called before relocation andmalloc()is not
available. SPI usesmalloc(), then you should movesetup_spito a later point.
ok - will move.
Quoted 9 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 7 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+#endif + gpio_direction_output(IMX_GPIO_NR(3, 22), 0); /* OTG power off */ + + /* Note this gets called again later, + * but needed in case i2c bus is stuck */ + timer_init();
timer_init()? I think this is called by generic code.
it is, but as the common states its called later (at least it was when I first wrote this) and causes one of the error handling functions to hang when it tries to delay. The specific issue I was working around here had to do with no console output from the bootloader if you had for example an HDMI monitor plugged in with a bad EDID clk/data pin.
I'll check to see if this is still needed as this code was written and tested some time ago.
Quoted 14 lines
Quoted 14 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +13
-0+ setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0); + setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1); + setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2); +#if defined(CONFIG_VIDEO_IPUV3) + setup_display(); +#endif + + return 0; +} + +#if defined(CONFIG_DISPLAY_BOARDINFO) +/* Identify board and display banner/info + */
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +5
-0+#define SRC_SBMR1 0x020d8004 /* holds BOOT_CFG1-BOOT_CFG4 from eFuse/pins */ +#define SRC_SBMR2 0x020d801c +#define SRC_GPR9 0x020d8040 /* holds copy of BOOT_CFG1-BOOT_CFG4 acted on */ +#define SRC_GPR10 0x020d8044 +No access to internal register using absolute addresses. Use structures in
imx_regs.h. that is structsrc->sbmrX
ack
Quoted 38 lines
Quoted 22 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +21
-0+/* this reads boot_cfg efuse/pins - does not reflect what actually booted + */ +void show_boot_mode(uint boot_cfg) +{ + switch ((boot_cfg & 0x000000ff) >> 4) { + case 0x2: + printf("SATA"); + break; + case 0x3: + printf("SPI NOR"); + break; + case 0x4: + case 0x5: + /* BOOT_CFG2[3:4] is devno */ + printf(" SD%d", (boot_cfg & 0x00001800) >> 11); + break; + case 0x6: + case 0x7: + /* BOOT_CFG2[3:4] is devno */ + printf(" MMC%d", (boot_cfg & 0x00001800) >> 11); + break;board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 10 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+ case 0x8 ... 0xf: + printf("NAND"); + break; + default: + printf("Unknown"); + break; + } + printf(" 0x%08x\n", boot_cfg); +} +This does not belog here. Please move this code in a separate patch and make it available to all boards. Code should flow into
./arch/arm/imx-common. Please add a function getting an enumated value as return value, not only a function that output the result.
Quoted 8 lines
Use
puts()instead ofprintf()if you print a constant string.Instead of:
printf("NAND");Use:
puts("NAND");
ack
Quoted 6 lines
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+ +int checkboard(void) +{ + struct ventana_board_info *info = &ventana_info; + uint src_sbmr2 = readl(SRC_SBMR2); + uint src_gpr10 = readl(SRC_GPR10);
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+ + /* check for valid i2c busses - if one was 'stuck' it did not get + * initialized + */ + if (i2c_set_bus_num(0)) + printf("invalid /dev/i2c-0\n");/dev has no meaning in U-Boot.
will fix
Quoted 44 lines
Quoted 44 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +43
-0+ if (i2c_set_bus_num(1)) + printf("invalid /dev/i2c-1\n"); + if (i2c_set_bus_num(2)) + printf("invalid /dev/i2c-2\n"); + read_eeprom(); + if (!(src_sbmr2 & 1<<4)) { + /* can consider this 'manufacturing mode' if needed */ + printf("First boot - eFUSE not blown\n"); + } + + printf("APP_IMAGE: %s\n", (src_gpr10 & 1<<30) ? + "Secondary" : "Primary"); + if (src_gpr10 & 1<<29) + printf("NAND: bad blocks in application image\n"); + +#if defined(CONFIG_ENV_IS_IN_SPI_FLASH) + printf("Env: SPI FLASH\n"); +#elif defined(CONFIG_ENV_IS_IN_MMC) + printf("Env: MMC\n"); +#elif defined(CONFIG_ENV_IS_IN_NAND) + printf("Env: NAND FLASH\n"); +#endif + + /* SRC_SBMR1 reflects eFUSE/pin */ + printf("BOOT_CFG: "); + show_boot_mode(readl(SRC_SBMR1)); + /* SRC_GPR9 reflects what was actually booted off of if not 0 + * (ie if bmode was used) */ + if (readl(SRC_GPR9)) { + printf("BMODE: "); + show_boot_mode(readl(SRC_GPR9)); + } + printf("\n"); + printf("Gateworks Corporation Copyright 2014\n"); + if (info->model[0]) { + printf("Model: %s\n", info->model); + printf("MFGDate: %02x-%02x-%02x%02x\n", + info->mfgdate[0], info->mfgdate[1], + info->mfgdate[2], info->mfgdate[3]); + printf("Serial:%d\n", info->serial); + } else { + printf("Invalid EEPROM - board will not function fully\n"); + }
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 4 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ + return 0; +} +#endifGeneral remak: you print a lot of stuff by booting. This can slow down your boot process significantly adding several seconds to your start up, before the kernel is loaded.
agreed - perhaps there are some common defines I can use to quiet things down by default or even better an env variable that the user can set?
We've found that showing the boot device, and model in the bootloader is extremely helpfull in supporting users but I suppose I could move some of the other things like DIO/SATA/RS232 configuration (hwconfig controlled) reporting to a user command.
Quoted 17 lines
Quoted 5 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +4
-0+ +/* Set gd->ram_size + */ +int dram_init(void)board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 10 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +10
-0+{ + struct ventana_board_info *info = &ventana_info; + + gd->ram_size = ((ulong)CONFIG_DDR_MB * 1024 * 1024); + if (info->model[0] && info->sdram_size > 0 && info->sdram_size < 9) { + int i = info->sdram_size; + gd->ram_size = 32*1024*1024; + while (--i) + gd->ram_size *= 2; + }Use
get_ramsizeto dynamically find the size of the installed RAM.
will do - looking at doc/README.memory-test it seems that get_ram_size() should be very fast and can also catch hardware related memory errors.
Quoted 36 lines
Quoted 36 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +35
-0+/* initialize periperhals + */ +int board_init(void) +{ + int ret = 0; + struct iomuxc_base_regs *const iomuxc_regs + = (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR; + +#ifdef CONFIG_CMD_NAND + setup_gpmi_nand(); +#endif + + clrsetbits_le32(&iomuxc_regs->gpr[1], + IOMUXC_GPR1_OTG_ID_MASK, + IOMUXC_GPR1_OTG_ID_GPIO1); + + imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads)); + + /* address of linux boot parameters */ + gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; + +#ifdef CONFIG_SYS_I2C_MXC + ret = setup_pmic_voltages(); + if (ret) + return -1; +#endif + + setup_pcie(); + +#ifdef CONFIG_CMD_SATA + setup_sata(); +#endif + + if (!i2c_set_bus_num(0)) { + unsigned char buf[4];
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 6 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +6
-0+ if (!gsc_i2c_read(0x20, 14, 1, buf, 1)) { + printf("GSC: v%d", buf[0]); + if (!gsc_i2c_read(0x20, 10, 1, buf, 4)) { + /* show firmware revision and CRC */ + printf(" 0x%04x", buf[2] | buf[3]<<8); + /* show status register */I do not understand the code here. This should belong to
checkboard().
it is displaying info about firmware revision and status of GSC - I will move it to checkboard().
Quoted 74 lines
Quoted 74 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +73
-0+/* late init + */ +int misc_init_r(void) +{ + /* set env vars based on board model from EEPROM */ + if (ventana_info.model[0]) { + char str[sizeof(ventana_info.model)]; + char fdt[sizeof(ventana_info.model)+20]; + char *p; + int i; + const char *prefix = ""; + + if (is_cpu_type(MXC_CPU_MX6Q)) + prefix = "imx6q"; + else if (is_cpu_type(MXC_CPU_MX6DL)) + prefix = "imx6dl"; + + memset(str, 0, sizeof(str)); + for (i = 0; i < (sizeof(ventana_info.model)-1) && + ventana_info.model[i]; i++) + str[i] = tolower(ventana_info.model[i]); + if (!getenv("model")) + setenv("model", str); + if (!getenv("fdt_file")) { + sprintf(fdt, "%s-%s.dtb", prefix, str); + setenv("fdt_file", fdt); + } + p = strchr(str, '-'); + if (p) { + *p++ = 0; + + setenv("model_base", str); + if (!getenv("fdt_file1")) { + sprintf(fdt, "%s-%s.dtb", prefix, str); + setenv("fdt_file1", fdt); + } + str[4] = 'x'; + str[5] = 'x'; + str[6] = 0; + if (!getenv("fdt_file2")) { + sprintf(fdt, "%s-%s.dtb", prefix, str); + setenv("fdt_file2", fdt); + } + } + get_mac("ethaddr", ventana_info.mac0); + get_mac("eth1addr", ventana_info.mac1); + sprintf(str, "%6d", ventana_info.serial); + setenv("serial#", str); + setup_board_gpio(getenv("model")); + } + + /* generate a random eth mac if no EEPROM (1st boot - mfg mode) */ + else { + u32 ethaddr_low, ethaddr_high; + char str[20]; + + /* use Device Unique ID bits 0-64 from eFUSE + * (OCOTP_CFG1/OCOTP_CFG2) */ + fuse_read(0, 1, ðaddr_low); + fuse_read(0, 2, ðaddr_high); + + /* + * setting the 2nd LSB in the most significant byte of + * the address makes it a locally administered ethernet + * address + */ + ethaddr_high &= 0xfeff; + ethaddr_high |= 0x0200; + sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", + ethaddr_high >> 8, ethaddr_high & 0xff, + ethaddr_low >> 24, (ethaddr_low >> 16) & 0xff, + (ethaddr_low >> 8) & 0xff, ethaddr_low & 0xff); + printf("### Setting random MAC address = \"%s\"\n", str);
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 2 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +2
-0+ setenv("ethaddr", str); + }Apart that this functionality should not be added to
misc_init(), but to the corresponding entry point (board_eth_initfor example), I do not think it is correct. If a random address can be generated, it should be part of the FEC driver. The FEC already reads from fuses, that makes the code here useless.
Agreed - I never noticed that was available in common code. I will remove it.
Quoted 156 lines
Quoted 156 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +155
-0+ +#ifdef CONFIG_CMD_BMODE + add_board_boot_modes(board_boot_modes); +#endif + + /* disable GSC boot watchdog + * + * The Gateworks System Controller implements a boot + * watchdog (always enabled) to cover things like ERR006282 which can + * lead to random boot failures. + */ + if (!i2c_set_bus_num(0)) { + unsigned char val; + if (!gsc_i2c_read(0x20, 1, 1, &val, 1)) { + val |= 0x80; + if (gsc_i2c_write(0x20, 1, 1, &val, 1)) + printf("Error: could not disable GSC Watchdog\n"); + } else { + printf("Error: could not disable GSC Watchdog\n"); + } + } + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + struct ventana_board_info *info = &ventana_info; + struct node_info nodes[] = { + { "sst,w25q256", MTD_DEV_TYPE_NOR, }, /* SPI flash */ + { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, /* NAND flash */ + }; + const char *model = getenv("model"); + + if (getenv("fdt_noauto")) { + printf(" Skiping ft_board_setup (fdt_noauto defined)\n"); + return; + } + + /* MTD partitions + * Update partition nodes using info from mtdparts env var + */ + printf(" Updating MTD partitions...\n"); + fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); + + if (!model) { + printf("invalid board info: Leaving FDT fully enabled\n"); + return; + } + printf(" Adjusting FDT per EEPROM for %s...\n", model); + + /* Note that fdt_fixup_ethernet is called in arm/lib/bootm before this + * which sets mac-address and local-mac-address properties of + * ethernet<n> aliases to ethaddr...eth<n>addr env + */ + + /* board serial number */ + fdt_setprop(blob, 0, "system-serial", getenv("serial#"), + strlen(getenv("serial#") + 1)); + + /* board (model contains model from device-tree) */ + fdt_setprop(blob, 0, "board", info->model, + strlen((const char *)info->model) + 1); + + /* Peripheral Config */ + if (!info->config_eth0) + fdt_del_node_and_alias(blob, "ethernet0"); + if (!info->config_eth1) + fdt_del_node_and_alias(blob, "ethernet1"); + if (!info->config_hdmi_out) + fdt_del_node_and_alias(blob, "hdmi_out"); + if (!info->config_sata) + fdt_del_node_and_alias(blob, "ahci0"); + if (!info->config_pcie) + fdt_del_node_and_alias(blob, "pcie"); + if (!info->config_ssi0) + fdt_del_node_and_alias(blob, "ssi0"); + if (!info->config_ssi1) + fdt_del_node_and_alias(blob, "ssi1"); + if (!info->config_lcd) + fdt_del_node_and_alias(blob, "lcd0"); + if (!info->config_lvds0) + fdt_del_node_and_alias(blob, "lvds0"); + if (!info->config_lvds1) + fdt_del_node_and_alias(blob, "lvds1"); + if (!info->config_usb0) + fdt_del_node_and_alias(blob, "usb0"); + if (!info->config_usb1) + fdt_del_node_and_alias(blob, "usb1"); + if (!info->config_sd0) + fdt_del_node_and_alias(blob, "usdhc0"); + if (!info->config_sd1) + fdt_del_node_and_alias(blob, "usdhc1"); + if (!info->config_sd2) + fdt_del_node_and_alias(blob, "usdhc2"); + if (!info->config_sd3) + fdt_del_node_and_alias(blob, "usdhc3"); + if (!info->config_uart0) + fdt_del_node_and_alias(blob, "serial0"); + if (!info->config_uart1) + fdt_del_node_and_alias(blob, "serial1"); + if (!info->config_uart2) + fdt_del_node_and_alias(blob, "serial2"); + if (!info->config_uart3) + fdt_del_node_and_alias(blob, "serial3"); + if (!info->config_uart4) + fdt_del_node_and_alias(blob, "serial4"); + if (!info->config_ipu0) + fdt_del_node_and_alias(blob, "ipu0"); + if (!info->config_ipu1) + fdt_del_node_and_alias(blob, "ipu1"); + if (!info->config_flexcan) + fdt_del_node_and_alias(blob, "can0"); + if (!info->config_mipi_dsi) + fdt_del_node_and_alias(blob, "mipi_dsi"); + if (!info->config_mipi_csi) + fdt_del_node_and_alias(blob, "mipi_csi"); + if (!info->config_tzasc0) + fdt_del_node_and_alias(blob, "tzasc0"); + if (!info->config_tzasc1) + fdt_del_node_and_alias(blob, "tzasc1"); + if (!info->config_i2c0) + fdt_del_node_and_alias(blob, "i2c0"); + if (!info->config_i2c1) + fdt_del_node_and_alias(blob, "i2c1"); + if (!info->config_i2c2) + fdt_del_node_and_alias(blob, "i2c2"); + if (!info->config_vpu) + fdt_del_node_and_alias(blob, "vpu"); + if (!info->config_csi0) + fdt_del_node_and_alias(blob, "csi0"); + if (!info->config_csi1) + fdt_del_node_and_alias(blob, "csi1"); + if (!info->config_caam) + fdt_del_node_and_alias(blob, "caam"); + if (!info->config_espci0) + fdt_del_node_and_alias(blob, "spi0"); + if (!info->config_espci1) + fdt_del_node_and_alias(blob, "spi1"); + if (!info->config_espci2) + fdt_del_node_and_alias(blob, "spi2"); + if (!info->config_espci3) + fdt_del_node_and_alias(blob, "spi3"); + if (!info->config_espci4) + fdt_del_node_and_alias(blob, "spi4"); + if (!info->config_espci5) + fdt_del_node_and_alias(blob, "spi5"); + if (!info->config_hdmi_in) + fdt_del_node_and_alias(blob, "hdmi_in"); + if (!info->config_vid_out) + fdt_del_node_and_alias(blob, "cvbs_out"); + if (!info->config_vid_in) + fdt_del_node_and_alias(blob, "cvbs_in"); + if (!info->config_nand)
Quoted 8 lines
board/gateworks/gw_ventana/ddr-setup.cfg
Quoted 3 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +3
-0+ fdt_del_node_and_alias(blob, "nand"); + if (!info->config_gps) + fdt_del_node_and_alias(blob, "pps");I find the way quite singular. It seems you have a full-blown .dts file and you want to drop the features that you do not find in eeprom. A more conventional way is to have a simpler or not fully configured dts and add only the feature you want.
Yes, this is what I am doing - removing nodes from a full-featured devicetree.
I feel it better represents the board to have the 'full featured' version present in the upstream Linux kernel and to simply disable nodes that are removed. Also, adding features instead would add a lot of code here as the whole dts representation of that feature would be necessary (bus connections etc) - it would get very messy and duplicate much of what is already present in the mainline Linux device tree's. The above represents everything possible based on the baseboard schematics and eeprom bit configuration but does not mean all the combinations the above can result in are order-able boards.
Quoted 4 lines
dts has the keyword "disabled", that let you enable or disable a specific feature. Maybe you could exchange the "status" field in dts instead of adding/dropping nodes.
I could do this but I'm not sure what is more appropriate. I'll need to inquire on the linux and device-tree mailing lists.
Quoted 27 lines
Quoted 27 lines
board/gateworks/gw_ventana/ddr-setup.cfg new file +3
-0+} +#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */ +board/gateworks/gw_ventana/gw_ventana.cfg new file +17
-0@@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Gateworks Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Refer doc/README.imximage for more details about how-to configure + * and create imximage boot image + * + * The syntax is taken as close as possible with the kwbimage + */ + +/* image version */ +IMAGE_VERSION 2 + +/* + * Boot Device : one of + * spi, sd, nand, sata
Quoted 8 lines
board/gateworks/gw_ventana/gw_ventana.cfg line 23
Quoted 6 lines
board/gateworks/gw_ventana/gw_ventana.cfg new file +6
-0+ */ +#ifdef CONFIG_SPI_FLASH +BOOT_FROM spi +#else +BOOT_FROM nand +#endifDo you boot also from SPI ?
The original prototype board for the Ventana family did (we only produced and shipped a handful of these but there are still some in the wild). This is the config for gwventanaq1gspi config in boards.cfg.
Quoted 58 lines
Quoted 58 lines
board/gateworks/gw_ventana/gw_ventana.cfg new file +19
-0+ +#define __ASSEMBLY__ +#include <config.h> +#include "asm/arch/mx6-ddr.h" +#include "asm/arch/iomux.h" +#include "asm/arch/crm_regs.h" + +/* Memory configuration (size is overridden via eeprom config) */ +#include "ddr-setup.cfg" +#if defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 1024 + #include "1066mhz_4x128mx16.cfg" +#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 1024 + #include "800mhz_4x128mx16.cfg" +#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 512 + #include "800mhz_2x128mx16.cfg" +#else + #error "Unsupported CPU/Memory configuration" +#endif +#include "clocks.cfg"board/gateworks/gw_ventana/ventana_eeprom.h new file +32
-0@@ -0,0 +1,107 @@ +/* +* ventana_eeprom.h - Gateworks Ventana EEPROM Configuration +* v1.00 +*/ +#ifndef _VENTANA_EEPROM_ +#define _VENTANA_EEPROM_ + +struct ventana_board_info { + u8 mac0[6]; /* 0x00: MAC1 */ + u8 mac1[6]; /* 0x06: MAC2 */ + u8 res0[12]; /* 0x0C: reserved */ + u32 serial; /* 0x18: Serial Number (read only) */ + u8 res1[4]; /* 0x1C: reserved */ + u8 mfgdate[4]; /* 0x20: MFG date (read only) */ + u8 res2[7]; /* 0x24 */ + /* sdram config */ + u8 sdram_size; /* 0x2B: enum (512,1024,2048) MB */ + u8 sdram_speed; /* 0x2C: enum (100,133,166,200,267,333,400) MHz */ + u8 sdram_width; /* 0x2D: enum (32,64) bit */ + /* cpu config */ + u8 cpu_speed; /* 0x2E: enum (800,1000,1200) MHz */ + u8 cpu_type; /* 0x2F: enum (imx6q,imx6d,imx6dl,imx6s) */ + u8 model[16]; /* 0x30: model string */ + /* FLASH config */ + u8 nand_flash_size; /* 0x40: enum (4,8,16,32,64,128) MB */ + u8 spi_flash_size; /* 0x41: enum (4,8,16,32,64,128) MB */ + + /* Config1: SoC Peripherals */ + u8 config_eth0:1; /* 0: 0x42 */ + u8 config_eth1:1; /* 1 */ + u8 config_hdmi_out:1;/* 2 */ + u8 config_sata:1; /* 3 */
Quoted 8 lines
board/gateworks/gw_ventana/ventana_eeprom.h line 36
Quoted 4 lines
board/gateworks/gw_ventana/ventana_eeprom.h new file +4
-0+ u8 config_pcie:1; /* 4 */ + u8 config_ssi0:1; /* 5 */ + u8 config_ssi1:1; /* 6 */ + u8 config_lcd:1; /* 7 */Generally, using bitwise fields is deprecated in favour of using maks. This because there is no conventions how the compiler should assign (MSB or LSB) the single bits.
Can you point me to an example? I'm not sure what you mean by 'maks' (macros defining bit positions perhaps?).
Quoted 75 lines
Quoted 75 lines
board/gateworks/gw_ventana/ventana_eeprom.h new file +71
-0+ + u8 config_lvds0:1; /* 0: 0x43 */ + u8 config_lvds1:1; /* 1 */ + u8 config_usb0:1; /* 2 (USB EHCI) */ + u8 config_usb1:1; /* 3 (USB OTG) */ + u8 config_sd0:1; /* 4 */ + u8 config_sd1:1; /* 5 */ + u8 config_sd2:1; /* 6 */ + u8 config_sd3:1; /* 7 */ + + u8 config_uart0:1; /* 0: 0x44 */ + u8 config_uart1:1; /* 1 */ + u8 config_uart2:1; /* 2 */ + u8 config_uart3:1; /* 3 */ + u8 config_uart4:1; /* 4 */ + u8 config_ipu0:1; /* 5 */ + u8 config_ipu1:1; /* 6 */ + u8 config_flexcan:1; /* 7 */ + + u8 config_mipi_dsi:1;/* 0: 0x45 */ + u8 config_mipi_csi:1;/* 1 */ + u8 config_tzasc0:1; /* 2 */ + u8 config_tzasc1:1; /* 3 */ + u8 config_i2c0:1; /* 4 */ + u8 config_i2c1:1; /* 5 */ + u8 config_i2c2:1; /* 6 */ + u8 config_vpu:1; /* 7 */ + + u8 config_csi0:1; /* 0: 0x46 */ + u8 config_csi1:1; /* 1 */ + u8 config_caam:1; /* 2 */ + u8 config_mezz:1; /* 3 */ + u8 config_res1:1; /* 4 */ + u8 config_res2:1; /* 5 */ + u8 config_res3:1; /* 6 */ + u8 config_res4:1; /* 7 */ + + u8 config_espci0:1; /* 0: 0x47 */ + u8 config_espci1:1; /* 1 */ + u8 config_espci2:1; /* 2 */ + u8 config_espci3:1; /* 3 */ + u8 config_espci4:1; /* 4 */ + u8 config_espci5:1; /* 5 */ + u8 config_res5:1; /* 6 */ + u8 config_res6:1; /* 7 */ + +/* Config2: Other Peripherals */ + u8 config_gps:1; /* 0: 0x48 */ + u8 config_spifl0:1; /* 1 */ + u8 config_spifl1:1; /* 2 */ + u8 config_gspbatt:1; /* 3 */ + u8 config_hdmi_in:1; /* 4 */ + u8 config_vid_out:1; /* 5 */ + u8 config_vid_in:1; /* 6 */ + u8 config_nand:1; /* 7 */ + + u8 config_res8:1; /* 0: 0x49 */ + u8 config_res9:1; /* 1 */ + u8 config_res10:1; /* 2 */ + u8 config_res11:1; /* 3 */ + u8 config_res12:1; /* 4 */ + u8 config_res13:1; /* 5 */ + u8 config_res14:1; /* 6 */ + u8 config_res15:1; /* 7 */ + +u8 res3[4 ];/* 0x4A */ + + u8 chksum[2]; /* 0x4E */ +}; + +#endif boards.cfg +0
-1--- a/boards.cfg
Quoted 8 lines
boards.cfg Active arm armv7 mx6 - udoo udoo_qua · line 298
Quoted 6 lines
+++ b/boards.cfg
boards.cfg +1
-0@@ -295,6 +295,7 @@ Active arm armv7 mx6 - udoo udoo_qua Active arm armv7 mx6 - wandboard wandboard_dl wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_quad wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048 Fabio Estevam <[email protected]> Active arm armv7 mx6 - wandboard wandboard_solo wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512 Fabio Estevam <[email protected]> +Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]>Why do you touch the titanium ?
it wasn't in alphabetical order (barco should be before boundary). I will not touch it as that shouldn't be part of my patch.
Quoted 12 lines
boards.cfg Active arm armv7 mx6 freescale mx6qsabreauto · line 312
Quoted 10 lines
boards.cfg +1
-1Active arm armv7 mx6 boundary nitrogen6x mx6qsabrelite nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q.cfg,MX6Q,DDR_MB=1024,SABRELITE Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024 Eric Nelson <[email protected]> Active arm armv7 mx6 boundary nitrogen6x nitrogen6dl2g nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl2g.cfg,MX6DL,DDR_MB=2048 Eric Nelson <[email protected]>@@ -308,7 +309,11 @@ Active arm armv7 mx6 freescale mx6qsabreauto Active arm armv7 mx6 freescale mx6sabresd mx6dlsabresd mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6sabresd mx6qsabresd mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q Fabio Estevam <[email protected]> Active arm armv7 mx6 freescale mx6slevk mx6slevk mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL Fabio Estevam <[email protected]> -Active arm armv7 mx6 barco titanium titanium titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg Stefan Roese <[email protected]> +Active arm armv7 mx6 gateworks gw_ventana gwventanaq1gspi gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH Tim Harvey <[email protected]>Please let the list sorted.
will do - I failed to sort the new additions with respect to each other.
Incidentally, I noticed that there are quite a few lines out of order from what tools/reformat.py does.
Thanks again for the review! I hope to have a v2 ready in perhaps a week.
Tim
Quoted 10 lines
Best regards,
Stefano Babic--
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
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
=====================================================================
PATCH 1/1 ventana: Add Gateworks Ventana family support
Hi Tim,
Quoted 5 lines · Tim Harvey
I will include the ddr config files from boundary with a ../../boundary/... where they do not differ. The clocks.cfg does differ (see below) but I liked the way Boundary broke these files out do want to re-use as much as possible.
ok, I see. Clock for NAND is not enabled in nitrogen's file. Well, then we should have only clocks.cfg for ventana.
Quoted 26 lines
Quoted 17 lines
Quoted 17 lines
board/gateworks/gw_ventana/README new file +11
-0@@ -0,0 +1,49 @@ +U-Boot for the Gateworks Ventana Product Family boards + +This file contains information for the port of U-Boot to the Gateworks +Ventana Product family boards. + +1. Boot source, boot from NAND +------------------------------ + +The i.MX6 BOOT ROM expects some headers that provide details of NAND layout +and bad block information (referred to as 'bootstreams') which are replicated +multiple times in NAND.Quoted 8 lines
board/gateworks/gw_ventana/README line 14
Quoted 4 lines
The number of replications is configurable through
board/gateworks/gw_ventana/README new file +3
-0+board strapping options and eFUSE settings. The Freescale 'kobs-ng' +application from the Freescale LTIB BSP, which runs under Linux, must be used +to program the bootstream in order to setup the replicated headers correctly.The behavior is quite different as we have currently in mainline. With kobs-ng you flash u-boot.bin, while the result image for i.MXes in mailine is u-boot.imx (u-boot.bin with imx header).
Quoted 4 lines
I'm not familiar with the IMX family other than IMX6 but for IMX6 kobs-ng does use u-boot.imx and not u-boot.bin. kobs needs the headers which are not part of u-boot.bin. Are you sure you are not mistaken here? Can you point me to some references?
I think there is a misunderstanding due to the usage of "headers". What do you mean with headers here ? As you talk about BOOT ROM, the only header that the ROM understands is the i.MX image header, that is the description of the image itself with the DCD and all that stuff. When you say that kobs-ng needs "headers", it seems you are talking about .h files,
As far as I know, kobs-ng is a flasher - a utility to install u-boot on the target. It is not the only method to install the binary. I think you should rework the text making the statements more clearer.
Quoted 4 lines
Regardless of what is loading the next level (u-boot.bin) the initial flashing of NAND is still currently handled only by kobs-ng so I'm not sure how this differs in this respect. I plan to look at adding the functionality of kobs-ng to u-boot at some point.
If as I think kobs-ng is only a flasher, it does not take part to the build of U-Boot binaries. IMHO it should be not part of U-Boot sources, but maybe there are some features that can be interesting.
Quoted 21 lines
Quoted 12 lines
Quoted 12 lines
+ * retries.
+ */board/gateworks/gw_ventana/README new file +10
-0+int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + int retry = 3; + int n = 0; + int ret; + + while (n++ < retry) { + ret = i2c_read(chip, addr, alen, buf, len); + if (!ret) + break;Quoted 8 lines
board/gateworks/gw_ventana/README
Quoted 6 lines
board/gateworks/gw_ventana/README new file +6
-0+ printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, + n, ret); + if (ret != -ENODEV) + break; + mdelay(10); + }Whcih is the benefit of trying three times ?
Quoted 1 line
it provides a little more redundancy than 2 times, and a little less than 4 ;)
As there is no guarantee that works, but it is only statistics, it looks more a workaround as a solution.
Quoted 3 lines
Our GSC can occasionally be 'busy' and NAK (every 1Hz it does some internal processing).
ok - but is there no way to understand that the component is busy ?
I mean, in most hardware solutions (there is plenty of them in Freescale's SOCs), software must poll a bit (a pin, whatever...) to check if it can access the component. Nothing here ?
Quoted 9 lines
As there are several places where I perform an
i2c transaction to one of the GSC's slave devices (it emulates several i2c devices) I wanted to consolidate where I had retry logic. There is nothing magic about 3 tries necessarily but I have found that with the speed of the SoC we never fail more than 2 successive reads due to the periodic loading of the GSC.If you want more info on the GSC you can read about it here:
http://trac.gateworks.com/wiki/gsc
I read the doc - however, there is no mention about this important detail !
Quoted 11 lines
Quoted 11 lines
board/gateworks/gw_ventana/README
Quoted 6 lines
board/gateworks/gw_ventana/README new file +5
-0+ +/* + * For SPL boot some boards need i2c before SDRAM is initialized so force + * variables to live in SRAM + */Agree - but then I will see SPL...
Quoted 1 line
+static struct
ventana_board_info__attribute__((section(".data")))ventana_info;
Quoted 7 lines
Quoted 1 line
Can you explain why do you need this ?
This was in preparation for SPL. I'm not clear if the struct needs any special attributes at this time to be available to all the functions that use it. Because currently the BOOTROM sets up DDR I'm thinking perhaps not, but I seem to recall before I added the attribute I ran into some issues.
If it is at the moment dead code, please remove. Dead code that passes a review will only confuse people.
Quoted 9 lines
Quoted 9 lines
board/gateworks/gw_ventana/README
Quoted 5 lines
+ * should be called once, the first time eeprom data is needed
+ */board/gateworks/gw_ventana/README new file +3
-0+static void +read_eeprom(void) +{You have a I2C eprom. This is supported in U-Boot. Why do you not set
CONFIG_SYS_I2C_EEPROM_ADDRin your config file and use general code ?
Quoted 6 lines
Quoted 1 line
It seems to me you can drop your own read/write_eeprom() function.
I considered this before (using
common/cmd_eeprom.c), but the fact that I want to be able to handle retries on NAK's would keep me from using a genericread_eepromfeature. Also, that common support only just replaces mygsc_i2c_readfunction -
Right, this is what I said with "payload". You have two functions:
- read from hardware
- check and interprete the result
The function that chjeck the data calls the function to read the data.
Quoted 2 lines
inside
read_eepromI verify
checksum and some other sanity checks.
As I said, you can check outside this function.
Quoted 3 lines
Grepping for
CONFIG_SYS_I2C_EEPROM_ADDRthere are a lot of boards that implement their ownread_eepromfunctionality for one reason or another.
Right. But again, if this is not strictly necessary, it is always better to reuse common code. You can also check 3 times the result of read_eeprom() to implement your retry-on-NAK, without implementing your own version.
Quoted 38 lines
Quoted 29 lines
Quoted 29 lines
board/gateworks/gw_ventana/README new file +27
-0+#ifdef CONFIG_CMD_GSC +int read_hwmon(const char *name, uint reg, uint size, uint low, uint high) +{ + unsigned char buf[3]; + uint ui; + int ret; + + printf("%-8s:", name); + memset(buf, 0, sizeof(buf)); + if (gsc_i2c_read(0x29, reg, 1, buf, size)) { + printf("fRD\n"); + ret = -1; + } else { + ret = 0; + ui = buf[0] | (buf[1]<<8) | (buf[2]<<16); + if (ui == 0xffffff) { + printf("fVL"); + } else if (ui < low) { + printf("%d fLO", ui); + ret = -2; + } else if (ui > high) { + printf("%d fHI", ui); + ret = -3; + } else { + printf("%d", ui); + } + }Quoted 8 lines
board/gateworks/gw_ventana/README
Quoted 4 lines
board/gateworks/gw_ventana/README new file +4
-0+ printf("\n"); + + return ret; +}I need help - I have not understood. This functions prints only something - return values is discarded when function is called. Buf is filled, but can you better explain the purpose of the function.
Quoted 4 lines
The gsc command (below) is currently just showing the values from the hardware monitor (temp and various voltage rails). The
read_hwmonfunction above is a helper function to display the value, or a failure high, or failure low in a standard fashion.
ok - then this is only a function that outputs details about hardwrae. Then:
- function must be declared static
- why should the function return a int if it is not checked at all ?
Quoted 9 lines
Quoted 8 lines
board/gateworks/gw_ventana/README
Quoted 6 lines
board/gateworks/gw_ventana/README new file +6
-0+#endif + gpio_direction_output(IMX_GPIO_NR(3, 22), 0); /* OTG power off */ + + /* Note this gets called again later, + * but needed in case i2c bus is stuck */ + timer_init();
timer_init()? I think this is called by generic code.
Quoted 3 lines
it is, but as the common states its called later (at least it was when I first wrote this) and causes one of the error handling functions to hang when it tries to delay.
This is correct. udelay() at this point is not yet working. board_early_init_f() is thought to set up hardware that is required before relocation. At this point, generally clocks and pinmuxes setup take place. The rest should be postponed to a later point, that is, board_init, or even board_late_init() (if you activate it) or misc_init().
Quoted 3 lines
The specific issue I was working around
here had to do with no console output from the bootloader if you had for example an HDMI monitor plugged in with a bad EDID clk/data pin.
You do not need HDMI before relocation.
Quoted 4 lines
Quoted 3 lines
General remak: you print a lot of stuff by booting. This can slow down your boot process significantly adding several seconds to your start up, before the kernel is loaded.
Quoted 8 lines
agreed - perhaps there are some common defines I can use to quiet things down by default or even better an env variable that the user can set?
We've found that showing the boot device, and model in the bootloader is extremely helpfull in supporting users but I suppose I could move some of the other things like DIO/SATA/RS232 configuration (hwconfig controlled) reporting to a user command.
You are mixing two things. During the boot process, it is better to print only what is really needed to speed up the process. The user has maybe no access to the console, and he wants that the system reacts very soon - with kernel, application, everything.
If a user is operating at U-Boot console, he has all the time he wants. Some output can be displayed with an additional command.
See "clocks" command for i.MXes - clock configuration is printed only on demand.
Quoted 7 lines
Quoted 4 lines
Generally, using bitwise fields is deprecated in favour of using maks. This because there is no conventions how the compiler should assign (MSB or LSB) the single bits.
Can you point me to an example? I'm not sure what you mean by 'maks' (macros defining bit positions perhaps?).
I need to buy a new keyboard - "s" key is not working well. It is not "maks", but "masks". Yes, accessing bit with and and or logical operation. And using the provided helper functions (clrsetbits_).
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel 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 =====================================================================
PATCH 1/1 ventana: Add Gateworks Ventana family support
Quoted 4 lines · Stefano Babic
Hi Tim,
On 28/01/2014 00:36, Tim Harvey wrote:
<snip>
Quoted 31 lines
Quoted 26 lines
Quoted 17 lines
Quoted 17 lines
board/gateworks/gw_ventana/README new file +11
-0@@ -0,0 +1,49 @@ +U-Boot for the Gateworks Ventana Product Family boards + +This file contains information for the port of U-Boot to the Gateworks +Ventana Product family boards. + +1. Boot source, boot from NAND +------------------------------ + +The i.MX6 BOOT ROM expects some headers that provide details of NAND layout +and bad block information (referred to as 'bootstreams') which are replicated +multiple times in NAND.Quoted 8 lines
board/gateworks/gw_ventana/README line 14
Quoted 4 lines
The number of replications is configurable through
board/gateworks/gw_ventana/README new file +3
-0+board strapping options and eFUSE settings. The Freescale 'kobs-ng' +application from the Freescale LTIB BSP, which runs under Linux, must be used +to program the bootstream in order to setup the replicated headers correctly.The behavior is quite different as we have currently in mainline. With kobs-ng you flash u-boot.bin, while the result image for i.MXes in mailine is u-boot.imx (u-boot.bin with imx header).
Quoted 4 lines
I'm not familiar with the IMX family other than IMX6 but for IMX6 kobs-ng does use u-boot.imx and not u-boot.bin. kobs needs the headers which are not part of u-boot.bin. Are you sure you are not mistaken here? Can you point me to some references?
Quoted 6 lines
I think there is a misunderstanding due to the usage of "headers". What do you mean with headers here ? As you talk about BOOT ROM, the only header that the ROM understands is the i.MX image header, that is the description of the image itself with the DCD and all that stuff. When you say that kobs-ng needs "headers", it seems you are talking about .h files,
I should not have used the word 'header'.
I _am_ talking about the Image Vector Table (IVT) and Device Configuration Data (DCD) data structures that the IMX6 BOOT ROM needs to boot and which are present in u-boot.imx. The kobs-ng (at least for IMX6) needs u-boot.imx because it contains these structures built from imximage and it must flash them onto the boot media.
Quoted 4 lines
As far as I know, kobs-ng is a flasher - a utility to install u-boot on the target. It is not the only method to install the binary. I think you should rework the text making the statements more clearer.
Can you re-read the README instructions? Other than the bad link I feel they are very clear. I think perhaps your thinking that I was in error specifying that kobs-ng needing u-boot.imx added to some confusion?
Quoted 10 lines
Quoted 5 lines
Regardless of what is loading the next level (u-boot.bin) the initial flashing of NAND is still currently handled only by kobs-ng so I'm not sure how this differs in this respect. I plan to look at adding the functionality of kobs-ng to u-boot at some point.
If as I think kobs-ng is only a flasher, it does not take part to the build of U-Boot binaries. IMHO it should be not part of U-Boot sources, but maybe there are some features that can be interesting.
I was not referring to making the code a part of uboot sources but adding the functionality that it provides such that one could use uboot to update itself on an IMX NAND device. I'm actually surprised nobody has done this before for IMX in general as its a bit inconvenient to boot to a linux based OS in order to run kobs-ng to flash the bootloader. Regardless, this would be functionality added later.
It appears the only other mainlined IMX6 bootloader to support NAND is the Titanium and there is no README for it at all. If there were, I would expect it to say pretty much the same thing that my proposed Ventana README states. There was a comment by Fabio on original titanium patch to include a README explaining how to flash and boot from NAND but it apparently didn't make it in:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/158436/focus=158441
I've added Stefan Roese and Fabio to the cc to hear their thoughts.
Quoted 23 lines
Quoted 21 lines
Quoted 12 lines
Quoted 12 lines
+ * retries.
+ */board/gateworks/gw_ventana/README new file +10
-0+int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len) +{ + int retry = 3; + int n = 0; + int ret; + + while (n++ < retry) { + ret = i2c_read(chip, addr, alen, buf, len); + if (!ret) + break;Quoted 8 lines
board/gateworks/gw_ventana/README
Quoted 6 lines
board/gateworks/gw_ventana/README new file +6
-0+ printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr, + n, ret); + if (ret != -ENODEV) + break; + mdelay(10); + }Whcih is the benefit of trying three times ?
Quoted 1 line
it provides a little more redundancy than 2 times, and a little less than 4 ;)
Quoted 8 lines
As there is no guarantee that works, but it is only statistics, it looks more a workaround as a solution.
Quoted 3 lines
Our GSC can occasionally be 'busy' and NAK (every 1Hz it does some internal processing).
ok - but is there no way to understand that the component is busy ?
No - the only communication channel to the GSC is the i2c bus. The only way it has to respond is to ACK or fail to ACK (aka NAK) within the i2c bit time (aka NAK). The device does not and can not support i2c clock stretching. The nature of GSC is such that the worst case failure when talking at 100kbps will be at most 2 times in a row (due to the latency of the timer tick) which is why I have a retry of 3.
Quoted 4 lines
I mean, in most hardware solutions (there is plenty of them in Freescale's SOCs), software must poll a bit (a pin, whatever...) to check if it can access the component. Nothing here ?
no - this is a 'slave' device on the i2c bus that is too busy to respond in the allotted time, not the controller. This isn't unheard of. Some i2c based EEPROM's need a certain delay after writing for example, before they are ready again for reading.
I 'can' as you say call the common i2c_read and wrap that around 3 retries but I don't any better solution to the other i2c read/writes to the GSC such as reading the hwmon, RTC, or firmware registers with up to 3 retries so it really doesn't shorten the code any. Note that I am using common i2c_read. I don't really see any benefit to using the common eeprom_read over the common i2c_read as I know I'm not wrapping page boundaries.
Would you rather see me implement retries down at the i2c_core level or at the i2c driver level?
Quoted 8 lines
Quoted 8 lines
As there are several places where I perform an
i2c transaction to one of the GSC's slave devices (it emulates several i2c devices) I wanted to consolidate where I had retry logic. There is nothing magic about 3 tries necessarily but I have found that with the speed of the SoC we never fail more than 2 successive reads due to the periodic loading of the GSC.
Quoted 4 lines
Quoted 2 lines
If you want more info on the GSC you can read about it here:
http://trac.gateworks.com/wiki/gscI read the doc - however, there is no mention about this important detail !
fair enough - I have updated the wiki page to make this clear.
Quoted 14 lines
Quoted 14 lines
Quoted 13 lines
board/gateworks/gw_ventana/README
Quoted 7 lines
board/gateworks/gw_ventana/README new file +5
-0+ +/* + * For SPL boot some boards need i2c before SDRAM is initialized so force + * variables to live in SRAM + */Agree - but then I will see SPL...
Quoted 1 line
+static struct
ventana_board_info__attribute__((section(".data")))ventana_info;Can you explain why do you need this ?
Quoted 8 lines
Quoted 5 lines
This was in preparation for SPL. I'm not clear if the struct needs any special attributes at this time to be available to all the functions that use it. Because currently the BOOTROM sets up DDR I'm thinking perhaps not, but I seem to recall before I added the attribute I ran into some issues.
If it is at the moment dead code, please remove. Dead code that passes a review will only confuse people.
once I realized I could #define CONFIG_DISPLAY_BOARDINFO_LATE to make checkconfig() run after relocation I no longer needed to have EEPROM read prior to relocation and that removed the need for this structure to be in the data segement. I still have the structure so that eeprom can be read just once (as its used in several places) but it no longer needs to be in the data segment so the attribute will be removed in the next patch version.
Quoted 21 lines
Quoted 10 lines
Quoted 10 lines
board/gateworks/gw_ventana/README
Quoted 6 lines
+ * should be called once, the first time eeprom data is needed
+ */board/gateworks/gw_ventana/README new file +3
-0+static void +read_eeprom(void) +{You have a I2C eprom. This is supported in U-Boot. Why do you not set
CONFIG_SYS_I2C_EEPROM_ADDRin your config file and use general code ?Quoted 6 lines
Quoted 1 line
It seems to me you can drop your own read/write_eeprom() function.
I considered this before (using
common/cmd_eeprom.c), but the fact that I want to be able to handle retries on NAK's would keep me from using a genericread_eepromfeature. Also, that common support only just replaces mygsc_i2c_readfunction -Right, this is what I said with "payload". You have two functions:
- read from hardware
- check and interprete the result
Quoted 6 lines
The function that chjeck the data calls the function to read the data.
Quoted 2 lines
inside
read_eepromI verify
checksum and some other sanity checks.As I said, you can check outside this function.
sure... but understand the only 'extra' code here is the implementation of gsc_i2c_read and gsc_i2c_write which wrap the common
i2c_read/i2c_write functions around a retry of 3. If I were to use
common i2c_read or eeprom_read I'm only substituting the call to gsc_i2c_read.
Quoted 10 lines
Quoted 4 lines
Grepping for
CONFIG_SYS_I2C_EEPROM_ADDRthere are a lot of boards that implement their ownread_eepromfunctionality for one reason or another.Right. But again, if this is not strictly necessary, it is always better to reuse common code. You can also check 3 times the result of
read_eeprom()to implement your retry-on-NAK, without implementing your own version.
Yes - I could, but then I wouldn't have a solution for the calls that read the other device registers that the GSC emulates (which are at different slave addresses).
Quoted 38 lines
Quoted 38 lines
Quoted 37 lines
Quoted 23 lines
board/gateworks/gw_ventana/README new file +21
-0+#ifdef CONFIG_CMD_GSC +int read_hwmon(const char *name, uint reg, uint size, uint low, uint high) +{ + unsigned char buf[3]; + uint ui; + int ret; + + printf("%-8s:", name); + memset(buf, 0, sizeof(buf)); + if (gsc_i2c_read(0x29, reg, 1, buf, size)) { + printf("fRD\n"); + ret = -1; + } else { + ret = 0; + ui = buf[0] | (buf[1]<<8) | (buf[2]<<16); + if (ui == 0xffffff) { + printf("fVL"); + } else if (ui < low) { + printf("%d fLO", ui); + ret = -2; + } else if (ui > high) {board/gateworks/gw_ventana/README
Quoted 10 lines
board/gateworks/gw_ventana/README new file +10
-0+ printf("%d fHI", ui); + ret = -3; + } else { + printf("%d", ui); + } + } + printf("\n"); + + return ret; +}I need help - I have not understood. This functions prints only something - return values is discarded when function is called. Buf is filled, but can you better explain the purpose of the function.
Quoted 8 lines
Quoted 4 lines
The gsc command (below) is currently just showing the values from the hardware monitor (temp and various voltage rails). The
read_hwmonfunction above is a helper function to display the value, or a failure high, or failure low in a standard fashion.ok - then this is only a function that outputs details about hardwrae. Then:
- function must be declared static
- why should the function return a int if it is not checked at all ?
Its both displaying the value and evaluating the value for pass, fail (high) and fail (low). As those return codes are not used, I'll remove the return value.
Quoted 14 lines
Quoted 10 lines
Quoted 9 lines
board/gateworks/gw_ventana/README
Quoted 7 lines
board/gateworks/gw_ventana/README new file +6
-0+#endif + gpio_direction_output(IMX_GPIO_NR(3, 22), 0); /* OTG power off */ + + /* Note this gets called again later, + * but needed in case i2c bus is stuck */ + timer_init();
timer_init()? I think this is called by generic code.Quoted 3 lines
it is, but as the common states its called later (at least it was when I first wrote this) and causes one of the error handling functions to hang when it tries to delay.
Quoted 6 lines
This is correct.
udelay()at this point is not yet working.board_early_init_f()is thought to set up hardware that is required before relocation. At this point, generally clocks and pinmuxes setup take place. The rest should be postponed to a later point, that is,board_init, or evenboard_late_init()(if you activate it) ormisc_init().
got it - moving checkboard() to late init resolved this.
Quoted 7 lines
Quoted 4 lines
The specific issue I was working around
here had to do with no console output from the bootloader if you had for example an HDMI monitor plugged in with a bad EDID clk/data pin.You do not need HDMI before relocation.
agreed - will be fixed
Quoted 19 lines
Quoted 5 lines
Quoted 4 lines
General remak: you print a lot of stuff by booting. This can slow down your boot process significantly adding several seconds to your start up, before the kernel is loaded.
Quoted 8 lines
agreed - perhaps there are some common defines I can use to quiet things down by default or even better an env variable that the user can set?
We've found that showing the boot device, and model in the bootloader is extremely helpfull in supporting users but I suppose I could move some of the other things like DIO/SATA/RS232 configuration (hwconfig controlled) reporting to a user command.
You are mixing two things. During the boot process, it is better to print only what is really needed to speed up the process. The user has maybe no access to the console, and he wants that the system reacts very soon - with kernel, application, everything.
Quoted 6 lines
If a user is operating at U-Boot console, he has all the time he wants. Some output can be displayed with an additional command.
See "clocks" command for i.MXes - clock configuration is printed only on demand.
agreed - I will move most of this into user commands.
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Generally, using bitwise fields is deprecated in favour of using maks. This because there is no conventions how the compiler should assign (MSB or LSB) the single bits.
Quoted 6 lines
Quoted 2 lines
Can you point me to an example? I'm not sure what you mean by 'maks' (macros defining bit positions perhaps?).
I need to buy a new keyboard - "s" key is not working well. It is not "maks", but "masks". Yes, accessing bit with and and or logical operation. And using the provided helper functions (
clrsetbits_).
I'll for sure take a stab at this - I've been wanting to re-define that structure using macros for a while anyway.
Thanks,
Tim
Quoted 10 lines
Best regards,
Stefano Babic--
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
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
=====================================================================
PATCH 1/1 ventana: Add Gateworks Ventana family support
Hi Tim,
Quoted 10 lines · Tim Harvey
Quoted 9 lines
Quoted 4 lines
Regardless of what is loading the next level (u-boot.bin) the initial flashing of NAND is still currently handled only by kobs-ng so I'm not sure how this differs in this respect. I plan to look at adding the functionality of kobs-ng to u-boot at some point.
If as I think kobs-ng is only a flasher, it does not take part to the build of U-Boot binaries. IMHO it should be not part of U-Boot sources, but maybe there are some features that can be interesting.
Quoted 7 lines
I was not referring to making the code a part of uboot sources but adding the functionality that it provides such that one could use uboot to update itself on an IMX NAND device. I'm actually surprised nobody has done this before for IMX in general as its a bit inconvenient to boot to a linux based OS in order to run kobs-ng to flash the bootloader. Regardless, this would be functionality added later.
That would be really convenient. Not having to boot Linux and to rely on kobs-ng for flashing U-Boot for NAND booting imx6.
Quoted 9 lines
It appears the only other mainlined IMX6 bootloader to support NAND is the Titanium and there is no README for it at all. If there were, I would expect it to say pretty much the same thing that my proposed Ventana README states. There was a comment by Fabio on original titanium patch to include a README explaining how to flash and boot from NAND but it apparently didn't make it in:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/158436/focus=158441I've added Stefan Roese and Fabio to the cc to hear their thoughts.
Yes, your README seems correct to me. So for this README:
Thanks,
Stefan
PATCH 1/1 ventana: Add Gateworks Ventana family support
In reply to Tim HarveyHi Tim,
Quoted 6 lines · Tim Harvey
I should not have used the word 'header'.
I _am_ talking about the Image Vector Table (IVT) and Device Configuration Data (DCD) data structures that the IMX6 BOOT ROM needs to boot and which are present in u-boot.imx.
Right.
Quoted 3 lines
The kobs-ng (at least
for IMX6) needs u-boot.imx because it contains these structures built from imximage and it must flash them onto the boot media.
ok, got it. My suggestion is then only to headline that kons-ng uses a imximage, that contains IVT and DCD.
Quoted 10 lines
Quoted 5 lines
As far as I know, kobs-ng is a flasher - a utility to install u-boot on the target. It is not the only method to install the binary. I think you should rework the text making the statements more clearer.
Can you re-read the README instructions? Other than the bad link I feel they are very clear. I think perhaps your thinking that I was in error specifying that kobs-ng needing u-boot.imx added to some confusion?
Yes, it had confused me. IMHO you could add that kobs-ng adds the FCB structure that it is not (yet) provided by imximage.
Quoted 6 lines
Quoted 5 lines
If as I think kobs-ng is only a flasher, it does not take part to the build of U-Boot binaries. IMHO it should be not part of U-Boot sources, but maybe there are some features that can be interesting.
Quoted 8 lines
I was not referring to making the code a part of uboot sources but adding the functionality that it provides such that one could use uboot to update itself on an IMX NAND device. I'm actually surprised nobody has done this before for IMX in general as its a bit inconvenient to boot to a linux based OS in order to run kobs-ng to flash the bootloader.
Regardless, this would be functionality added
later.
It would be great. Of course, it will be great if we can flash NAND exactly as we do for other SOCs. We will need to improve imximage to add the FCB at the beginning of the image.
Quoted 8 lines
It appears the only other mainlined IMX6 bootloader to support NAND is the Titanium and there is no README for it at all. If there were, I would expect it to say pretty much the same thing that my proposed Ventana README states. There was a comment by Fabio on original titanium patch to include a README explaining how to flash and boot from NAND but it apparently didn't make it in:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/158436/focus=158441
Good point. Stefan, how do you flash the titanium ? At the moment I do not see any other way as using the kobs-ng. Or do you have some early improvement for mkimage adding the FCB/DBBT data ?
Quoted 7 lines
No - the only communication channel to the GSC is the i2c bus. The only way it has to respond is to ACK or fail to ACK (aka NAK) within the i2c bit time (aka NAK). The device does not and can not support i2c clock stretching. The nature of GSC is such that the worst case failure when talking at 100kbps will be at most 2 times in a row (due to the latency of the timer tick) which is why I have a retry of 3.
ok - I think it will be cleaner if you split your patch and move gsc code in a separate file, still in your board directory. I understand the point - if the hardware does not provide any way to check if it is busy, it is ok to retry when first access fails.
Quoted 10 lines
Quoted 2 lines
If it is at the moment dead code, please remove. Dead code that passes a review will only confuse people.
once I realized I could #define
CONFIG_DISPLAY_BOARDINFO_LATEto makecheckconfig()run after relocation I no longer needed to have EEPROM read prior to relocation and that removed the need for this structure to be in the data segement. I still have the structure so that eeprom can be read just once (as its used in several places) but it no longer needs to be in the data segment so the attribute will be removed in the next patch version.
Fine.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel 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 =====================================================================
PATCH 1/1 ventana: Add Gateworks Ventana family support
Hi Stefano,
Quoted 11 lines · Stefano Babic
Quoted 7 lines
It appears the only other mainlined IMX6 bootloader to support NAND is the Titanium and there is no README for it at all. If there were, I would expect it to say pretty much the same thing that my proposed Ventana README states. There was a comment by Fabio on original titanium patch to include a README explaining how to flash and boot from NAND but it apparently didn't make it in:
http://thread.gmane.org/gmane.comp.boot-loaders.u-boot/158436/focus=158441Good point. Stefan, how do you flash the titanium ? At the moment I do not see any other way as using the kobs-ng. Or do you have some early improvement for mkimage adding the FCB/DBBT data ?
No. As already mentioned in my previous mail, I also used kobs-ng via Linux to flash the NAND booting image.
Thanks,
Stefan