[U-Boot] [PATCH v4 2/2] wandboard: Add support for the MX6QP variant

Stefano Babic sbabic at denx.de
Wed Oct 4 09:34:47 UTC 2017


Hi Fabio,

On 02/10/2017 20:47, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam at nxp.com>
> 
> Add support for the latest MX6QP wandboard variant.
> 
> Based on Richard Hu's work from Technexion's U-Boot tree.
> 
> Signed-off-by: Fabio Estevam <fabio.estevam at nxp.com>
> ---
> Changes since v3:
> - Rebased against latest u-boot-imx
> 
>  arch/arm/include/asm/arch-mx6/imx-regs.h |   3 +
>  board/wandboard/spl.c                    | 135 ++++++++++++++++++++++++++++++-
>  board/wandboard/wandboard.c              |   6 +-
>  include/configs/wandboard.h              |   2 +
>  4 files changed, 142 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
> index 86e2670..624ccec 100644
> --- a/arch/arm/include/asm/arch-mx6/imx-regs.h
> +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
> @@ -346,6 +346,9 @@
>  #define IOMUXC_SNVS_BASE_ADDR       (AIPS3_ARB_BASE_ADDR + 0x90000)
>  #define SNVS_GPR_BASE_ADDR          (AIPS3_ARB_BASE_ADDR + 0x94000)
>  #endif
> +
> +#define NOC_DDR_BASE_ADDR           (GPV0_BASE_ADDR + 0xB0000)
> +
>  /* Only for i.MX6SX */
>  #define LCDIF2_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x24000)
>  #define MX6SX_LCDIF1_BASE_ADDR      (AIPS3_ARB_BASE_ADDR + 0x20000)
> diff --git a/board/wandboard/spl.c b/board/wandboard/spl.c
> index 00c75d0..2446699 100644
> --- a/board/wandboard/spl.c
> +++ b/board/wandboard/spl.c
> @@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
>  
>  #define IMX6DQ_DRIVE_STRENGTH		0x30
>  #define IMX6SDL_DRIVE_STRENGTH		0x28
> +#define IMX6QP_DRIVE_STRENGTH		0x28
>  
>  /* configure MX6Q/DUAL mmdc DDR io registers */
>  static struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
> @@ -260,15 +261,145 @@ static void ccgr_init(void)
>  	writel(0x00C03F3F, &ccm->CCGR0);
>  	writel(0x0030FC03, &ccm->CCGR1);
>  	writel(0x0FFFC000, &ccm->CCGR2);
> -	writel(0x3FF00000, &ccm->CCGR3);
> +	writel(0x3FF03000, &ccm->CCGR3);
>  	writel(0x00FFF300, &ccm->CCGR4);
>  	writel(0x0F0000C3, &ccm->CCGR5);
>  	writel(0x000003FF, &ccm->CCGR6);
>  }
>  
> +static void spl_dram_init_imx6qp_lpddr3(void)
> +{
> +	/* DDR IO TYPE */
> +	writel(0x000C0000, IOMUXC_BASE_ADDR + 0x798);
> +	writel(0x00000000, IOMUXC_BASE_ADDR + 0x758);
> +	/* Clock */
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x588);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x594);
> +	/* Address */
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x56c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x578);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x74c);
> +	/* Control */
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x57c);
> +	writel(0x00000000, IOMUXC_BASE_ADDR + 0x58c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x59c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5a0);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x78c);
> +	/* Data Strobe */
> +	writel(0x00020000, IOMUXC_BASE_ADDR + 0x750);

mmhhh...it looks to me we are diverging with this SOC. I understand that
current funtions are not suitable for the new SOC. However, we were able
to manage up now to write tables (mx6dq_iomux_ddr_regs) and use
functions to setup the strength and the other parameters. As your tests
has proofed that these functions do not work for MX6QP, the logical way
to do is to modify these functions instead of putting back all this code
in the board file. Do you agree ?


