uboot/arch/arm/mach-imx/ddrmc-vf610-calibration.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * ddrmc DDR3 calibration code for NXP's VF610
   4 *
   5 * Copyright (C) 2018 DENX Software Engineering
   6 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
   7 *
   8 */
   9/* #define DEBUG */
  10#include <common.h>
  11#include <log.h>
  12#include <asm/io.h>
  13#include <asm/arch/imx-regs.h>
  14#include <linux/bitmap.h>
  15
  16#include "ddrmc-vf610-calibration.h"
  17
  18/*
  19 * Documents:
  20 *
  21 * [1] "Vybrid: About DDR leveling feature on DDRMC."
  22 * https://community.nxp.com/thread/395323
  23 *
  24 * [2] VFxxx Controller Reference Manual, Rev. 0, 10/2016
  25 *
  26 *
  27 * NOTE
  28 * ====
  29 *
  30 * NXP recommends setting 'fixed' parameters instead of performing the
  31 * training at each boot.
  32 *
  33 * Use those functions to determine those values on new HW, read the
  34 * calculated value from registers and add them to the board specific
  35 * struct ddrmc_cr_setting.
  36 *
  37 * SW leveling supported operations - CR93[SW_LVL_MODE]:
  38 *
  39 * - 0x0 (b'00) - No leveling
  40 *
  41 * - 0x1 (b'01) - WRLVL_DL_X - It is not recommended to perform this tuning
  42 *                             on HW designs utilizing non-flyback topology
  43 *                             (Single DDR3 with x16).
  44 *                             Instead the WRLVL_DL_0/1 fields shall be set
  45 *                             based on trace length differences from their
  46 *                             layout.
  47 *                             Mismatches up to 25% or tCK (clock period) are
  48 *                             allowed, so the value in the filed doesn’t have
  49 *                             to be very accurate.
  50 *
  51 * - 0x2 (b'10) - RDLVL_DL_0/1 - refers to adjusting the DQS strobe in relation
  52 *                             to the DQ signals so that the strobe edge is
  53 *                             centered in the window of valid read data.
  54 *
  55 * - 0x3 (b'11) - RDLVL_GTDL_0/1 - refers to the delay the PHY uses to un-gate
  56 *                             the Read DQS strobe pad from the time that the
  57 *                             PHY enables the pad to input the strobe signal.
  58 *
  59 */
  60static int ddr_cal_get_first_edge_index(unsigned long *bmap, enum edge e,
  61                                        int samples, int start, int max)
  62{
  63        int i, ret = -1;
  64
  65        /*
  66         * We look only for the first value (and filter out
  67         * some wrong data)
  68         */
  69        switch (e) {
  70        case RISING_EDGE:
  71                for (i = start; i <= max - samples; i++) {
  72                        if (test_bit(i, bmap)) {
  73                                if (!test_bit(i - 1, bmap) &&
  74                                    test_bit(i + 1, bmap) &&
  75                                    test_bit(i + 2, bmap) &&
  76                                    test_bit(i + 3, bmap)) {
  77                                        return i;
  78                                }
  79                        }
  80                }
  81                break;
  82        case FALLING_EDGE:
  83                for (i = start; i <= max - samples; i++) {
  84                        if (!test_bit(i, bmap)) {
  85                                if (test_bit(i - 1, bmap) &&
  86                                    test_bit(i - 2, bmap) &&
  87                                    test_bit(i - 3, bmap)) {
  88                                        return i;
  89                                }
  90                        }
  91                }
  92        }
  93
  94        return ret;
  95}
  96
  97static void bitmap_print(unsigned long *bmap, int max)
  98{
  99        int i;
 100
 101        debug("BITMAP [0x%p]:\n", bmap);
 102        for (i = 0; i <= max; i++) {
 103                debug("%d ", test_bit(i, bmap) ? 1 : 0);
 104                if (i && (i % 32) == (32 - 1))
 105                        debug("\n");
 106        }
 107        debug("\n");
 108}
 109
 110#define sw_leveling_op_done \
 111        while (!(readl(&ddrmr->cr[94]) & DDRMC_CR94_SWLVL_OP_DONE))
 112
 113#define sw_leveling_load_value \
 114        do { clrsetbits_le32(&ddrmr->cr[93], DDRMC_CR93_SWLVL_LOAD, \
 115                             DDRMC_CR93_SWLVL_LOAD); } while (0)
 116
 117#define sw_leveling_start \
 118        do { clrsetbits_le32(&ddrmr->cr[93], DDRMC_CR93_SWLVL_START, \
 119                             DDRMC_CR93_SWLVL_START); } while (0)
 120
 121#define sw_leveling_exit \
 122        do { clrsetbits_le32(&ddrmr->cr[94], DDRMC_CR94_SWLVL_EXIT, \
 123                             DDRMC_CR94_SWLVL_EXIT); } while (0)
 124
 125/*
 126 * RDLVL_DL calibration:
 127 *
 128 * NXP is _NOT_ recommending performing the leveling at each
 129 * boot. Instead - one shall run this procedure on new boards
 130 * and then use hardcoded values.
 131 *
 132 */
 133static int ddrmc_cal_dqs_to_dq(struct ddrmr_regs *ddrmr)
 134{
 135        DECLARE_BITMAP(rdlvl_rsp, DDRMC_DQS_DQ_MAX_DELAY + 1);
 136        int rdlvl_dl_0_min = -1, rdlvl_dl_0_max = -1;
 137        int rdlvl_dl_1_min = -1, rdlvl_dl_1_max = -1;
 138        int rdlvl_dl_0, rdlvl_dl_1;
 139        u8 swlvl_rsp;
 140        u32 tmp;
 141        int i;
 142
 143        /* Read defaults */
 144        u16 rdlvl_dl_0_def =
 145                (readl(&ddrmr->cr[105]) >> DDRMC_CR105_RDLVL_DL_0_OFF) & 0xFFFF;
 146        u16 rdlvl_dl_1_def = readl(&ddrmr->cr[110]) & 0xFFFF;
 147
 148        debug("\nRDLVL: ======================\n");
 149        debug("RDLVL: DQS to DQ (RDLVL)\n");
 150
 151        debug("RDLVL: RDLVL_DL_0_DFL:\t 0x%x\n", rdlvl_dl_0_def);
 152        debug("RDLVL: RDLVL_DL_1_DFL:\t 0x%x\n", rdlvl_dl_1_def);
 153
 154        /*
 155         * Set/Read setup for calibration
 156         *
 157         * Values necessary for leveling from Vybrid RM [2] - page 1600
 158         */
 159        writel(0x40703030, &ddrmr->cr[144]);
 160        writel(0x40, &ddrmr->cr[145]);
 161        writel(0x40, &ddrmr->cr[146]);
 162
 163        tmp = readl(&ddrmr->cr[144]);
 164        debug("RDLVL: PHY_RDLVL_RES:\t 0x%x\n", (tmp >> 24) & 0xFF);// set 0x40
 165        debug("RDLVL: PHY_RDLV_LOAD:\t 0x%x\n", (tmp >> 16) & 0xFF);// set 0x70
 166        debug("RDLVL: PHY_RDLV_DLL:\t 0x%x\n", (tmp >> 8) & 0xFF); // set 0x30
 167        debug("RDLVL: PHY_RDLV_EN:\t 0x%x\n", tmp & 0xFF); //set 0x30
 168
 169        tmp = readl(&ddrmr->cr[145]);
 170        debug("RDLVL: PHY_RDLV_RR:\t 0x%x\n", tmp & 0x3FF); //set 0x40
 171
 172        tmp = readl(&ddrmr->cr[146]);
 173        debug("RDLVL: PHY_RDLV_RESP:\t 0x%x\n", tmp); //set 0x40
 174
 175        /*
 176         * Program/read the leveling edge RDLVL_EDGE = 0
 177         *
 178         * 0x00 is the correct output on SWLVL_RSP_X
 179         * If by any chance 1s are visible -> wrong number read
 180         */
 181        clrbits_le32(&ddrmr->cr[101], DDRMC_CR101_PHY_RDLVL_EDGE);
 182
 183        tmp = readl(&ddrmr->cr[101]);
 184        debug("RDLVL: PHY_RDLVL_EDGE:\t 0x%x\n",
 185              (tmp >> DDRMC_CR101_PHY_RDLVL_EDGE_OFF) & 0x1); //set 0
 186
 187        /* Program Leveling mode - CR93[SW_LVL_MODE] to ’b10 */
 188        clrsetbits_le32(&ddrmr->cr[93], DDRMC_CR93_SW_LVL_MODE(0x3),
 189                        DDRMC_CR93_SW_LVL_MODE(0x2));
 190        tmp = readl(&ddrmr->cr[93]);
 191        debug("RDLVL: SW_LVL_MODE:\t 0x%x\n",
 192              (tmp >> DDRMC_CR93_SW_LVL_MODE_OFF) & 0x3);
 193
 194        /* Start procedure - CR93[SWLVL_START] to ’b1 */
 195        sw_leveling_start;
 196
 197        /* Poll CR94[SWLVL_OP_DONE] */
 198        sw_leveling_op_done;
 199
 200        /*
 201         * Program delays for RDLVL_DL_0
 202         *
 203         * The procedure is to increase the delay values from 0 to 0xFF
 204         * and read the response from the DDRMC
 205         */
 206        debug("\nRDLVL: ---> RDLVL_DL_0\n");
 207        bitmap_zero(rdlvl_rsp, DDRMC_DQS_DQ_MAX_DELAY + 1);
 208
 209        for (i = 0; i <= DDRMC_DQS_DQ_MAX_DELAY; i++) {
 210                clrsetbits_le32(&ddrmr->cr[105],
 211                                0xFFFF << DDRMC_CR105_RDLVL_DL_0_OFF,
 212                                i << DDRMC_CR105_RDLVL_DL_0_OFF);
 213
 214                /* Load values CR93[SWLVL_LOAD] to ’b1 */
 215                sw_leveling_load_value;
 216
 217                /* Poll CR94[SWLVL_OP_DONE] */
 218                sw_leveling_op_done;
 219
 220                /*
 221                 * Read Responses - SWLVL_RESP_0
 222                 *
 223                 * The 0x00 (correct response when PHY_RDLVL_EDGE = 0)
 224                 * -> 1 in the bit vector
 225                 */
 226                swlvl_rsp = (readl(&ddrmr->cr[94]) >>
 227                             DDRMC_CR94_SWLVL_RESP_0_OFF) & 0xF;
 228                if (swlvl_rsp == 0)
 229                        generic_set_bit(i, rdlvl_rsp);
 230        }
 231
 232        bitmap_print(rdlvl_rsp, DDRMC_DQS_DQ_MAX_DELAY);
 233
 234        /*
 235         * First test for rising edge 0x0 -> 0x1 in bitmap
 236         */
 237        rdlvl_dl_0_min = ddr_cal_get_first_edge_index(rdlvl_rsp, RISING_EDGE,
 238                                                      N_SAMPLES, N_SAMPLES,
 239                                                      DDRMC_DQS_DQ_MAX_DELAY);
 240
 241        /*
 242         * Secondly test for falling edge 0x1 -> 0x0 in bitmap
 243         */
 244        rdlvl_dl_0_max = ddr_cal_get_first_edge_index(rdlvl_rsp, FALLING_EDGE,
 245                                                      N_SAMPLES, rdlvl_dl_0_min,
 246                                                      DDRMC_DQS_DQ_MAX_DELAY);
 247
 248        debug("RDLVL: DL_0 min: %d [0x%x] DL_0 max: %d [0x%x]\n",
 249              rdlvl_dl_0_min, rdlvl_dl_0_min, rdlvl_dl_0_max, rdlvl_dl_0_max);
 250        rdlvl_dl_0 = (rdlvl_dl_0_max - rdlvl_dl_0_min) / 2;
 251
 252        if (rdlvl_dl_0_max == -1 || rdlvl_dl_0_min == -1 || rdlvl_dl_0 <= 0) {
 253                debug("RDLVL: The DQS to DQ delay cannot be found!\n");
 254                debug("RDLVL: Using default - slice 0: %d!\n", rdlvl_dl_0_def);
 255                rdlvl_dl_0 = rdlvl_dl_0_def;
 256        }
 257
 258        debug("\nRDLVL: ---> RDLVL_DL_1\n");
 259        bitmap_zero(rdlvl_rsp, DDRMC_DQS_DQ_MAX_DELAY + 1);
 260
 261        for (i = 0; i <= DDRMC_DQS_DQ_MAX_DELAY; i++) {
 262                clrsetbits_le32(&ddrmr->cr[110],
 263                                0xFFFF << DDRMC_CR110_RDLVL_DL_1_OFF,
 264                                i << DDRMC_CR110_RDLVL_DL_1_OFF);
 265
 266                /* Load values CR93[SWLVL_LOAD] to ’b1 */
 267                sw_leveling_load_value;
 268
 269                /* Poll CR94[SWLVL_OP_DONE] */
 270                sw_leveling_op_done;
 271
 272                /*
 273                 * Read Responses - SWLVL_RESP_1
 274                 *
 275                 * The 0x00 (correct response when PHY_RDLVL_EDGE = 0)
 276                 * -> 1 in the bit vector
 277                 */
 278                swlvl_rsp = (readl(&ddrmr->cr[95]) >>
 279                             DDRMC_CR95_SWLVL_RESP_1_OFF) & 0xF;
 280                if (swlvl_rsp == 0)
 281                        generic_set_bit(i, rdlvl_rsp);
 282        }
 283
 284        bitmap_print(rdlvl_rsp, DDRMC_DQS_DQ_MAX_DELAY);
 285
 286        /*
 287         * First test for rising edge 0x0 -> 0x1 in bitmap
 288         */
 289        rdlvl_dl_1_min = ddr_cal_get_first_edge_index(rdlvl_rsp, RISING_EDGE,
 290                                                      N_SAMPLES, N_SAMPLES,
 291                                                      DDRMC_DQS_DQ_MAX_DELAY);
 292
 293        /*
 294         * Secondly test for falling edge 0x1 -> 0x0 in bitmap
 295         */
 296        rdlvl_dl_1_max = ddr_cal_get_first_edge_index(rdlvl_rsp, FALLING_EDGE,
 297                                                      N_SAMPLES, rdlvl_dl_1_min,
 298                                                      DDRMC_DQS_DQ_MAX_DELAY);
 299
 300        debug("RDLVL: DL_1 min: %d [0x%x] DL_1 max: %d [0x%x]\n",
 301              rdlvl_dl_1_min, rdlvl_dl_1_min, rdlvl_dl_1_max, rdlvl_dl_1_max);
 302        rdlvl_dl_1 = (rdlvl_dl_1_max - rdlvl_dl_1_min) / 2;
 303
 304        if (rdlvl_dl_1_max == -1 || rdlvl_dl_1_min == -1 || rdlvl_dl_1 <= 0) {
 305                debug("RDLVL: The DQS to DQ delay cannot be found!\n");
 306                debug("RDLVL: Using default - slice 1: %d!\n", rdlvl_dl_1_def);
 307                rdlvl_dl_1 = rdlvl_dl_1_def;
 308        }
 309
 310        debug("RDLVL: CALIBRATED: rdlvl_dl_0: 0x%x\t rdlvl_dl_1: 0x%x\n",
 311              rdlvl_dl_0, rdlvl_dl_1);
 312
 313        /* Write new delay values */
 314        writel(DDRMC_CR105_RDLVL_DL_0(rdlvl_dl_0), &ddrmr->cr[105]);
 315        writel(DDRMC_CR110_RDLVL_DL_1(rdlvl_dl_1), &ddrmr->cr[110]);
 316
 317        sw_leveling_load_value;
 318        sw_leveling_op_done;
 319
 320        /* Exit procedure - CR94[SWLVL_EXIT] to ’b1 */
 321        sw_leveling_exit;
 322
 323        /* Poll CR94[SWLVL_OP_DONE] */
 324        sw_leveling_op_done;
 325
 326        return 0;
 327}
 328
 329/*
 330 * WRLVL_DL calibration:
 331 *
 332 * For non-flyback memory architecture - where one have a single DDR3 x16
 333 * memory - it is NOT necessary to perform "Write Leveling"
 334 * [3] 'Vybrid DDR3 write leveling' https://community.nxp.com/thread/429362
 335 *
 336 */
 337
 338int ddrmc_calibration(struct ddrmr_regs *ddrmr)
 339{
 340        ddrmc_cal_dqs_to_dq(ddrmr);
 341
 342        return 0;
 343}
 344