uboot/arch/arm/mach-at91/mpddrc.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Atmel Corporation
   3 *                    Bo Shen <voice.shen@atmel.com>
   4 *
   5 * Copyright (C) 2015 Atmel Corporation
   6 *                    Wenyou Yang <wenyou.yang@atmel.com>
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <asm/io.h>
  13#include <asm/arch/atmel_mpddrc.h>
  14
  15#define SAMA5D3_MPDDRC_VERSION          0x140
  16
  17static inline void atmel_mpddr_op(const struct atmel_mpddr *mpddr,
  18              int mode,
  19              u32 ram_address)
  20{
  21        writel(mode, &mpddr->mr);
  22        writel(0, ram_address);
  23}
  24
  25static int ddr2_decodtype_is_seq(const unsigned int base, u32 cr)
  26{
  27        struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
  28        u16 version = readl(&mpddr->version) & 0xffff;
  29
  30        if ((version >= SAMA5D3_MPDDRC_VERSION) &&
  31            (cr & ATMEL_MPDDRC_CR_DECOD_INTERLEAVED))
  32                return 0;
  33
  34        return 1;
  35}
  36
  37
  38int ddr2_init(const unsigned int base,
  39              const unsigned int ram_address,
  40              const struct atmel_mpddrc_config *mpddr_value)
  41{
  42        const struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
  43
  44        u32 ba_off, cr;
  45
  46        /* Compute bank offset according to NC in configuration register */
  47        ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
  48        if (ddr2_decodtype_is_seq(base, mpddr_value->cr))
  49                ba_off += ((mpddr_value->cr & ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
  50
  51        ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
  52
  53        /* Program the memory device type into the memory device register */
  54        writel(mpddr_value->md, &mpddr->md);
  55
  56        /* Program the configuration register */
  57        writel(mpddr_value->cr, &mpddr->cr);
  58
  59        /* Program the timing register */
  60        writel(mpddr_value->tpr0, &mpddr->tpr0);
  61        writel(mpddr_value->tpr1, &mpddr->tpr1);
  62        writel(mpddr_value->tpr2, &mpddr->tpr2);
  63
  64        /* Issue a NOP command */
  65        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  66
  67        /* A 200 us is provided to precede any signal toggle */
  68        udelay(200);
  69
  70        /* Issue a NOP command */
  71        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
  72
  73        /* Issue an all banks precharge command */
  74        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
  75
  76        /* Issue an extended mode register set(EMRS2) to choose operation */
  77        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  78                       ram_address + (0x2 << ba_off));
  79
  80        /* Issue an extended mode register set(EMRS3) to set EMSR to 0 */
  81        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  82                       ram_address + (0x3 << ba_off));
  83
  84        /*
  85         * Issue an extended mode register set(EMRS1) to enable DLL and
  86         * program D.I.C (output driver impedance control)
  87         */
  88        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
  89                       ram_address + (0x1 << ba_off));
  90
  91        /* Enable DLL reset */
  92        cr = readl(&mpddr->cr);
  93        writel(cr | ATMEL_MPDDRC_CR_DLL_RESET_ENABLED, &mpddr->cr);
  94
  95        /* A mode register set(MRS) cycle is issued to reset DLL */
  96        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
  97
  98        /* Issue an all banks precharge command */
  99        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_PRCGALL_CMD, ram_address);
 100
 101        /* Two auto-refresh (CBR) cycles are provided */
 102        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
 103        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_RFSH_CMD, ram_address);
 104
 105        /* Disable DLL reset */
 106        cr = readl(&mpddr->cr);
 107        writel(cr & (~ATMEL_MPDDRC_CR_DLL_RESET_ENABLED), &mpddr->cr);
 108
 109        /* A mode register set (MRS) cycle is issued to disable DLL reset */
 110        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
 111
 112        /* Set OCD calibration in default state */
 113        cr = readl(&mpddr->cr);
 114        writel(cr | ATMEL_MPDDRC_CR_OCD_DEFAULT, &mpddr->cr);
 115
 116        /*
 117         * An extended mode register set (EMRS1) cycle is issued
 118         * to OCD default value
 119         */
 120        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
 121                       ram_address + (0x1 << ba_off));
 122
 123         /* OCD calibration mode exit */
 124        cr = readl(&mpddr->cr);
 125        writel(cr & (~ATMEL_MPDDRC_CR_OCD_DEFAULT), &mpddr->cr);
 126
 127        /*
 128         * An extended mode register set (EMRS1) cycle is issued
 129         * to enable OCD exit
 130         */
 131        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
 132                       ram_address + (0x1 << ba_off));
 133
 134        /* A nornal mode command is provided */
 135        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
 136
 137        /* Perform a write access to any DDR2-SDRAM address */
 138        writel(0, ram_address);
 139
 140        /* Write the refresh rate */
 141        writel(mpddr_value->rtr, &mpddr->rtr);
 142
 143        return 0;
 144}
 145
 146int ddr3_init(const unsigned int base,
 147              const unsigned int ram_address,
 148              const struct atmel_mpddrc_config *mpddr_value)
 149{
 150        struct atmel_mpddr *mpddr = (struct atmel_mpddr *)base;
 151        u32 ba_off;
 152
 153        /* Compute bank offset according to NC in configuration register */
 154        ba_off = (mpddr_value->cr & ATMEL_MPDDRC_CR_NC_MASK) + 9;
 155        if (ddr2_decodtype_is_seq(base, mpddr_value->cr))
 156                ba_off += ((mpddr_value->cr &
 157                           ATMEL_MPDDRC_CR_NR_MASK) >> 2) + 11;
 158
 159        ba_off += (mpddr_value->md & ATMEL_MPDDRC_MD_DBW_MASK) ? 1 : 2;
 160
 161        /* Program the memory device type */
 162        writel(mpddr_value->md, &mpddr->md);
 163
 164        /*
 165         * Program features of the DDR3-SDRAM device and timing parameters
 166         */
 167        writel(mpddr_value->cr, &mpddr->cr);
 168
 169        writel(mpddr_value->tpr0, &mpddr->tpr0);
 170        writel(mpddr_value->tpr1, &mpddr->tpr1);
 171        writel(mpddr_value->tpr2, &mpddr->tpr2);
 172
 173        /* A NOP command is issued to the DDR3-SRAM */
 174        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
 175
 176        /* A pause of at least 500us must be observed before a single toggle. */
 177        udelay(500);
 178
 179        /* A NOP command is issued to the DDR3-SDRAM */
 180        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NOP_CMD, ram_address);
 181
 182        /*
 183         * An Extended Mode Register Set (EMRS2) cycle is issued to choose
 184         * between commercial or high temperature operations.
 185         */
 186        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
 187                       ram_address + (0x2 << ba_off));
 188        /*
 189         * Step 7: An Extended Mode Register Set (EMRS3) cycle is issued to set
 190         * the Extended Mode Register to 0.
 191         */
 192        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
 193                       ram_address + (0x3 << ba_off));
 194        /*
 195         * An Extended Mode Register Set (EMRS1) cycle is issued to disable and
 196         * to program O.D.S. (Output Driver Strength).
 197         */
 198        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_EXT_LMR_CMD,
 199                       ram_address + (0x1 << ba_off));
 200
 201        /*
 202         * Write a one to the DLL bit (enable DLL reset) in the MPDDRC
 203         * Configuration Register.
 204         */
 205
 206        /* A Mode Register Set (MRS) cycle is issued to reset DLL. */
 207        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_LMR_CMD, ram_address);
 208
 209        udelay(50);
 210
 211        /*
 212         * A Calibration command (MRS) is issued to calibrate RTT and RON
 213         * values for the Process Voltage Temperature (PVT).
 214         */
 215        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_DEEP_CMD, ram_address);
 216
 217        /* A Normal Mode command is provided. */
 218        atmel_mpddr_op(mpddr, ATMEL_MPDDRC_MR_MODE_NORMAL_CMD, ram_address);
 219
 220        /* Perform a write access to any DDR3-SDRAM address. */
 221        writel(0, ram_address);
 222
 223        /*
 224         * Write the refresh rate into the COUNT field in the MPDDRC
 225         * Refresh Timer Register (MPDDRC_RTR):
 226         */
 227        writel(mpddr_value->rtr, &mpddr->rtr);
 228
 229        return 0;
 230}
 231