[U-Boot] [PATCH 07/12] MX6: add structs for mmdc and ddr iomux registers

Stefano Babic sbabic at denx.de
Mon May 5 12:34:34 CEST 2014


Hi Tim,

On 28/04/2014 22:17, Tim Harvey wrote:
> Add memory-mapped structures for MMDC iomux and configuration. Note that while
> the MMDC configuration registers are common between the IMX6DQ
> (IMX6DUAL/IMX6QUAD) and IMX6SDL (IMX6SOLO/IMX6DUALLITE) types the iomux
> registers differ. This requires two sets of structures.
> 
> Add structures to describe DDR3 device information, system information
> (memory layout, etc), and MMDC calibration regitsers that can be used to
> configure the MMDC dynamically.
> 
> We define these structures for SPL builds instead of including mx6q-ddr.h and
> mx6dl-ddr.h which use the same namespace and are only useful for imximage cfg
> files.
> 
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> ---
> v2:
> - split out from original mmdc configuration patch
> - only define for SPL build
> - do not include mx6q-ddr.h and mx6dl-ddr.h for SPL build - these use the
>   same namespace and are only useful for imximage cfg files
> ---
>  arch/arm/include/asm/arch-mx6/mx6-ddr.h | 231 ++++++++++++++++++++++++++++++++
>  1 file changed, 231 insertions(+)
> 
> diff --git a/arch/arm/include/asm/arch-mx6/mx6-ddr.h b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> index 43d377a..d544d2e 100644
> --- a/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> +++ b/arch/arm/include/asm/arch-mx6/mx6-ddr.h
> @@ -6,6 +6,7 @@
>  #ifndef __ASM_ARCH_MX6_DDR_H__
>  #define __ASM_ARCH_MX6_DDR_H__
>  
> +#ifndef CONFIG_SPL_BUILD
>  #ifdef CONFIG_MX6Q
>  #include "mx6q-ddr.h"
>  #else
> @@ -15,6 +16,236 @@
>  #error "Please select cpu"
>  #endif	/* CONFIG_MX6DL or CONFIG_MX6S */
>  #endif	/* CONFIG_MX6Q */
> +#else
> +
> +/* MMDC P0/P1 Registers */
> +struct mmdc_p_regs {
> +	u32 mdctl;
> +	u32 mdpdc;
> +	u32 mdotc;
> +	u32 mdcfg0;
> +	u32 mdcfg1;
> +	u32 mdcfg2;
> +	u32 mdmisc;
> +	u32 mdscr;
> +	u32 mdref;
> +	u32 res1[2];
> +	u32 mdrwd;
> +	u32 mdor;
> +	u32 res2[3];
> +	u32 mdasp;
> +	u32 res3[240];
> +	u32 mapsr;
> +	u32 res4[254];
> +	u32 mpzqhwctrl;
> +	u32 res5[2];
> +	u32 mpwldectrl0;
> +	u32 mpwldectrl1;
> +	u32 res6;
> +	u32 mpodtctrl;
> +	u32 mprddqby0dl;
> +	u32 mprddqby1dl;
> +	u32 mprddqby2dl;
> +	u32 mprddqby3dl;
> +	u32 res7[4];
> +	u32 mpdgctrl0;
> +	u32 mpdgctrl1;
> +	u32 res8;
> +	u32 mprddlctl;
> +	u32 res9;
> +	u32 mpwrdlctl;
> +	u32 res10[25];
> +	u32 mpmur0;
> +};
> +
> +/*
> + * MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
> + */
> +#define MX6DQ_IOM_DDR_BASE      0x020e0500

It is only a question - having the value here let us know where the
registers are located. Anyway, registers' offsets are stored in the
imx-regs.h file of the SOC. Which is the reason to set them here ?

