All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andreas Bießmann" <andreas.devel@googlemail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/3] arm: at91/spl: mpddrc: add mpddrc DDR3-SDRAM initialization
Date: Fri, 27 Nov 2015 22:36:30 +0100	[thread overview]
Message-ID: <5658CCDE.9090903@googlemail.com> (raw)
In-Reply-To: <1446618755-11300-3-git-send-email-wenyou.yang@atmel.com>

Hi Wenyou,

On 04.11.15 07:32, Wenyou Yang wrote:
> The implementation conforms to DDR3-SRAM/DDR3L-SDRAM
typo ----------------------------------^

> initialization section described in the SAMA5D2 datasheet.
> 
> Add registers and definitions of mpddrc controller, which is used
> to support DDR3 devices.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
> 
>  arch/arm/mach-at91/include/mach/atmel_mpddrc.h |   88 +++++++++++++++++++++---
>  arch/arm/mach-at91/mpddrc.c                    |   87 +++++++++++++++++++++++
>  2 files changed, 167 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h
> index 47b4cd4..e777e67 100644
> --- a/arch/arm/mach-at91/include/mach/atmel_mpddrc.h
> +++ b/arch/arm/mach-at91/include/mach/atmel_mpddrc.h
> @@ -2,6 +2,9 @@
>   * Copyright (C) 2013 Atmel Corporation
>   *		      Bo Shen <voice.shen@atmel.com>
>   *
> + * Copyright (C) 2015 Atmel Corporation
> + *		      Wenyou Yang <wenyou.yang@atmel.com>
> + *
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> @@ -23,14 +26,38 @@ struct atmel_mpddrc_config {
>   * If other register needed, will add them later

This comment should be removed

>   */
>  struct atmel_mpddr {
> -	u32 mr;
> -	u32 rtr;
> -	u32 cr;
> -	u32 tpr0;
> -	u32 tpr1;
> -	u32 tpr2;
> -	u32 reserved[2];
> -	u32 md;
> +	u32 mr;			/* 0x00: Mode Register */
> +	u32 rtr;		/* 0x04: Refresh Timer Register */
> +	u32 cr;			/* 0x08: Configuration Register */
> +	u32 tpr0;		/* 0x0c: Timing Parameter 0 Register */
> +	u32 tpr1;		/* 0x10: Timing Parameter 1 Register */
> +	u32 tpr2;		/* 0x14: Timing Parameter 2 Register */
> +	u32 reserved;		/* 0x18: Reserved */
> +	u32 lpr;		/* 0x1c: Low-power Register */
> +	u32 md;			/* 0x20: Memory Device Register */
> +	u32 reserved1;		/* 0x24: Reserved */

This is the MPDDRC High Speed Register for sama5d3

> +	u32 lpddr23_lpr;	/* 0x28: LPDDR2-LPDDR3 Low-power Register*/
> +	u32 cal_mr4;		/* 0x2c: LPDDR2 LPDDR3 and DDR3 Calibration and MR4 Register */
> +	u32 tim_cal;		/* 0x30: LPDDR2 LPDDR3 and DDR3 Timing Calibration Register */
> +	u32 io_calibr;		/* 0x34: IO Calibration */
> +	u32 ocms;		/* 0x38: OCMS Register */
> +	u32 ocms_key1;		/* 0x3c: OCMS KEY1 Register */
> +	u32 ocms_key2;		/* 0x40: OCMS KEY2 Register */
> +	u32 conf_arbiter;	/* 0x44: Configuration Arbiter Register */
> +	u32 timeout;		/* 0x48: Timeout Port 0/1/2/3 Register */
> +	u32 req_port0123;	/* 0x4c: Request Port 0/1/2/3 Register */
> +	u32 req_port4567;	/* 0x50: Request Port 4/5/6/7 Register */
> +	u32 bdw_port0123;	/* 0x54: Bandwidth Port 0/1/2/3 Register */
> +	u32 bdw_port4567;	/* 0x58: Bandwidth Port 4/5/6/7 Register */
> +	u32 rd_data_path;	/* 0x5c: Read Datapath Register */
> +	u32 mcfgr;		/* 0x60: Monitor Configuration */
> +	u32 maddr[8];		/* 0x64 ~ 0x80: Monitor Address High/Low port0~7 */
> +	u32 minfo[8];		/* 0x84 ~ 0xa0: Monitor Information port0~7 */

... here it seems the two variants (sama5d3 and sama5d2) are way different

> +	u32 reserved2[16];
> +	u32 wpmr;		/* 0xe4: Write Protection Mode Register */
> +	u32 wpsr;		/* 0xe8: Write Protection Status Register */
> +	u32 reserved3[4];
> +	u32 version;		/* 0xfc: IP version */
>  };
>  
>  
> @@ -38,6 +65,9 @@ int ddr2_init(const unsigned int base,
>  	      const unsigned int ram_address,
>  	      const struct atmel_mpddrc_config *mpddr_value);
>  
> +int ddr3_init(const unsigned int ram_address,
> +	      const struct atmel_mpddrc_config *mpddr_value);
> +
>  /* Bit field in mode register */
>  #define ATMEL_MPDDRC_MR_MODE_NORMAL_CMD		0x0
>  #define ATMEL_MPDDRC_MR_MODE_NOP_CMD		0x1
> @@ -120,9 +150,51 @@ int ddr2_init(const unsigned int base,
>  
>  /* Bit field in Memory Device Register */
>  #define ATMEL_MPDDRC_MD_LPDDR_SDRAM	0x3
> +#define ATMEL_MPDDRC_MD_DDR3_SDRAM	0x4
> +#define ATMEL_MPDDRC_MD_LPDDR3_SDRAM	0x5
>  #define ATMEL_MPDDRC_MD_DDR2_SDRAM	0x6
>  #define ATMEL_MPDDRC_MD_DBW_MASK	(0x1 << 4)
>  #define ATMEL_MPDDRC_MD_DBW_32_BITS	(0x0 << 4)
>  #define ATMEL_MPDDRC_MD_DBW_16_BITS	(0x1 << 4)
>  
> +/* Bit field in I/O Calibration Register */
> +#define ATMEL_MPDDRC_IO_CALIBR_RDIV		0x7
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_34_3	0x1
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_40	0x2
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_48	0x3
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_60	0x4
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_80	0x6
> +#define ATMEL_MPDDRC_IO_CALIBR_LPDDR2_RZQ_120	0x7
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_35	0x2
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_43	0x3
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_52	0x4
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_70	0x6
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR2_RZQ_105	0x7
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_37	0x2
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_44	0x3
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55	0x4
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_73	0x6
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_110	0x7
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_37	0x2
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_44	0x3
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_55	0x4
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_73	0x6
> +#define ATMEL_MPDDRC_IO_CALIBR_DDR3_RZQ_110	0x7
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_TZQIO		0x7f
> +#define ATMEL_MPDDRC_IO_CALIBR_TZQIO_(x)	(((x) & 0x7f) << 8)
> +
> +#define ATMEL_MPDDRC_IO_CALIBR_EN_CALIB		(0x1 << 4)
> +
> +/* Bit field in Read Data Path Register */
> +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_SAMPLING	0x3
> +#define ATMEL_MPDDRC_RD_DATA_PATH_NO_SHIFT		0x0
> +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_ONE_CYCLE	0x1
> +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_TWO_CYCLE	0x2
> +#define ATMEL_MPDDRC_RD_DATA_PATH_SHIFT_THREE_CYCLE	0x3
> +
>  #endif
> diff --git a/arch/arm/mach-at91/mpddrc.c b/arch/arm/mach-at91/mpddrc.c
> index 9ba2a00..ae8b0ff 100644
> --- a/arch/arm/mach-at91/mpddrc.c
> +++ b/arch/arm/mach-at91/mpddrc.c
> @@ -2,6 +2,9 @@
>   * Copyright (C) 2013 Atmel Corporation
>   *		      Bo Shen <voice.shen@atmel.com>
>   *
> + * Copyright (C) 2015 Atmel Corporation
> + *		      Wenyou Yang <wenyou.yang@atmel.com>
> + *
>   * SPDX-License-Identifier:	GPL-2.0+
>   */
>  
> @@ -135,3 +138,87 @@ int ddr2_init(const unsigned int base,
>  
>  	return 0;
>  }
> +
> +int ddr3_init(const unsigned int ram_address,
> +	      const struct atmel_mpddrc_config *mpddr_value)
> +{
> +	struct atmel_mpddr *mpddr = (struct atmel_mpddr *)ATMEL_BASE_MPDDRC;
> +	u32 ba_off;
> +
> +	/* Compute bank offset according to NC in configuration register */
> +	ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
> +	if (ddr2_decodtype_is_seq(mpddr_value->cr))
> +		ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
> +
> +	ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
> +
> +	/* Program the memory device type */
> +	writel(mpddr_value->md, &mpddr->md);
> +
> +	/*
> +	 * Program features of the DDR3-SDRAM device and timing parameters
> +	 */
> +	writel(mpddr_value->cr, &mpddr->cr);
> +
> +	writel(mpddr_value->tpr0, &mpddr->tpr0);
> +	writel(mpddr_value->tpr1, &mpddr->tpr1);
> +	writel(mpddr_value->tpr2, &mpddr->tpr2);
> +
> +	/* A NOP command is issued to the DDR3-SRAM */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
> +
> +	/* A pause of at least 500us must be observed before a single toggle. */
> +	 udelay(500);

whitespace error

> +
> +	/* A NOP command is issued to the DDR3-SDRAM */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
> +
> +	/*
> +	 * An Extended Mode Register Set (EMRS2) cycle is issued to choose
> +	 * between commercial or high temperature operations.
> +	 */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
> +		       ram_address + (0x2 << ba_off));
> +	/*
> +	 * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set
> +	 * the Extended Mode Register to 0.
> +	 */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
> +		       ram_address + (0x3 << ba_off));
> +	/*
> +	 * An Extended Mode Register Set (EMRS1) cycle is issued to disable and
> +	 * to program O.D.S. (Output Driver Strength).
> +	 */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
> +		       ram_address + (0x1 << ba_off));
> +
> +	/*
> +	 * Write a one to the DLL bit (enable DLL reset) in the MPDDRC
> +	 * Configuration Register.
> +	 */
> +
> +	/* A Mode Register Set (MRS) cycle is issued to reset DLL. */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
> +
> +	udelay(50);
> +
> +	/*
> +	 * A Calibration command (MRS) is issued to calibrate RTT and RON
> +	 * values for the Process Voltage Temperature (PVT).
> +	 */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address);
> +
> +	/* A Normal Mode command is provided. */
> +	atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
> +
> +	/* Perform a write access to any DDR3-SDRAM address. */
> +	writel(0, ram_address);
> +
> +	/*
> +	 * Write the refresh rate into the COUNT field in the MPDDRC
> +	 * Refresh Timer Register (MPDDRC_RTR):
> +	 */
> +	writel(mpddr_value->rtr, &mpddr->rtr);
> +
> +	return 0;
> +}
> 

Sequence seems to be good to me

Andreas

  reply	other threads:[~2015-11-27 21:36 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-04  6:32 [U-Boot] [PATCH 0/3] arm: at91/spl: add DDR3-SDRAM initialization support Wenyou Yang
2015-11-04  6:32 ` [U-Boot] [PATCH 1/3] arm: at91/spl: mpddrc: add struct atmel_mpddrc_config Wenyou Yang
2015-11-27 21:22   ` Andreas Bießmann
2015-11-04  6:32 ` [U-Boot] [PATCH 2/3] arm: at91/spl: mpddrc: add mpddrc DDR3-SDRAM initialization Wenyou Yang
2015-11-27 21:36   ` Andreas Bießmann [this message]
2015-12-01  1:37     ` Yang, Wenyou
2015-11-04  6:32 ` [U-Boot] [PATCH 3/3] arm: at91/spl: mpddrc: use IP version to check configuration Wenyou Yang
2015-11-27 21:39   ` Andreas Bießmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5658CCDE.9090903@googlemail.com \
    --to=andreas.devel@googlemail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.