> +
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5a8);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5b0);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x524);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x51c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x518);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x50c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5b8);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5c0);
> +	/* Data */
> +	writel(0x00020000, IOMUXC_BASE_ADDR + 0x774);
> +
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x784);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x788);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x794);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x79c);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x7a0);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x7a4);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x7a8);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x748);
> +
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5ac);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5b4);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x528);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x520);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x514);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x510);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5bc);
> +	writel(IMX6QP_DRIVE_STRENGTH, IOMUXC_BASE_ADDR + 0x5c4);
> +> +	/* MMDC0_MDSCR set the Configuration request bit during MMDC set up */
> +	writel(0x00008000, MMDC_P0_BASE_ADDR + 0x01c);

Then we are starting with a custom version of mx6_dram_cfg(). But again,
we should change the common code, and let the board maintainer to simply
call these function.

I am sure that if we let this code in, we will get in short time a lot
of boards doing exactly in the same way. :-(

> +
> +	/* Calibrations - ZQ */
> +	writel(0xa1390003, MMDC_P0_BASE_ADDR + 0x800);
> +	/* write leveling */
> +	writel(0x00060004, MMDC_P0_BASE_ADDR + 0x80c);
> +	writel(0x000B0004, MMDC_P0_BASE_ADDR + 0x810);
> +	writel(0x00000004, MMDC_P1_BASE_ADDR + 0x80c);
> +	writel(0x00000000, MMDC_P1_BASE_ADDR + 0x810);
> +	/*

Calibration is also part of mx6_dram_cfg(). I want to avoid that MX6QP
is an island in the MX6 infrastructure.


> +	 * DQS gating, read delay, write delay calibration values
> +	 * based on calibration compare of 0x00ffff00
> +	 */
> +	writel(0x03040314, MMDC_P0_BASE_ADDR + 0x83c);
> +	writel(0x03080300, MMDC_P0_BASE_ADDR + 0x840);
> +	writel(0x03000310, MMDC_P1_BASE_ADDR + 0x83c);
> +	writel(0x0268023C, MMDC_P1_BASE_ADDR + 0x840);
> +
> +	writel(0x4034363A, MMDC_P0_BASE_ADDR + 0x848);
> +	writel(0x36302C3C, MMDC_P1_BASE_ADDR + 0x848);
> +
> +	writel(0x3E3E4046, MMDC_P0_BASE_ADDR + 0x850);
> +	writel(0x483A4844, MMDC_P1_BASE_ADDR + 0x850);
> +
> +	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x81c);
> +	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x820);
> +	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x824);
> +	writel(0x33333333, MMDC_P0_BASE_ADDR + 0x828);
> +	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x81c);
> +	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x820);
> +	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x824);
> +	writel(0x33333333, MMDC_P1_BASE_ADDR + 0x828);
> +
> +	writel(0x24912489, MMDC_P0_BASE_ADDR + 0x8c0);
> +	writel(0x24914452, MMDC_P1_BASE_ADDR + 0x8c0);
> +
> +	writel(0x00000800, MMDC_P0_BASE_ADDR + 0x8b8);
> +	writel(0x00000800, MMDC_P1_BASE_ADDR + 0x8b8);
> +	/* MMDC init: in DDR3, 64-bit mode, only MMDC0 is initiated */
> +	writel(0x00020036, MMDC_P0_BASE_ADDR + 0x004);
> +	writel(0x09444040, MMDC_P0_BASE_ADDR + 0x008);
> +	writel(0x898E79A4, MMDC_P0_BASE_ADDR + 0x00c);
> +	writel(0xDB538F64, MMDC_P0_BASE_ADDR + 0x010);
> +	writel(0x01FF00DD, MMDC_P0_BASE_ADDR + 0x014);
> +
> +	writel(0x00011740, MMDC_P0_BASE_ADDR + 0x018);
> +	writel(0x00008000, MMDC_P0_BASE_ADDR + 0x01c);
> +	writel(0x000026D2, MMDC_P0_BASE_ADDR + 0x02c);
> +	writel(0x008E1023, MMDC_P0_BASE_ADDR + 0x030);
> +	writel(0x00000047, MMDC_P0_BASE_ADDR + 0x040);
> +
> +	writel(0x14420000, MMDC_P0_BASE_ADDR + 0x400);
> +	writel(0x841A0000, MMDC_P0_BASE_ADDR + 0x000);
> +	writel(0x00400c58, MMDC_P0_BASE_ADDR + 0x890);
> +
> +	/* add NOC DDR configuration */
> +	writel(0x00000000, NOC_DDR_BASE_ADDR + 0x008);
> +	writel(0x2871C39B, NOC_DDR_BASE_ADDR + 0x00c);
> +	writel(0x000005B4, NOC_DDR_BASE_ADDR + 0x038);
> +	writel(0x00000040, NOC_DDR_BASE_ADDR + 0x014);
> +	writel(0x00000020, NOC_DDR_BASE_ADDR + 0x028);
> +	writel(0x00000020, NOC_DDR_BASE_ADDR + 0x02c);
> +
> +	writel(0x02088032, MMDC_P0_BASE_ADDR + 0x01c);
> +	writel(0x00008033, MMDC_P0_BASE_ADDR + 0x01c);
> +	writel(0x00048031, MMDC_P0_BASE_ADDR + 0x01c);
> +	writel(0x19308030, MMDC_P0_BASE_ADDR + 0x01c);
> +	writel(0x04008040, MMDC_P0_BASE_ADDR + 0x01c);
> +
> +	writel(0x00007800, MMDC_P0_BASE_ADDR + 0x020);
> +	writel(0x00022227, MMDC_P0_BASE_ADDR + 0x818);
> +	writel(0x00022227, MMDC_P1_BASE_ADDR + 0x818);
> +	writel(0x00025576, MMDC_P0_BASE_ADDR + 0x004);
> +	writel(0x00011006, MMDC_P0_BASE_ADDR + 0x404);
> +	writel(0x00000000, MMDC_P0_BASE_ADDR + 0x01c);
> +}
> +
>  static void spl_dram_init(void)
>  {
> -	if (is_cpu_type(MXC_CPU_MX6SOLO)) {
> +	if (is_mx6dqp()) {
> +		spl_dram_init_imx6qp_lpddr3();
> +	} else if (is_cpu_type(MXC_CPU_MX6SOLO)) {
>  		mx6sdl_dram_iocfg(32, &mx6sdl_ddr_ioregs, &mx6sdl_grp_ioregs);
>  		mx6_dram_cfg(&mem_s, &mx6s_512m_mmdc_calib, &h5tq2g63dfr);
>  	} else if (is_cpu_type(MXC_CPU_MX6DL)) {
> diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c
> index 6d2609c..051560f 100644
> --- a/board/wandboard/wandboard.c
> +++ b/board/wandboard/wandboard.c
> @@ -512,7 +512,9 @@ int board_late_init(void)
>  #endif
>  
>  #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
> -	if (is_mx6dq())
> +	if (is_mx6dqp())
> +		env_set("board_rev", "MX6QP");
> +	else if (is_mx6dq())
>  		env_set("board_rev", "MX6Q");
>  	else
>  		env_set("board_rev", "MX6DL");
> @@ -534,7 +536,7 @@ int board_init(void)
>  
>  #if defined(CONFIG_VIDEO_IPUV3)
>  	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c2_pad_info);
> -	if (is_mx6dq()) {
> +	if (is_mx6dq() || is_mx6dqp()) {
>  		setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c2_pad_info);
>  		setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c3_pad_info);
>  	} else {
> diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
> index ba88d02..8fdfc02 100644
> --- a/include/configs/wandboard.h
> +++ b/include/configs/wandboard.h
> @@ -109,6 +109,8 @@
>  			"fi; "	\
>  		"fi\0" \
>  	"findfdt="\
> +		"if test $board_name = D1 && test $board_rev = MX6QP ; then " \
> +			"setenv fdtfile imx6qp-wandboard-revd1.dtb; fi; " \
>  		"if test $board_name = D1 && test $board_rev = MX6Q ; then " \
>  			"setenv fdtfile imx6q-wandboard-revd1.dtb; fi; " \
>  		"if test $board_name = D1 && test $board_rev = MX6DL ; then " \
> 

Best regards,
Stefano

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================


More information about the U-Boot mailing list