> +struct mx6dq_iomux_ddr_regs {
> +	u32 res1[3];
> +	u32 dram_sdqs5;
> +	u32 dram_dqm5;
> +	u32 dram_dqm4;
> +	u32 dram_sdqs4;
> +	u32 dram_sdqs3;
> +	u32 dram_dqm3;
> +	u32 dram_sdqs2;
> +	u32 dram_dqm2;
> +	u32 res2[16];
> +	u32 dram_cas;
> +	u32 res3[2];
> +	u32 dram_ras;
> +	u32 dram_reset;
> +	u32 res4[2];
> +	u32 dram_sdclk_0;
> +	u32 dram_sdba2;
> +	u32 dram_sdcke0;
> +	u32 dram_sdclk_1;
> +	u32 dram_sdcke1;
> +	u32 dram_sdodt0;
> +	u32 dram_sdodt1;
> +	u32 res5;
> +	u32 dram_sdqs0;
> +	u32 dram_dqm0;
> +	u32 dram_sdqs1;
> +	u32 dram_dqm1;
> +	u32 dram_sdqs6;
> +	u32 dram_dqm6;
> +	u32 dram_sdqs7;
> +	u32 dram_dqm7;
> +};
> +
> +#define MX6DQ_IOM_GRP_BASE      0x020e0700
> +struct mx6dq_iomux_grp_regs {
> +	u32 res1[18];
> +	u32 grp_b7ds;
> +	u32 grp_addds;
> +	u32 grp_ddrmode_ctl;
> +	u32 res2;
> +	u32 grp_ddrpke;
> +	u32 res3[6];
> +	u32 grp_ddrmode;
> +	u32 res4[3];
> +	u32 grp_b0ds;
> +	u32 grp_b1ds;
> +	u32 grp_ctlds;
> +	u32 res5;
> +	u32 grp_b2ds;
> +	u32 grp_ddr_type;
> +	u32 grp_b3ds;
> +	u32 grp_b4ds;
> +	u32 grp_b5ds;
> +	u32 grp_b6ds;
> +};
> +
> +#define MX6SDL_IOM_DDR_BASE     0x020e0400
> +struct mx6sdl_iomux_ddr_regs {
> +	u32 res1[25];
> +	u32 dram_cas;
> +	u32 res2[2];
> +	u32 dram_dqm0;
> +	u32 dram_dqm1;
> +	u32 dram_dqm2;
> +	u32 dram_dqm3;
> +	u32 dram_dqm4;
> +	u32 dram_dqm5;
> +	u32 dram_dqm6;
> +	u32 dram_dqm7;
> +	u32 dram_ras;
> +	u32 dram_reset;
> +	u32 res3[2];
> +	u32 dram_sdba2;
> +	u32 dram_sdcke0;
> +	u32 dram_sdcke1;
> +	u32 dram_sdclk_0;
> +	u32 dram_sdclk_1;
> +	u32 dram_sdodt0;
> +	u32 dram_sdodt1;
> +	u32 dram_sdqs0;
> +	u32 dram_sdqs1;
> +	u32 dram_sdqs2;
> +	u32 dram_sdqs3;
> +	u32 dram_sdqs4;
> +	u32 dram_sdqs5;
> +	u32 dram_sdqs6;
> +	u32 dram_sdqs7;
> +};
> +
> +#define MX6SDL_IOM_GRP_BASE     0x020e0700
> +struct mx6sdl_iomux_grp_regs {
> +	u32 res1[18];
> +	u32 grp_b7ds;
> +	u32 grp_addds;
> +	u32 grp_ddrmode_ctl;
> +	u32 grp_ddrpke;
> +	u32 res2[2];
> +	u32 grp_ddrmode;
> +	u32 grp_b0ds;
> +	u32 res3;
> +	u32 grp_ctlds;
> +	u32 grp_b1ds;
> +	u32 grp_ddr_type;
> +	u32 grp_b2ds;
> +	u32 grp_b3ds;
> +	u32 grp_b4ds;
> +	u32 grp_b5ds;
> +	u32 res4;
> +	u32 grp_b6ds;
> +};
> +
> +/* Device Information: Varies per DDR3 part number and speed grade */
> +struct mx6_ddr3_cfg {
> +	u16 mem_speed;	/* ie 1600 for DDR3-1600 (800,1066,1333,1600) */
> +	u8 density;	/* chip density (Gb) (1,2,4,8) */
> +	u8 width;	/* bus width (bits) (4,8,16) */
> +	u8 banks;	/* number of banks */
> +	u8 rowaddr;	/* row address bits (11-16)*/
> +	u8 coladdr;	/* col address bits (9-12) */
> +	u8 pagesz;	/* page size (K) (1-2) */
> +	u16 trcd;	/* tRCD=tRP=CL (ns*100) */
> +	u16 trcmin;	/* tRC min (ns*100) */
> +	u16 trasmin;	/* tRAS min (ns*100) */
> +	u8 SRT;		/* self-refresh temperature: 0=normal, 1=extended */
> +};
> +
> +/* System Information: Varies per board design, layout, and term choices */
> +struct mx6_ddr_sysinfo {
> +	u8 dsize;	/* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */
> +	u8 cs_density;	/* density per chip select (Gb) */
> +	u8 ncs;		/* number chip selects used (1|2) */
> +	char cs1_mirror;/* enable address mirror (0|1) */
> +	char bi_on;	/* Bank interleaving enable */
> +	u8 rtt_nom;	/* Rtt_Nom (DDR3_RTT_*) */
> +	u8 rtt_wr;	/* Rtt_Wr (DDR3_RTT_*) */
> +	u8 ralat;	/* Read Additional Latency (0-7) */
> +	u8 walat;	/* Write Additional Latency (0-3) */
> +	u8 mif3_mode;	/* Command prediction working mode */
> +	u8 rst_to_cke;	/* Time from SDE enable to CKE rise */
> +	u8 sde_to_rst;	/* Time from SDE enable until DDR reset# is high */
> +};
> +
> +/*
> + * Board specific calibration:
> + *   This includes write leveling calibration values as well as DQS gating
> + *   and read/write delays. These values are board/layout/device specific.
> + *   Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2
> + *   (DOC-96412) to determine these values over a range of boards and
> + *   temperatures.
> + */
> +struct mx6_mmdc_calibration {
> +	/* write leveling calibration */
> +	u32 p0_mpwldectrl0;
> +	u32 p0_mpwldectrl1;
> +	u32 p1_mpwldectrl0;
> +	u32 p1_mpwldectrl1;
> +	/* read DQS gating */
> +	u32 p0_mpdgctrl0;
> +	u32 p0_mpdgctrl1;
> +	u32 p1_mpdgctrl0;
> +	u32 p1_mpdgctrl1;
> +	/* read delay */
> +	u32 p0_mprddlctl;
> +	u32 p1_mprddlctl;
> +	/* write delay */
> +	u32 p0_mpwrdlctl;
> +	u32 p1_mpwrdlctl;
> +};
> +

I agree on theses structures. It is then simpler for a board maintainer
to understand what is required to add SPL support for the own board.

> +/* configure iomux (pinctl/padctl) */
> +void mx6dq_dram_iocfg(unsigned width,
> +		      const struct mx6dq_iomux_ddr_regs *,
> +		      const struct mx6dq_iomux_grp_regs *);
> +void mx6sdl_dram_iocfg(unsigned width,
> +		       const struct mx6sdl_iomux_ddr_regs *,
> +		       const struct mx6sdl_iomux_grp_regs *);
> +
> +/* configure mx6 mmdc registers */
> +void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
> +		  const struct mx6_mmdc_calibration *,
> +		  const struct mx6_ddr3_cfg *);
> +
> +#endif /* CONFIG_SPL_BUILD */
>  
>  #define MX6_MMDC_P0_MDCTL	0x021b0000
>  #define MX6_MMDC_P0_MDPDC	0x021b0004
> 

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
=====================================================================


More information about the U-Boot mailing list