uboot/drivers/ddr/marvell/a38x/ddr3_training_ip_engine.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) Marvell International Ltd. and its affiliates
   4 */
   5
   6#include "ddr3_init.h"
   7#include "mv_ddr_regs.h"
   8#include "ddr_training_ip_db.h"
   9
  10#define PATTERN_1       0x55555555
  11#define PATTERN_2       0xaaaaaaaa
  12
  13#define VALIDATE_TRAINING_LIMIT(e1, e2)                 \
  14        ((((e2) - (e1) + 1) > 33) && ((e1) < 67))
  15
  16u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
  17
  18u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
  19                 HWS_SEARCH_DIR_LIMIT];
  20u8 byte_status[MAX_INTERFACE_NUM][MAX_BUS_NUM]; /* holds the bit status in the byte in wrapper function*/
  21
  22u16 mask_results_dq_reg_map[] = {
  23        RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
  24        RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
  25        RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
  26        RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
  27        RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
  28        RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
  29        RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
  30        RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
  31        RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
  32        RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
  33        RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
  34        RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
  35        RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
  36        RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
  37        RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
  38        RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
  39        RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
  40        RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
  41        RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
  42        RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
  43#if MAX_BUS_NUM == 9
  44        RESULT_CONTROL_PUP_5_BIT_0_REG, RESULT_CONTROL_PUP_5_BIT_1_REG,
  45        RESULT_CONTROL_PUP_5_BIT_2_REG, RESULT_CONTROL_PUP_5_BIT_3_REG,
  46        RESULT_CONTROL_PUP_5_BIT_4_REG, RESULT_CONTROL_PUP_5_BIT_5_REG,
  47        RESULT_CONTROL_PUP_5_BIT_6_REG, RESULT_CONTROL_PUP_5_BIT_7_REG,
  48        RESULT_CONTROL_PUP_6_BIT_0_REG, RESULT_CONTROL_PUP_6_BIT_1_REG,
  49        RESULT_CONTROL_PUP_6_BIT_2_REG, RESULT_CONTROL_PUP_6_BIT_3_REG,
  50        RESULT_CONTROL_PUP_6_BIT_4_REG, RESULT_CONTROL_PUP_6_BIT_5_REG,
  51        RESULT_CONTROL_PUP_6_BIT_6_REG, RESULT_CONTROL_PUP_6_BIT_7_REG,
  52        RESULT_CONTROL_PUP_7_BIT_0_REG, RESULT_CONTROL_PUP_7_BIT_1_REG,
  53        RESULT_CONTROL_PUP_7_BIT_2_REG, RESULT_CONTROL_PUP_7_BIT_3_REG,
  54        RESULT_CONTROL_PUP_7_BIT_4_REG, RESULT_CONTROL_PUP_7_BIT_5_REG,
  55        RESULT_CONTROL_PUP_7_BIT_6_REG, RESULT_CONTROL_PUP_7_BIT_7_REG,
  56        RESULT_CONTROL_PUP_8_BIT_0_REG, RESULT_CONTROL_PUP_8_BIT_1_REG,
  57        RESULT_CONTROL_PUP_8_BIT_2_REG, RESULT_CONTROL_PUP_8_BIT_3_REG,
  58        RESULT_CONTROL_PUP_8_BIT_4_REG, RESULT_CONTROL_PUP_8_BIT_5_REG,
  59        RESULT_CONTROL_PUP_8_BIT_6_REG, RESULT_CONTROL_PUP_8_BIT_7_REG,
  60#endif
  61        0xffff
  62};
  63
  64u16 mask_results_pup_reg_map[] = {
  65        RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
  66        RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
  67        RESULT_CONTROL_BYTE_PUP_4_REG,
  68#if MAX_BUS_NUM == 9
  69        RESULT_CONTROL_BYTE_PUP_5_REG, RESULT_CONTROL_BYTE_PUP_6_REG,
  70        RESULT_CONTROL_BYTE_PUP_7_REG, RESULT_CONTROL_BYTE_PUP_8_REG,
  71#endif
  72        0xffff
  73};
  74
  75#if MAX_BUS_NUM == 5
  76u16 mask_results_dq_reg_map_pup3_ecc[] = {
  77        RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
  78        RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
  79        RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
  80        RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
  81        RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
  82        RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
  83        RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
  84        RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
  85        RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
  86        RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
  87        RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
  88        RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
  89        RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
  90        RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
  91        RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
  92        RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
  93        RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
  94        RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
  95        RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
  96        RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG
  97};
  98#endif
  99
 100#if MAX_BUS_NUM == 5
 101u16 mask_results_pup_reg_map_pup3_ecc[] = {
 102        RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
 103        RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
 104        RESULT_CONTROL_BYTE_PUP_4_REG
 105};
 106#endif
 107
 108struct pattern_info pattern_table_64[] = {
 109        /*
 110         * num_of_phases_tx, tx_burst_size;
 111         * delay_between_bursts, num_of_phases_rx,
 112         * start_addr, pattern_len
 113         */
 114        {0x7, 0x7, 2, 0x7, 0x00000, 8},         /* PATTERN_PBS1 */
 115        {0x7, 0x7, 2, 0x7, 0x00080, 8},         /* PATTERN_PBS2 */
 116        {0x7, 0x7, 2, 0x7, 0x00100, 8},         /* PATTERN_PBS3 */
 117        {0x7, 0x7, 2, 0x7, 0x00030, 8},         /* PATTERN_TEST */
 118        {0x7, 0x7, 2, 0x7, 0x00100, 8},         /* PATTERN_RL */
 119        {0x7, 0x7, 2, 0x7, 0x00100, 8},         /* PATTERN_RL2 */
 120        {0x1f, 0xf, 2, 0xf, 0x00680, 32},       /* PATTERN_STATIC_PBS */
 121        {0x1f, 0xf, 2, 0xf, 0x00a80, 32},       /* PATTERN_KILLER_DQ0 */
 122        {0x1f, 0xf, 2, 0xf, 0x01280, 32},       /* PATTERN_KILLER_DQ1 */
 123        {0x1f, 0xf, 2, 0xf, 0x01a80, 32},       /* PATTERN_KILLER_DQ2 */
 124        {0x1f, 0xf, 2, 0xf, 0x02280, 32},       /* PATTERN_KILLER_DQ3 */
 125        {0x1f, 0xf, 2, 0xf, 0x02a80, 32},       /* PATTERN_KILLER_DQ4 */
 126        {0x1f, 0xf, 2, 0xf, 0x03280, 32},       /* PATTERN_KILLER_DQ5 */
 127        {0x1f, 0xf, 2, 0xf, 0x03a80, 32},       /* PATTERN_KILLER_DQ6 */
 128        {0x1f, 0xf, 2, 0xf, 0x04280, 32},       /* PATTERN_KILLER_DQ7 */
 129        {0x1f, 0xf, 2, 0xf, 0x00e80, 32},       /* PATTERN_KILLER_DQ0_64 */
 130        {0x1f, 0xf, 2, 0xf, 0x01680, 32},       /* PATTERN_KILLER_DQ1_64 */
 131        {0x1f, 0xf, 2, 0xf, 0x01e80, 32},       /* PATTERN_KILLER_DQ2_64 */
 132        {0x1f, 0xf, 2, 0xf, 0x02680, 32},       /* PATTERN_KILLER_DQ3_64 */
 133        {0x1f, 0xf, 2, 0xf, 0x02e80, 32},       /* PATTERN_KILLER_DQ4_64 */
 134        {0x1f, 0xf, 2, 0xf, 0x03680, 32},       /* PATTERN_KILLER_DQ5_64 */
 135        {0x1f, 0xf, 2, 0xf, 0x03e80, 32},       /* PATTERN_KILLER_DQ6_64 */
 136        {0x1f, 0xf, 2, 0xf, 0x04680, 32},       /* PATTERN_KILLER_DQ7_64 */
 137        {0x1f, 0xf, 2, 0xf, 0x04a80, 32},       /* PATTERN_KILLER_DQ0_INV */
 138        {0x1f, 0xf, 2, 0xf, 0x05280, 32},       /* PATTERN_KILLER_DQ1_INV */
 139        {0x1f, 0xf, 2, 0xf, 0x05a80, 32},       /* PATTERN_KILLER_DQ2_INV */
 140        {0x1f, 0xf, 2, 0xf, 0x06280, 32},       /* PATTERN_KILLER_DQ3_INV */
 141        {0x1f, 0xf, 2, 0xf, 0x06a80, 32},       /* PATTERN_KILLER_DQ4_INV */
 142        {0x1f, 0xf, 2, 0xf, 0x07280, 32},       /* PATTERN_KILLER_DQ5_INV */
 143        {0x1f, 0xf, 2, 0xf, 0x07a80, 32},       /* PATTERN_KILLER_DQ6_INV */
 144        {0x1f, 0xf, 2, 0xf, 0x08280, 32},       /* PATTERN_KILLER_DQ7_INV */
 145        {0x1f, 0xf, 2, 0xf, 0x04e80, 32},       /* PATTERN_KILLER_DQ0_INV_64 */
 146        {0x1f, 0xf, 2, 0xf, 0x05680, 32},       /* PATTERN_KILLER_DQ1_INV_64 */
 147        {0x1f, 0xf, 2, 0xf, 0x05e80, 32},       /* PATTERN_KILLER_DQ2_INV_64 */
 148        {0x1f, 0xf, 2, 0xf, 0x06680, 32},       /* PATTERN_KILLER_DQ3_INV_64 */
 149        {0x1f, 0xf, 2, 0xf, 0x06e80, 32},       /* PATTERN_KILLER_DQ4_INV_64 */
 150        {0x1f, 0xf, 2, 0xf, 0x07680, 32},       /* PATTERN_KILLER_DQ5_INV_64 */
 151        {0x1f, 0xf, 2, 0xf, 0x07e80, 32},       /* PATTERN_KILLER_DQ6_INV_64 */
 152        {0x1f, 0xf, 2, 0xf, 0x08680, 32},       /* PATTERN_KILLER_DQ7_INV_64 */
 153        {0x1f, 0xf, 2, 0xf, 0x08a80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ0 */
 154        {0x1f, 0xf, 2, 0xf, 0x09280, 32},       /* PATTERN_SSO_FULL_XTALK_DQ1 */
 155        {0x1f, 0xf, 2, 0xf, 0x09a80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ2 */
 156        {0x1f, 0xf, 2, 0xf, 0x0a280, 32},       /* PATTERN_SSO_FULL_XTALK_DQ3 */
 157        {0x1f, 0xf, 2, 0xf, 0x0aa80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ4 */
 158        {0x1f, 0xf, 2, 0xf, 0x0b280, 32},       /* PATTERN_SSO_FULL_XTALK_DQ5 */
 159        {0x1f, 0xf, 2, 0xf, 0x0ba80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ6 */
 160        {0x1f, 0xf, 2, 0xf, 0x0c280, 32},       /* PATTERN_SSO_FULL_XTALK_DQ7 */
 161        {0x1f, 0xf, 2, 0xf, 0x08e80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ0_64 */
 162        {0x1f, 0xf, 2, 0xf, 0x09680, 32},       /* PATTERN_SSO_FULL_XTALK_DQ1_64 */
 163        {0x1f, 0xf, 2, 0xf, 0x09e80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ2_64 */
 164        {0x1f, 0xf, 2, 0xf, 0x0a680, 32},       /* PATTERN_SSO_FULL_XTALK_DQ3_64 */
 165        {0x1f, 0xf, 2, 0xf, 0x0ae80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ4_64 */
 166        {0x1f, 0xf, 2, 0xf, 0x0b680, 32},       /* PATTERN_SSO_FULL_XTALK_DQ5_64 */
 167        {0x1f, 0xf, 2, 0xf, 0x0be80, 32},       /* PATTERN_SSO_FULL_XTALK_DQ6_64 */
 168        {0x1f, 0xf, 2, 0xf, 0x0c680, 32},       /* PATTERN_SSO_FULL_XTALK_DQ7_64 */
 169        {0x1f, 0xf, 2, 0xf, 0x0ca80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ0 */
 170        {0x1f, 0xf, 2, 0xf, 0x0d280, 32},       /* PATTERN_SSO_XTALK_FREE_DQ1 */
 171        {0x1f, 0xf, 2, 0xf, 0x0da80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ2 */
 172        {0x1f, 0xf, 2, 0xf, 0x0e280, 32},       /* PATTERN_SSO_XTALK_FREE_DQ3 */
 173        {0x1f, 0xf, 2, 0xf, 0x0ea80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ4 */
 174        {0x1f, 0xf, 2, 0xf, 0x0f280, 32},       /* PATTERN_SSO_XTALK_FREE_DQ5 */
 175        {0x1f, 0xf, 2, 0xf, 0x0fa80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ6 */
 176        {0x1f, 0xf, 2, 0xf, 0x10280, 32},       /* PATTERN_SSO_XTALK_FREE_DQ7 */
 177        {0x1f, 0xf, 2, 0xf, 0x0ce80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ0_64 */
 178        {0x1f, 0xf, 2, 0xf, 0x0d680, 32},       /* PATTERN_SSO_XTALK_FREE_DQ1_64 */
 179        {0x1f, 0xf, 2, 0xf, 0x0de80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ2_64 */
 180        {0x1f, 0xf, 2, 0xf, 0x0e680, 32},       /* PATTERN_SSO_XTALK_FREE_DQ3_64 */
 181        {0x1f, 0xf, 2, 0xf, 0x0ee80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ4_64 */
 182        {0x1f, 0xf, 2, 0xf, 0x0f680, 32},       /* PATTERN_SSO_XTALK_FREE_DQ5_64 */
 183        {0x1f, 0xf, 2, 0xf, 0x0fe80, 32},       /* PATTERN_SSO_XTALK_FREE_DQ6_64 */
 184        {0x1f, 0xf, 2, 0xf, 0x10680, 32},       /* PATTERN_SSO_XTALK_FREE_DQ7_64 */
 185        {0x1f, 0xf, 2, 0xf, 0x10a80, 32},       /* PATTERN_ISI_XTALK_FREE */
 186        {0x1f, 0xf, 2, 0xf, 0x10e80, 32},       /* PATTERN_ISI_XTALK_FREE_64 */
 187        {0x1f, 0xf, 2, 0xf, 0x11280, 32},       /* PATTERN_VREF */
 188        {0x1f, 0xf, 2, 0xf, 0x11680, 32},       /* PATTERN_VREF_64 */
 189        {0x1f, 0xf, 2, 0xf, 0x11a80, 32},       /* PATTERN_VREF_INV */
 190        {0x1f, 0xf, 2, 0xf, 0x11e80, 32},       /* PATTERN_FULL_SSO_0T */
 191        {0x1f, 0xf, 2, 0xf, 0x12280, 32},       /* PATTERN_FULL_SSO_1T */
 192        {0x1f, 0xf, 2, 0xf, 0x12680, 32},       /* PATTERN_FULL_SSO_2T */
 193        {0x1f, 0xf, 2, 0xf, 0x12a80, 32},       /* PATTERN_FULL_SSO_3T */
 194        {0x1f, 0xf, 2, 0xf, 0x12e80, 32},       /* PATTERN_RESONANCE_1T */
 195        {0x1f, 0xf, 2, 0xf, 0x13280, 32},       /* PATTERN_RESONANCE_2T */
 196        {0x1f, 0xf, 2, 0xf, 0x13680, 32},       /* PATTERN_RESONANCE_3T */
 197        {0x1f, 0xf, 2, 0xf, 0x13a80, 32},       /* PATTERN_RESONANCE_4T */
 198        {0x1f, 0xf, 2, 0xf, 0x13e80, 32},       /* PATTERN_RESONANCE_5T */
 199        {0x1f, 0xf, 2, 0xf, 0x14280, 32},       /* PATTERN_RESONANCE_6T */
 200        {0x1f, 0xf, 2, 0xf, 0x14680, 32},       /* PATTERN_RESONANCE_7T */
 201        {0x1f, 0xf, 2, 0xf, 0x14a80, 32},       /* PATTERN_RESONANCE_8T */
 202        {0x1f, 0xf, 2, 0xf, 0x14e80, 32},       /* PATTERN_RESONANCE_9T */
 203        {0x1f, 0xf, 2, 0xf, 0x15280, 32},       /* PATTERN_ZERO */
 204        {0x1f, 0xf, 2, 0xf, 0x15680, 32}        /* PATTERN_ONE */
 205        /* Note: actual start_address is "<< 3" of defined address */
 206};
 207
 208#if defined(CONFIG_DDR4)
 209struct pattern_info pattern_table_16[] = {
 210        /*
 211         * num tx phases, tx burst, delay between, rx pattern,
 212         * start_address, pattern_len
 213         */
 214        {0x1, 0x1, 2, 0x1, 0x0000, 2},  /* PATTERN_PBS1*/
 215        {0x1, 0x1, 2, 0x1, 0x0080, 2},  /* PATTERN_PBS2*/
 216        {0x1, 0x1, 2, 0x1, 0x0100, 2},  /* PATTERN_PBS3*/
 217        {0x1, 0x1, 2, 0x1, 0x0180, 2},  /* PATTERN_TEST*/
 218        {0x1, 0x1, 2, 0x1, 0x0200, 2},  /* PATTERN_RL*/
 219        {0x1, 0x1, 2, 0x1, 0x0280, 2},  /* PATTERN_RL2*/
 220        {0xf, 0x7, 2, 0x7, 0x0680, 16}, /* PATTERN_STATIC_PBS*/
 221        {0xf, 0x7, 2, 0x7, 0x0A80, 16}, /* PATTERN_KILLER_DQ0*/
 222        {0xf, 0x7, 2, 0x7, 0x0E80, 16}, /* PATTERN_KILLER_DQ1*/
 223        {0xf, 0x7, 2, 0x7, 0x1280, 16}, /* PATTERN_KILLER_DQ2*/
 224        {0xf, 0x7, 2, 0x7, 0x1680, 16}, /* PATTERN_KILLER_DQ3*/
 225        {0xf, 0x7, 2, 0x7, 0x1A80, 16}, /* PATTERN_KILLER_DQ4*/
 226        {0xf, 0x7, 2, 0x7, 0x1E80, 16}, /* PATTERN_KILLER_DQ5*/
 227        {0xf, 0x7, 2, 0x7, 0x2280, 16}, /* PATTERN_KILLER_DQ6*/
 228        {0xf, 0x7, 2, 0x7, 0x2680, 16}, /* PATTERN_KILLER_DQ7*/
 229        {0xf, 0x7, 2, 0x7, 0x2A80, 16}, /* PATTERN_KILLER_DQ0_INV*/
 230        {0xf, 0x7, 2, 0x7, 0x2E80, 16}, /* PATTERN_KILLER_DQ1_INV*/
 231        {0xf, 0x7, 2, 0x7, 0x3280, 16}, /* PATTERN_KILLER_DQ2_INV*/
 232        {0xf, 0x7, 2, 0x7, 0x3680, 16}, /* PATTERN_KILLER_DQ3_INV*/
 233        {0xf, 0x7, 2, 0x7, 0x3A80, 16}, /* PATTERN_KILLER_DQ4_INV*/
 234        {0xf, 0x7, 2, 0x7, 0x3E80, 16}, /* PATTERN_KILLER_DQ5_INV*/
 235        {0xf, 0x7, 2, 0x7, 0x4280, 16}, /* PATTERN_KILLER_DQ6_INV*/
 236        {0xf, 0x7, 2, 0x7, 0x4680, 16}, /* PATTERN_KILLER_DQ7_INV*/
 237        {0xf, 0x7, 2, 0x7, 0x4A80, 16}, /* PATTERN_VREF*/
 238        {0xf, 0x7, 2, 0x7, 0x4E80, 16}, /* PATTERN_VREF_INV*/
 239        {0xf, 0x7, 2, 0x7, 0x5280, 16}, /* PATTERN_FULL_SSO_0T*/
 240        {0xf, 0x7, 2, 0x7, 0x5680, 16}, /* PATTERN_FULL_SSO_1T*/
 241        {0xf, 0x7, 2, 0x7, 0x5A80, 16}, /* PATTERN_FULL_SSO_2T*/
 242        {0xf, 0x7, 2, 0x7, 0x5E80, 16}, /* PATTERN_FULL_SSO_3T*/
 243        {0xf, 0x7, 2, 0x7, 0x6280, 16}, /* PATTERN_ZERO */
 244        {0xf, 0x7, 2, 0x7, 0x6680, 16}, /* PATTERN_ONE */
 245        {0xf, 0x7, 2, 0x7, 0x6A80, 16}, /* PATTERN_SSO_FULL_XTALK_DQ0*/
 246        {0xf, 0x7, 2, 0x7, 0x6E80, 16}, /* PATTERN_SSO_FULL_XTALK_DQ1*/
 247        {0xf, 0x7, 2, 0x7, 0x7280, 16}, /* PATTERN_SSO_FULL_XTALK_DQ2*/
 248        {0xf, 0x7, 2, 0x7, 0x7680, 16}, /* PATTERN_SSO_FULL_XTALK_DQ3*/
 249        {0xf, 0x7, 2, 0x7, 0x7A80, 16}, /* PATTERN_SSO_FULL_XTALK_DQ4*/
 250        {0xf, 0x7, 2, 0x7, 0x7E80, 16}, /* PATTERN_SSO_FULL_XTALK_DQ5*/
 251        {0xf, 0x7, 2, 0x7, 0x8280, 16}, /* PATTERN_SSO_FULL_XTALK_DQ6*/
 252        {0xf, 0x7, 2, 0x7, 0x8680, 16}, /* PATTERN_SSO_FULL_XTALK_DQ7*/
 253        {0xf, 0x7, 2, 0x7, 0x8A80, 16}, /* PATTERN_SSO_XTALK_FREE_DQ0*/
 254        {0xf, 0x7, 2, 0x7, 0x8E80, 16}, /* PATTERN_SSO_XTALK_FREE_DQ1*/
 255        {0xf, 0x7, 2, 0x7, 0x9280, 16}, /* PATTERN_SSO_XTALK_FREE_DQ2*/
 256        {0xf, 0x7, 2, 0x7, 0x9680, 16}, /* PATTERN_SSO_XTALK_FREE_DQ3*/
 257        {0xf, 0x7, 2, 0x7, 0x9A80, 16}, /* PATTERN_SSO_XTALK_FREE_DQ4*/
 258        {0xf, 0x7, 2, 0x7, 0x9E80, 16}, /* PATTERN_SSO_XTALK_FREE_DQ5*/
 259        {0xf, 0x7, 2, 0x7, 0xA280, 16}, /* PATTERN_SSO_XTALK_FREE_DQ6*/
 260        {0xf, 0x7, 2, 0x7, 0xA680, 16}, /* PATTERN_SSO_XTALK_FREE_DQ7*/
 261        {0xf, 0x7, 2, 0x7, 0xAA80, 16}, /* PATTERN_ISI_XTALK_FREE*/
 262        {0xf, 0x7, 2, 0x7, 0xAE80, 16}, /* PATTERN_RESONANCE_1T*/
 263        {0xf, 0x7, 2, 0x7, 0xB280, 16}, /* PATTERN_RESONANCE_2T*/
 264        {0xf, 0x7, 2, 0x7, 0xB680, 16}, /* PATTERN_RESONANCE_3T*/
 265        {0xf, 0x7, 2, 0x7, 0xBA80, 16}, /* PATTERN_RESONANCE_4T*/
 266        {0xf, 0x7, 2, 0x7, 0xBE80, 16}, /* PATTERN_RESONANCE_5T*/
 267        {0xf, 0x7, 2, 0x7, 0xC280, 16}, /* PATTERN_RESONANCE_6T*/
 268        {0xf, 0x7, 2, 0x7, 0xC680, 16}, /* PATTERN_RESONANCE_7T*/
 269        {0xf, 0x7, 2, 0x7, 0xca80, 16}, /* PATTERN_RESONANCE_8T*/
 270        {0xf, 0x7, 2, 0x7, 0xce80, 16}  /* PATTERN_RESONANCE_9T*/
 271        /* Note: actual start_address is "<< 3" of defined address */
 272};
 273
 274struct pattern_info pattern_table_32[] = {
 275        /*
 276         * num tx phases, tx burst, delay between, rx pattern,
 277         * start_address, pattern_len
 278         */
 279        {0x3, 0x3, 2, 0x3, 0x0000, 4},          /* PATTERN_PBS1*/
 280        {0x3, 0x3, 2, 0x3, 0x0020, 4},          /* PATTERN_PBS2*/
 281        {0x3, 0x3, 2, 0x3, 0x0040, 4},          /* PATTERN_PBS3*/
 282        {0x3, 0x3, 2, 0x3, 0x0060, 4},          /* PATTERN_TEST*/
 283        {0x3, 0x3, 2, 0x3, 0x0080, 4},          /* PATTERN_RL*/
 284        {0x3, 0x3, 2, 0x3, 0x00a0, 4},          /* PATTERN_RL2*/
 285        {0x1f, 0xf, 2, 0xf, 0x00c0, 32},        /* PATTERN_STATIC_PBS*/
 286        {0x1f, 0xf, 2, 0xf, 0x00e0, 32},        /* PATTERN_KILLER_DQ0*/
 287        {0x1f, 0xf, 2, 0xf, 0x0100, 32},        /* PATTERN_KILLER_DQ1*/
 288        {0x1f, 0xf, 2, 0xf, 0x0120, 32},        /* PATTERN_KILLER_DQ2*/
 289        {0x1f, 0xf, 2, 0xf, 0x0140, 32},        /* PATTERN_KILLER_DQ3*/
 290        {0x1f, 0xf, 2, 0xf, 0x0160, 32},        /* PATTERN_KILLER_DQ4*/
 291        {0x1f, 0xf, 2, 0xf, 0x0180, 32},        /* PATTERN_KILLER_DQ5*/
 292        {0x1f, 0xf, 2, 0xf, 0x01a0, 32},        /* PATTERN_KILLER_DQ6*/
 293        {0x1f, 0xf, 2, 0xf, 0x01c0, 32},        /* PATTERN_KILLER_DQ7*/
 294        {0x1f, 0xf, 2, 0xf, 0x01e0, 32},        /* PATTERN_KILLER_DQ0_INV*/
 295        {0x1f, 0xf, 2, 0xf, 0x0200, 32},        /* PATTERN_KILLER_DQ1_INV*/
 296        {0x1f, 0xf, 2, 0xf, 0x0220, 32},        /* PATTERN_KILLER_DQ2_INV*/
 297        {0x1f, 0xf, 2, 0xf, 0x0240, 32},        /* PATTERN_KILLER_DQ3_INV*/
 298        {0x1f, 0xf, 2, 0xf, 0x0260, 32},        /* PATTERN_KILLER_DQ4_INV*/
 299        {0x1f, 0xf, 2, 0xf, 0x0280, 32},        /* PATTERN_KILLER_DQ5_INV*/
 300        {0x1f, 0xf, 2, 0xf, 0x02a0, 32},        /* PATTERN_KILLER_DQ6_INV*/
 301        {0x1f, 0xf, 2, 0xf, 0x02c0, 32},        /* PATTERN_KILLER_DQ7_INV*/
 302        {0x1f, 0xf, 2, 0xf, 0x02e0, 32},        /* PATTERN_VREF*/
 303        {0x1f, 0xf, 2, 0xf, 0x0300, 32},        /* PATTERN_VREF_INV*/
 304        {0x1f, 0xf, 2, 0xf, 0x0320, 32},        /* PATTERN_FULL_SSO_0T*/
 305        {0x1f, 0xf, 2, 0xf, 0x0340, 32},        /* PATTERN_FULL_SSO_1T*/
 306        {0x1f, 0xf, 2, 0xf, 0x0360, 32},        /* PATTERN_FULL_SSO_2T*/
 307        {0x1f, 0xf, 2, 0xf, 0x0380, 32},        /* PATTERN_FULL_SSO_3T*/
 308        {0x1f, 0xf, 2, 0xf, 0x6280, 32},        /* PATTERN_ZERO */
 309        {0x1f, 0xf, 2, 0xf, 0x6680, 32},        /* PATTERN_ONE */
 310        {0x1f, 0xf, 2, 0xf, 0x6A80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ0*/
 311        {0x1f, 0xf, 2, 0xf, 0x6E80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ1*/
 312        {0x1f, 0xf, 2, 0xf, 0x7280, 32},        /* PATTERN_SSO_FULL_XTALK_DQ2*/
 313        {0x1f, 0xf, 2, 0xf, 0x7680, 32},        /* PATTERN_SSO_FULL_XTALK_DQ3*/
 314        {0x1f, 0xf, 2, 0xf, 0x7A80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ4*/
 315        {0x1f, 0xf, 2, 0xf, 0x7E80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ5*/
 316        {0x1f, 0xf, 2, 0xf, 0x8280, 32},        /* PATTERN_SSO_FULL_XTALK_DQ6*/
 317        {0x1f, 0xf, 2, 0xf, 0x8680, 32},        /* PATTERN_SSO_FULL_XTALK_DQ7*/
 318        {0x1f, 0xf, 2, 0xf, 0x8A80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ0*/
 319        {0x1f, 0xf, 2, 0xf, 0x8E80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ1*/
 320        {0x1f, 0xf, 2, 0xf, 0x9280, 32},        /* PATTERN_SSO_XTALK_FREE_DQ2*/
 321        {0x1f, 0xf, 2, 0xf, 0x9680, 32},        /* PATTERN_SSO_XTALK_FREE_DQ3*/
 322        {0x1f, 0xf, 2, 0xf, 0x9A80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ4*/
 323        {0x1f, 0xf, 2, 0xf, 0x9E80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ5*/
 324        {0x1f, 0xf, 2, 0xf, 0xA280, 32},        /* PATTERN_SSO_XTALK_FREE_DQ6*/
 325        {0x1f, 0xf, 2, 0xf, 0xA680, 32},        /* PATTERN_SSO_XTALK_FREE_DQ7*/
 326        {0x1f, 0xf, 2, 0xf, 0xAA80, 32},        /* PATTERN_ISI_XTALK_FREE*/
 327        {0x1f, 0xf, 2, 0xf, 0xAE80, 32},        /* PATTERN_RESONANCE_1T*/
 328        {0x1f, 0xf, 2, 0xf, 0xB280, 32},        /* PATTERN_RESONANCE_2T*/
 329        {0x1f, 0xf, 2, 0xf, 0xB680, 32},        /* PATTERN_RESONANCE_3T*/
 330        {0x1f, 0xf, 2, 0xf, 0xBA80, 32},        /* PATTERN_RESONANCE_4T*/
 331        {0x1f, 0xf, 2, 0xf, 0xBE80, 32},        /* PATTERN_RESONANCE_5T*/
 332        {0x1f, 0xf, 2, 0xf, 0xC280, 32},        /* PATTERN_RESONANCE_6T*/
 333        {0x1f, 0xf, 2, 0xf, 0xC680, 32},        /* PATTERN_RESONANCE_7T*/
 334        {0x1f, 0xf, 2, 0xf, 0xca80, 32},        /* PATTERN_RESONANCE_8T*/
 335        {0x1f, 0xf, 2, 0xf, 0xce80, 32}         /* PATTERN_RESONANCE_9T*/
 336        /* Note: actual start_address is "<< 3" of defined address */
 337};
 338#else /* CONFIG_DDR4 */
 339struct pattern_info pattern_table_16[] = {
 340        /*
 341         * num tx phases, tx burst, delay between, rx pattern,
 342         * start_address, pattern_len
 343         */
 344        {1, 1, 2, 1, 0x0080, 2},        /* PATTERN_PBS1 */
 345        {1, 1, 2, 1, 0x00c0, 2},        /* PATTERN_PBS2 */
 346        {1, 1, 2, 1, 0x0380, 2},        /* PATTERN_PBS3 */
 347        {1, 1, 2, 1, 0x0040, 2},        /* PATTERN_TEST */
 348        {1, 1, 2, 1, 0x0100, 2},        /* PATTERN_RL */
 349        {1, 1, 2, 1, 0x0000, 2},        /* PATTERN_RL2 */
 350        {0xf, 0x7, 2, 0x7, 0x0140, 16}, /* PATTERN_STATIC_PBS */
 351        {0xf, 0x7, 2, 0x7, 0x0190, 16}, /* PATTERN_KILLER_DQ0 */
 352        {0xf, 0x7, 2, 0x7, 0x01d0, 16}, /* PATTERN_KILLER_DQ1 */
 353        {0xf, 0x7, 2, 0x7, 0x0210, 16}, /* PATTERN_KILLER_DQ2 */
 354        {0xf, 0x7, 2, 0x7, 0x0250, 16}, /* PATTERN_KILLER_DQ3 */
 355        {0xf, 0x7, 2, 0x7, 0x0290, 16}, /* PATTERN_KILLER_DQ4 */
 356        {0xf, 0x7, 2, 0x7, 0x02d0, 16}, /* PATTERN_KILLER_DQ5 */
 357        {0xf, 0x7, 2, 0x7, 0x0310, 16}, /* PATTERN_KILLER_DQ6 */
 358        {0xf, 0x7, 2, 0x7, 0x0350, 16}, /* PATTERN_KILLER_DQ7 */
 359        {0xf, 0x7, 2, 0x7, 0x04c0, 16}, /* PATTERN_VREF */
 360        {0xf, 0x7, 2, 0x7, 0x03c0, 16}, /* PATTERN_FULL_SSO_1T */
 361        {0xf, 0x7, 2, 0x7, 0x0400, 16}, /* PATTERN_FULL_SSO_2T */
 362        {0xf, 0x7, 2, 0x7, 0x0440, 16}, /* PATTERN_FULL_SSO_3T */
 363        {0xf, 0x7, 2, 0x7, 0x0480, 16}, /* PATTERN_FULL_SSO_4T */
 364        {0xf, 7, 2, 7, 0x6280, 16},     /* PATTERN_SSO_FULL_XTALK_DQ1 */
 365        {0xf, 7, 2, 7, 0x6680, 16},     /* PATTERN_SSO_FULL_XTALK_DQ1 */
 366        {0xf, 7, 2, 7, 0x6A80, 16},     /* PATTERN_SSO_FULL_XTALK_DQ2 */
 367        {0xf, 7, 2, 7, 0x6E80, 16},     /* PATTERN_SSO_FULL_XTALK_DQ3 */
 368        {0xf, 7, 2, 7, 0x7280, 16},     /* PATTERN_SSO_FULL_XTALK_DQ4 */
 369        {0xf, 7, 2, 7, 0x7680, 16},     /* PATTERN_SSO_FULL_XTALK_DQ5 */
 370        {0xf, 7, 2, 7, 0x7A80, 16},     /* PATTERN_SSO_FULL_XTALK_DQ6 */
 371        {0xf, 7, 2, 7, 0x7E80, 16},     /* PATTERN_SSO_FULL_XTALK_DQ7 */
 372        {0xf, 7, 2, 7, 0x8280, 16},     /* PATTERN_SSO_XTALK_FREE_DQ0 */
 373        {0xf, 7, 2, 7, 0x8680, 16},     /* PATTERN_SSO_XTALK_FREE_DQ1 */
 374        {0xf, 7, 2, 7, 0x8A80, 16},     /* PATTERN_SSO_XTALK_FREE_DQ2 */
 375        {0xf, 7, 2, 7, 0x8E80, 16},     /* PATTERN_SSO_XTALK_FREE_DQ3 */
 376        {0xf, 7, 2, 7, 0x9280, 16},     /* PATTERN_SSO_XTALK_FREE_DQ4 */
 377        {0xf, 7, 2, 7, 0x9680, 16},     /* PATTERN_SSO_XTALK_FREE_DQ5 */
 378        {0xf, 7, 2, 7, 0x9A80, 16},     /* PATTERN_SSO_XTALK_FREE_DQ6 */
 379        {0xf, 7, 2, 7, 0x9E80, 16},     /* PATTERN_SSO_XTALK_FREE_DQ7 */
 380        {0xf, 7, 2, 7, 0xA280, 16}      /* PATTERN_ISI_XTALK_FREE */
 381        /* Note: actual start_address is "<< 3" of defined address */
 382};
 383
 384struct pattern_info pattern_table_32[] = {
 385        /*
 386         * num tx phases, tx burst, delay between, rx pattern,
 387         * start_address, pattern_len
 388         */
 389        {3, 3, 2, 3, 0x0080, 4},        /* PATTERN_PBS1 */
 390        {3, 3, 2, 3, 0x00c0, 4},        /* PATTERN_PBS2 */
 391        {3, 3, 2, 3, 0x0380, 4},        /* PATTERN_PBS3 */
 392        {3, 3, 2, 3, 0x0040, 4},        /* PATTERN_TEST */
 393        {3, 3, 2, 3, 0x0100, 4},        /* PATTERN_RL */
 394        {3, 3, 2, 3, 0x0000, 4},        /* PATTERN_RL2 */
 395        {0x1f, 0xf, 2, 0xf, 0x0140, 32},        /* PATTERN_STATIC_PBS */
 396        {0x1f, 0xf, 2, 0xf, 0x0190, 32},        /* PATTERN_KILLER_DQ0 */
 397        {0x1f, 0xf, 2, 0xf, 0x01d0, 32},        /* PATTERN_KILLER_DQ1 */
 398        {0x1f, 0xf, 2, 0xf, 0x0210, 32},        /* PATTERN_KILLER_DQ2 */
 399        {0x1f, 0xf, 2, 0xf, 0x0250, 32},        /* PATTERN_KILLER_DQ3 */
 400        {0x1f, 0xf, 2, 0xf, 0x0290, 32},        /* PATTERN_KILLER_DQ4 */
 401        {0x1f, 0xf, 2, 0xf, 0x02d0, 32},        /* PATTERN_KILLER_DQ5 */
 402        {0x1f, 0xf, 2, 0xf, 0x0310, 32},        /* PATTERN_KILLER_DQ6 */
 403        {0x1f, 0xf, 2, 0xf, 0x0350, 32},        /* PATTERN_KILLER_DQ7 */
 404        {0x1f, 0xf, 2, 0xf, 0x04c0, 32},        /* PATTERN_VREF */
 405        {0x1f, 0xf, 2, 0xf, 0x03c0, 32},        /* PATTERN_FULL_SSO_1T */
 406        {0x1f, 0xf, 2, 0xf, 0x0400, 32},        /* PATTERN_FULL_SSO_2T */
 407        {0x1f, 0xf, 2, 0xf, 0x0440, 32},        /* PATTERN_FULL_SSO_3T */
 408        {0x1f, 0xf, 2, 0xf, 0x0480, 32},        /* PATTERN_FULL_SSO_4T */
 409        {0x1f, 0xF, 2, 0xf, 0x6280, 32},        /* PATTERN_SSO_FULL_XTALK_DQ0 */
 410        {0x1f, 0xF, 2, 0xf, 0x6680, 32},        /* PATTERN_SSO_FULL_XTALK_DQ1 */
 411        {0x1f, 0xF, 2, 0xf, 0x6A80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ2 */
 412        {0x1f, 0xF, 2, 0xf, 0x6E80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ3 */
 413        {0x1f, 0xF, 2, 0xf, 0x7280, 32},        /* PATTERN_SSO_FULL_XTALK_DQ4 */
 414        {0x1f, 0xF, 2, 0xf, 0x7680, 32},        /* PATTERN_SSO_FULL_XTALK_DQ5 */
 415        {0x1f, 0xF, 2, 0xf, 0x7A80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ6 */
 416        {0x1f, 0xF, 2, 0xf, 0x7E80, 32},        /* PATTERN_SSO_FULL_XTALK_DQ7 */
 417        {0x1f, 0xF, 2, 0xf, 0x8280, 32},        /* PATTERN_SSO_XTALK_FREE_DQ0 */
 418        {0x1f, 0xF, 2, 0xf, 0x8680, 32},        /* PATTERN_SSO_XTALK_FREE_DQ1 */
 419        {0x1f, 0xF, 2, 0xf, 0x8A80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ2 */
 420        {0x1f, 0xF, 2, 0xf, 0x8E80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ3 */
 421        {0x1f, 0xF, 2, 0xf, 0x9280, 32},        /* PATTERN_SSO_XTALK_FREE_DQ4 */
 422        {0x1f, 0xF, 2, 0xf, 0x9680, 32},        /* PATTERN_SSO_XTALK_FREE_DQ5 */
 423        {0x1f, 0xF, 2, 0xf, 0x9A80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ6 */
 424        {0x1f, 0xF, 2, 0xf, 0x9E80, 32},        /* PATTERN_SSO_XTALK_FREE_DQ7 */
 425        {0x1f, 0xF, 2, 0xf, 0xA280, 32}         /* PATTERN_ISI_XTALK_FREE */
 426        /* Note: actual start_address is "<< 3" of defined address */
 427};
 428#endif /* CONFIG_DDR4 */
 429
 430u32 train_dev_num;
 431enum hws_ddr_cs traintrain_cs_type;
 432u32 train_pup_num;
 433enum hws_training_result train_result_type;
 434enum hws_control_element train_control_element;
 435enum hws_search_dir traine_search_dir;
 436enum hws_dir train_direction;
 437u32 train_if_select;
 438u32 train_init_value;
 439u32 train_number_iterations;
 440enum hws_pattern train_pattern;
 441enum hws_edge_compare train_edge_compare;
 442u32 train_cs_num;
 443u32 train_if_acess, train_if_id, train_pup_access;
 444#if defined(CONFIG_DDR4)
 445/* The counter was increased for DDR4 because of A390 DB-GP DDR4 failure */
 446u32 max_polling_for_done = 100000000;
 447#else /* CONFIG_DDR4 */
 448u32 max_polling_for_done = 1000000;
 449#endif /* CONFIG_DDR4 */
 450
 451u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
 452                          enum hws_training_result result_type,
 453                          u32 interface_num)
 454{
 455        u32 *buf_ptr = NULL;
 456
 457        buf_ptr = &training_res
 458                [MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS * search +
 459                 interface_num * MAX_BUS_NUM * BUS_WIDTH_IN_BITS];
 460
 461        return buf_ptr;
 462}
 463
 464enum {
 465        PASS,
 466        FAIL
 467};
 468/*
 469 * IP Training search
 470 * Note: for one edge search only from fail to pass, else jitter can
 471 * be be entered into solution.
 472 */
 473int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
 474                         u32 interface_num,
 475                         enum hws_access_type pup_access_type,
 476                         u32 pup_num, enum hws_training_result result_type,
 477                         enum hws_control_element control_element,
 478                         enum hws_search_dir search_dir, enum hws_dir direction,
 479                         u32 interface_mask, u32 init_value, u32 num_iter,
 480                         enum hws_pattern pattern,
 481                         enum hws_edge_compare edge_comp,
 482                         enum hws_ddr_cs cs_type, u32 cs_num,
 483                         enum hws_training_ip_stat *train_status)
 484{
 485        u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt,
 486                reg_data, pup_id;
 487        u32 tx_burst_size;
 488        u32 delay_between_burst;
 489        u32 rd_mode;
 490        u32 data;
 491        struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 492        u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 493        u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
 494        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 495        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 496
 497        if (pup_num >= octets_per_if_num) {
 498                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 499                                         ("pup_num %d not valid\n", pup_num));
 500        }
 501        if (interface_num >= MAX_INTERFACE_NUM) {
 502                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 503                                         ("if_id %d not valid\n",
 504                                          interface_num));
 505        }
 506        if (train_status == NULL) {
 507                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 508                                         ("error param 4\n"));
 509                return MV_BAD_PARAM;
 510        }
 511
 512        /* load pattern */
 513        if (cs_type == CS_SINGLE) {
 514                /* All CSs to CS0     */
 515                CHECK_STATUS(ddr3_tip_if_write
 516                             (dev_num, access_type, interface_num,
 517                              DUAL_DUNIT_CFG_REG, 1 << 3, 1 << 3));
 518                /* All CSs to CS0     */
 519                CHECK_STATUS(ddr3_tip_if_write
 520                             (dev_num, access_type, interface_num,
 521                              ODPG_DATA_CTRL_REG,
 522                              (0x3 | (effective_cs << 26)), 0xc000003));
 523        } else {
 524                CHECK_STATUS(ddr3_tip_if_write
 525                             (dev_num, access_type, interface_num,
 526                              DUAL_DUNIT_CFG_REG, 0, 1 << 3));
 527                /*  CS select */
 528                CHECK_STATUS(ddr3_tip_if_write
 529                             (dev_num, access_type, interface_num,
 530                              ODPG_DATA_CTRL_REG, 0x3 | cs_num << 26,
 531                              0x3 | 3 << 26));
 532        }
 533
 534        /* load pattern to ODPG */
 535        ddr3_tip_load_pattern_to_odpg(dev_num, access_type, interface_num,
 536                                      pattern,
 537                                      pattern_table[pattern].start_addr);
 538        tx_burst_size = (direction == OPER_WRITE) ?
 539                pattern_table[pattern].tx_burst_size : 0;
 540        delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
 541        rd_mode = (direction == OPER_WRITE) ? 1 : 0;
 542        CHECK_STATUS(ddr3_tip_configure_odpg
 543                     (dev_num, access_type, interface_num, direction,
 544                      pattern_table[pattern].num_of_phases_tx, tx_burst_size,
 545                      pattern_table[pattern].num_of_phases_rx,
 546                      delay_between_burst, rd_mode, effective_cs, STRESS_NONE,
 547                      DURATION_SINGLE));
 548        reg_data = (direction == OPER_READ) ? 0 : (0x3 << 30);
 549        reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
 550        CHECK_STATUS(ddr3_tip_if_write
 551                     (dev_num, access_type, interface_num,
 552                      ODPG_WR_RD_MODE_ENA_REG, reg_data,
 553                      MASK_ALL_BITS));
 554        reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
 555        reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
 556                (1 << 7) : 0;
 557
 558        /* change from Pass to Fail will lock the result */
 559        if (pup_access_type == ACCESS_TYPE_MULTICAST)
 560                reg_data |= 0xe << 14;
 561        else
 562                reg_data |= pup_num << 14;
 563
 564        if (edge_comp == EDGE_FP) {
 565                /* don't search for readl edge change, only the state */
 566                reg_data |= (0 << 20);
 567        } else if (edge_comp == EDGE_FPF) {
 568                reg_data |= (0 << 20);
 569        } else {
 570                reg_data |= (3 << 20);
 571        }
 572
 573        CHECK_STATUS(ddr3_tip_if_write
 574                     (dev_num, access_type, interface_num,
 575                      GENERAL_TRAINING_OPCODE_REG,
 576                      reg_data | (0x7 << 8) | (0x7 << 11),
 577                      (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
 578                       (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
 579        reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
 580        CHECK_STATUS(ddr3_tip_if_write
 581                     (dev_num, access_type, interface_num, OPCODE_REG0_REG(1),
 582                      1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
 583                      0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));
 584
 585        /*
 586         * Write2_dunit(0x10b4, Number_iteration , [15:0])
 587         * Max number of iterations
 588         */
 589        CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
 590                                       OPCODE_REG1_REG(1), num_iter,
 591                                       0xffff));
 592        if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
 593            direction == OPER_READ) {
 594                /*
 595                 * Write2_dunit(0x10c0, 0x5f , [7:0])
 596                 * MC PBS Reg Address at DDR PHY
 597                 */
 598                reg_data = PBS_RX_BCAST_PHY_REG(effective_cs);
 599        } else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
 600                   direction == OPER_WRITE) {
 601                reg_data = PBS_TX_BCAST_PHY_REG(effective_cs);
 602        } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
 603                   direction == OPER_WRITE) {
 604                /*
 605                 * LOOP         0x00000001 + 4*n:
 606                 * where n (0-3) represents M_CS number
 607                 */
 608                /*
 609                 * Write2_dunit(0x10c0, 0x1 , [7:0])
 610                 * ADLL WR Reg Address at DDR PHY
 611                 */
 612                reg_data = CTX_PHY_REG(effective_cs);
 613        } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
 614                   direction == OPER_READ) {
 615                /* ADLL RD Reg Address at DDR PHY */
 616                reg_data = CRX_PHY_REG(effective_cs);
 617        } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
 618                   direction == OPER_WRITE) {
 619                /* TBD not defined in 0.5.0 requirement  */
 620        } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
 621                   direction == OPER_READ) {
 622                /* TBD not defined in 0.5.0 requirement */
 623        }
 624
 625        reg_data |= (0x6 << 28);
 626        CHECK_STATUS(ddr3_tip_if_write
 627                     (dev_num, access_type, interface_num, CAL_PHY_REG(1),
 628                      reg_data | (init_value << 8),
 629                      0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));
 630
 631        mask_dq_num_of_regs = octets_per_if_num * BUS_WIDTH_IN_BITS;
 632        mask_pup_num_of_regs = octets_per_if_num;
 633
 634        if (result_type == RESULT_PER_BIT) {
 635                for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
 636                     index_cnt++) {
 637                        CHECK_STATUS(ddr3_tip_if_write
 638                                     (dev_num, access_type, interface_num,
 639                                      mask_results_dq_reg_map[index_cnt], 0,
 640                                      1 << 24));
 641                }
 642
 643                /* Mask disabled buses */
 644                for (pup_id = 0; pup_id < octets_per_if_num;
 645                     pup_id++) {
 646                        if (IS_BUS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
 647                                continue;
 648
 649                        for (index_cnt = (pup_id * 8); index_cnt < (pup_id + 1) * 8; index_cnt++) {
 650                                CHECK_STATUS(ddr3_tip_if_write
 651                                             (dev_num, access_type,
 652                                              interface_num,
 653                                              mask_results_dq_reg_map
 654                                              [index_cnt], (1 << 24), 1 << 24));
 655                        }
 656                }
 657
 658                for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
 659                     index_cnt++) {
 660                        CHECK_STATUS(ddr3_tip_if_write
 661                                     (dev_num, access_type, interface_num,
 662                                      mask_results_pup_reg_map[index_cnt],
 663                                      (1 << 24), 1 << 24));
 664                }
 665        } else if (result_type == RESULT_PER_BYTE) {
 666                /* write to adll */
 667                for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
 668                     index_cnt++) {
 669                        CHECK_STATUS(ddr3_tip_if_write
 670                                     (dev_num, access_type, interface_num,
 671                                      mask_results_pup_reg_map[index_cnt], 0,
 672                                      1 << 24));
 673                }
 674                for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
 675                     index_cnt++) {
 676                        CHECK_STATUS(ddr3_tip_if_write
 677                                     (dev_num, access_type, interface_num,
 678                                      mask_results_dq_reg_map[index_cnt],
 679                                      (1 << 24), (1 << 24)));
 680                }
 681        }
 682
 683        /* trigger training */
 684        mv_ddr_training_enable();
 685
 686        /* wa for 16-bit mode: wait for all rfu tests to finish or timeout */
 687        mdelay(1);
 688
 689        /* check for training done */
 690        if (mv_ddr_is_training_done(MAX_POLLING_ITERATIONS, &data) != MV_OK) {
 691                train_status[0] = HWS_TRAINING_IP_STATUS_TIMEOUT;
 692        } else { /* training done; check for pass */
 693                if (data == PASS)
 694                        train_status[0] = HWS_TRAINING_IP_STATUS_SUCCESS;
 695                else
 696                        train_status[0] = HWS_TRAINING_IP_STATUS_FAIL;
 697        }
 698
 699        ddr3_tip_if_write(0, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
 700                          ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS);
 701#if defined(CONFIG_DDR4)
 702        if (tm->debug_level != DEBUG_LEVEL_ERROR)
 703                refresh();
 704#endif
 705
 706        return MV_OK;
 707}
 708
 709/*
 710 * Load expected Pattern to ODPG
 711 */
 712int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
 713                                  u32 if_id, enum hws_pattern pattern,
 714                                  u32 load_addr)
 715{
 716        u32 pattern_length_cnt = 0;
 717        struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
 718        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 719
 720        for (pattern_length_cnt = 0;
 721             pattern_length_cnt < pattern_table[pattern].pattern_len;
 722             pattern_length_cnt++) {    /* FIXME: the ecc patch below is only for a7040 A0 */
 723                if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)/* || tm->bus_act_mask == MV_DDR_32BIT_ECC_PUP8_BUS_MASK*/) {
 724                        CHECK_STATUS(ddr3_tip_if_write
 725                                     (dev_num, access_type, if_id,
 726                                      ODPG_DATA_WR_DATA_LOW_REG,
 727                                      pattern_table_get_word(dev_num, pattern,
 728                                                             (u8) (pattern_length_cnt)),
 729                                      MASK_ALL_BITS));
 730                        CHECK_STATUS(ddr3_tip_if_write
 731                                     (dev_num, access_type, if_id,
 732                                      ODPG_DATA_WR_DATA_HIGH_REG,
 733                                      pattern_table_get_word(dev_num, pattern,
 734                                                             (u8) (pattern_length_cnt)),
 735                                      MASK_ALL_BITS));
 736                } else {
 737                        CHECK_STATUS(ddr3_tip_if_write
 738                                     (dev_num, access_type, if_id,
 739                                              ODPG_DATA_WR_DATA_LOW_REG,
 740                                      pattern_table_get_word(dev_num, pattern,
 741                                                             (u8) (pattern_length_cnt * 2)),
 742                                      MASK_ALL_BITS));
 743                        CHECK_STATUS(ddr3_tip_if_write
 744                                     (dev_num, access_type, if_id,
 745                                      ODPG_DATA_WR_DATA_HIGH_REG,
 746                                      pattern_table_get_word(dev_num, pattern,
 747                                                             (u8) (pattern_length_cnt * 2 + 1)),
 748                                      MASK_ALL_BITS));
 749                }
 750                CHECK_STATUS(ddr3_tip_if_write
 751                             (dev_num, access_type, if_id,
 752                              ODPG_DATA_WR_ADDR_REG, pattern_length_cnt,
 753                              MASK_ALL_BITS));
 754        }
 755
 756        CHECK_STATUS(ddr3_tip_if_write
 757                     (dev_num, access_type, if_id,
 758                      ODPG_DATA_BUFFER_OFFS_REG, load_addr, MASK_ALL_BITS));
 759
 760        return MV_OK;
 761}
 762
 763/*
 764 * Configure ODPG
 765 */
 766int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
 767                            u32 if_id, enum hws_dir direction, u32 tx_phases,
 768                            u32 tx_burst_size, u32 rx_phases,
 769                            u32 delay_between_burst, u32 rd_mode, u32 cs_num,
 770                            u32 addr_stress_jump, u32 single_pattern)
 771{
 772        u32 data_value = 0;
 773        int ret;
 774
 775        data_value = ((single_pattern << 2) | (tx_phases << 5) |
 776                      (tx_burst_size << 11) | (delay_between_burst << 15) |
 777                      (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
 778                      (addr_stress_jump << 29));
 779        ret = ddr3_tip_if_write(dev_num, access_type, if_id,
 780                                ODPG_DATA_CTRL_REG, data_value, 0xaffffffc);
 781        if (ret != MV_OK)
 782                return ret;
 783
 784        return MV_OK;
 785}
 786
 787int ddr3_tip_process_result(u32 *ar_result, enum hws_edge e_edge,
 788                            enum hws_edge_search e_edge_search,
 789                            u32 *edge_result)
 790{
 791        u32 i, res;
 792        int tap_val, max_val = -10000, min_val = 10000;
 793        int lock_success = 1;
 794
 795        for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
 796                res = GET_LOCK_RESULT(ar_result[i]);
 797                if (res == 0) {
 798                        lock_success = 0;
 799                        break;
 800                }
 801                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 802                                         ("lock failed for bit %d\n", i));
 803        }
 804
 805        if (lock_success == 1) {
 806                for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
 807                        tap_val = GET_TAP_RESULT(ar_result[i], e_edge);
 808                        if (tap_val > max_val)
 809                                max_val = tap_val;
 810                        if (tap_val < min_val)
 811                                min_val = tap_val;
 812                        if (e_edge_search == TRAINING_EDGE_MAX)
 813                                *edge_result = (u32) max_val;
 814                        else
 815                                *edge_result = (u32) min_val;
 816
 817                        DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 818                                                 ("i %d ar_result[i] 0x%x tap_val %d max_val %d min_val %d Edge_result %d\n",
 819                                                  i, ar_result[i], tap_val,
 820                                                  max_val, min_val,
 821                                                  *edge_result));
 822                }
 823        } else {
 824                return MV_FAIL;
 825        }
 826
 827        return MV_OK;
 828}
 829
 830/*
 831 * Read training search result
 832 */
 833int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
 834                                  enum hws_access_type pup_access_type,
 835                                  u32 pup_num, u32 bit_num,
 836                                  enum hws_search_dir search,
 837                                  enum hws_dir direction,
 838                                  enum hws_training_result result_type,
 839                                  enum hws_training_load_op operation,
 840                                  u32 cs_num_type, u32 **load_res,
 841                                  int is_read_from_db, u8 cons_tap,
 842                                  int is_check_result_validity)
 843{
 844        u32 reg_offset, pup_cnt, start_pup, end_pup, start_reg, end_reg;
 845        u32 *interface_train_res = NULL;
 846        u16 *reg_addr = NULL;
 847        u32 read_data[MAX_INTERFACE_NUM];
 848        u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
 849        u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
 850        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
 851        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 852
 853        /*
 854         * Agreed assumption: all CS mask contain same number of bits,
 855         * i.e. in multi CS, the number of CS per memory is the same for
 856         * all pups
 857         */
 858        CHECK_STATUS(ddr3_tip_if_write
 859                     (dev_num, ACCESS_TYPE_UNICAST, if_id, DUAL_DUNIT_CFG_REG,
 860                      (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
 861        CHECK_STATUS(ddr3_tip_if_write
 862                     (dev_num, ACCESS_TYPE_UNICAST, if_id,
 863                      ODPG_DATA_CTRL_REG, (cs_num_type << 26), (3 << 26)));
 864        DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
 865                                 ("Read_from_d_b %d cs_type %d oper %d result_type %d direction %d search %d pup_num %d if_id %d pup_access_type %d\n",
 866                                  is_read_from_db, cs_num_type, operation,
 867                                  result_type, direction, search, pup_num,
 868                                  if_id, pup_access_type));
 869
 870        if ((load_res == NULL) && (is_read_from_db == 1)) {
 871                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 872                                         ("ddr3_tip_read_training_result load_res = NULL"));
 873                return MV_FAIL;
 874        }
 875        if (pup_num >= octets_per_if_num) {
 876                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 877                                         ("pup_num %d not valid\n", pup_num));
 878        }
 879        if (if_id >= MAX_INTERFACE_NUM) {
 880                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
 881                                         ("if_id %d not valid\n", if_id));
 882        }
 883        if (result_type == RESULT_PER_BIT)
 884                reg_addr = mask_results_dq_reg_map;
 885        else
 886                reg_addr = mask_results_pup_reg_map;
 887        if (pup_access_type == ACCESS_TYPE_UNICAST) {
 888                start_pup = pup_num;
 889                end_pup = pup_num;
 890        } else {                /*pup_access_type == ACCESS_TYPE_MULTICAST) */
 891
 892                start_pup = 0;
 893                end_pup = octets_per_if_num - 1;
 894        }
 895
 896        for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
 897                VALIDATE_BUS_ACTIVE(tm->bus_act_mask, pup_cnt);
 898                DEBUG_TRAINING_IP_ENGINE(
 899                        DEBUG_LEVEL_TRACE,
 900                        ("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
 901                         if_id, start_pup, end_pup, pup_cnt));
 902                if (result_type == RESULT_PER_BIT) {
 903                        if (bit_num == ALL_BITS_PER_PUP) {
 904                                start_reg = pup_cnt * BUS_WIDTH_IN_BITS;
 905                                end_reg = (pup_cnt + 1) * BUS_WIDTH_IN_BITS - 1;
 906                        } else {
 907                                start_reg =
 908                                        pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
 909                                end_reg = pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
 910                        }
 911                } else {
 912                        start_reg = pup_cnt;
 913                        end_reg = pup_cnt;
 914                }
 915
 916                interface_train_res =
 917                        ddr3_tip_get_buf_ptr(dev_num, search, result_type,
 918                                             if_id);
 919                DEBUG_TRAINING_IP_ENGINE(
 920                        DEBUG_LEVEL_TRACE,
 921                        ("start_reg %d end_reg %d interface %p\n",
 922                         start_reg, end_reg, interface_train_res));
 923                if (interface_train_res == NULL) {
 924                        DEBUG_TRAINING_IP_ENGINE(
 925                                DEBUG_LEVEL_ERROR,
 926                                ("interface_train_res is NULL\n"));
 927                        return MV_FAIL;
 928                }
 929
 930                for (reg_offset = start_reg; reg_offset <= end_reg;
 931                     reg_offset++) {
 932                        if (operation == TRAINING_LOAD_OPERATION_UNLOAD) {
 933                                if (is_read_from_db == 0) {
 934                                        CHECK_STATUS(ddr3_tip_if_read
 935                                                     (dev_num,
 936                                                      ACCESS_TYPE_UNICAST,
 937                                                      if_id,
 938                                                      reg_addr[reg_offset],
 939                                                      read_data,
 940                                                      MASK_ALL_BITS));
 941                                        if (is_check_result_validity == 1) {
 942                                                if ((read_data[if_id] &
 943                                                     TIP_ENG_LOCK) == 0) {
 944                                                        interface_train_res
 945                                                                [reg_offset] =
 946                                                                TIP_ENG_LOCK +
 947                                                                TIP_TX_DLL_RANGE_MAX;
 948                                                } else {
 949                                                        interface_train_res
 950                                                                [reg_offset] =
 951                                                                read_data
 952                                                                [if_id] +
 953                                                                cons_tap;
 954                                                }
 955                                        } else {
 956                                                interface_train_res[reg_offset]
 957                                                        = read_data[if_id] +
 958                                                        cons_tap;
 959                                        }
 960                                        DEBUG_TRAINING_IP_ENGINE
 961                                                (DEBUG_LEVEL_TRACE,
 962                                                 ("reg_offset %d value 0x%x addr %p\n",
 963                                                  reg_offset,
 964                                                  interface_train_res
 965                                                  [reg_offset],
 966                                                  &interface_train_res
 967                                                  [reg_offset]));
 968                                } else {
 969                                        *load_res =
 970                                                &interface_train_res[start_reg];
 971                                        DEBUG_TRAINING_IP_ENGINE
 972                                                (DEBUG_LEVEL_TRACE,
 973                                                 ("*load_res %p\n", *load_res));
 974                                }
 975                        } else {
 976                                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
 977                                                         ("not supported\n"));
 978                        }
 979                }
 980        }
 981#if defined(CONFIG_DDR4)
 982        if (tm->debug_level != DEBUG_LEVEL_ERROR)
 983                refresh();
 984#endif
 985
 986        return MV_OK;
 987}
 988
 989/*
 990 * Load all pattern to memory using ODPG
 991 */
 992int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
 993{
 994        u32 pattern = 0, if_id;
 995        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 996
 997        for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
 998                VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
 999                training_result[training_stage][if_id] = TEST_SUCCESS;
1000        }
1001
1002        for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1003                VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1004                /* enable single cs */
1005                CHECK_STATUS(ddr3_tip_if_write
1006                             (dev_num, ACCESS_TYPE_UNICAST, if_id,
1007                              DUAL_DUNIT_CFG_REG, (1 << 3), (1 << 3)));
1008        }
1009
1010        for (pattern = 0; pattern < PATTERN_LAST; pattern++) {
1011                if (pattern == PATTERN_TEST)
1012                        continue;
1013                ddr3_tip_load_pattern_to_mem(dev_num, pattern);
1014        }
1015
1016        return MV_OK;
1017}
1018
1019/*
1020 * Load specific pattern to memory using ODPG
1021 */
1022int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
1023{
1024        u32 reg_data, if_id;
1025        struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
1026        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1027
1028        /* load pattern to memory */
1029        /*
1030         * Write Tx mode, CS0, phases, Tx burst size, delay between burst,
1031         * rx pattern phases
1032         */
1033        reg_data =
1034                0x1 | (pattern_table[pattern].num_of_phases_tx << 5) |
1035                (pattern_table[pattern].tx_burst_size << 11) |
1036                (pattern_table[pattern].delay_between_bursts << 15) |
1037                (pattern_table[pattern].num_of_phases_rx << 21) | (0x1 << 25) |
1038                (effective_cs << 26);
1039        CHECK_STATUS(ddr3_tip_if_write
1040                     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1041                      ODPG_DATA_CTRL_REG, reg_data, MASK_ALL_BITS));
1042        /* ODPG Write enable from BIST */
1043        CHECK_STATUS(ddr3_tip_if_write
1044                     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1045                      ODPG_DATA_CTRL_REG, (0x1 | (effective_cs << 26)),
1046                      0xc000003));
1047        /* disable error injection */
1048        CHECK_STATUS(ddr3_tip_if_write
1049                     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1050                      ODPG_DATA_WR_DATA_ERR_REG, 0, 0x1));
1051        /* load pattern to ODPG */
1052        ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
1053                                      PARAM_NOT_CARE, pattern,
1054                                      pattern_table[pattern].start_addr);
1055
1056        if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
1057                for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
1058                        VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1059
1060                        CHECK_STATUS(ddr3_tip_if_write
1061                                     (dev_num, ACCESS_TYPE_UNICAST, if_id,
1062                                      SDRAM_ODT_CTRL_HIGH_REG,
1063                                      0x3, 0xf));
1064                }
1065
1066                mv_ddr_odpg_enable();
1067        } else {
1068                CHECK_STATUS(ddr3_tip_if_write
1069                             (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1070                              ODPG_DATA_CTRL_REG, (u32)(0x1 << 31),
1071                              (u32)(0x1 << 31)));
1072        }
1073        mdelay(1);
1074
1075        if (mv_ddr_is_odpg_done(MAX_POLLING_ITERATIONS) != MV_OK)
1076                return MV_FAIL;
1077
1078        /* Disable ODPG and stop write to memory */
1079        CHECK_STATUS(ddr3_tip_if_write
1080                     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1081                      ODPG_DATA_CTRL_REG, (0x1 << 30), (u32) (0x3 << 30)));
1082
1083        /* return to default */
1084        CHECK_STATUS(ddr3_tip_if_write
1085                     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1086                      ODPG_DATA_CTRL_REG, 0, MASK_ALL_BITS));
1087
1088        if (ddr3_tip_dev_attr_get(dev_num, MV_ATTR_TIP_REV) >= MV_TIP_REV_3) {
1089                /* Disable odt0 for CS0 training - need to adjust for multy CS */
1090                CHECK_STATUS(ddr3_tip_if_write
1091                             (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1092                              SDRAM_ODT_CTRL_HIGH_REG, 0x0, 0xf));
1093        }
1094        /* temporary added */
1095        mdelay(1);
1096
1097        return MV_OK;
1098}
1099
1100/*
1101 * Training search routine
1102 */
1103int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
1104                                     enum hws_access_type access_type,
1105                                     u32 if_id,
1106                                     enum hws_access_type pup_access_type,
1107                                     u32 pup_num, u32 bit_num,
1108                                     enum hws_training_result result_type,
1109                                     enum hws_control_element control_element,
1110                                     enum hws_search_dir search_dir,
1111                                     enum hws_dir direction,
1112                                     u32 interface_mask, u32 init_value_l2h,
1113                                     u32 init_value_h2l, u32 num_iter,
1114                                     enum hws_pattern pattern,
1115                                     enum hws_edge_compare edge_comp,
1116                                     enum hws_ddr_cs train_cs_type, u32 cs_num,
1117                                     enum hws_training_ip_stat *train_status)
1118{
1119        u32 interface_num = 0, start_if, end_if, init_value_used;
1120        enum hws_search_dir search_dir_id, start_search, end_search;
1121        enum hws_edge_compare edge_comp_used;
1122        u8 cons_tap = 0;
1123        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1124        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1125
1126        if (train_status == NULL) {
1127                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1128                                         ("train_status is NULL\n"));
1129                return MV_FAIL;
1130        }
1131
1132        if ((train_cs_type > CS_NON_SINGLE) ||
1133            (edge_comp >= EDGE_PFP) ||
1134            (pattern >= PATTERN_LAST) ||
1135            (direction > OPER_WRITE_AND_READ) ||
1136            (search_dir > HWS_HIGH2LOW) ||
1137            (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
1138            (result_type > RESULT_PER_BYTE) ||
1139            (pup_num >= octets_per_if_num) ||
1140            (pup_access_type > ACCESS_TYPE_MULTICAST) ||
1141            (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
1142                DEBUG_TRAINING_IP_ENGINE(
1143                        DEBUG_LEVEL_ERROR,
1144                        ("wrong parameter train_cs_type %d edge_comp %d pattern %d direction %d search_dir %d control_element %d result_type %d pup_num %d pup_access_type %d if_id %d access_type %d\n",
1145                         train_cs_type, edge_comp, pattern, direction,
1146                         search_dir, control_element, result_type, pup_num,
1147                         pup_access_type, if_id, access_type));
1148                return MV_FAIL;
1149        }
1150
1151        if (edge_comp == EDGE_FPF) {
1152                start_search = HWS_LOW2HIGH;
1153                end_search = HWS_HIGH2LOW;
1154                edge_comp_used = EDGE_FP;
1155        } else {
1156                start_search = search_dir;
1157                end_search = search_dir;
1158                edge_comp_used = edge_comp;
1159        }
1160
1161        for (search_dir_id = start_search; search_dir_id <= end_search;
1162             search_dir_id++) {
1163                init_value_used = (search_dir_id == HWS_LOW2HIGH) ?
1164                        init_value_l2h : init_value_h2l;
1165                DEBUG_TRAINING_IP_ENGINE(
1166                        DEBUG_LEVEL_TRACE,
1167                        ("dev_num %d, access_type %d, if_id %d, pup_access_type %d,pup_num %d, result_type %d, control_element %d search_dir_id %d, direction %d, interface_mask %d,init_value_used %d, num_iter %d, pattern %d, edge_comp_used %d, train_cs_type %d, cs_num %d\n",
1168                         dev_num, access_type, if_id, pup_access_type, pup_num,
1169                         result_type, control_element, search_dir_id,
1170                         direction, interface_mask, init_value_used, num_iter,
1171                         pattern, edge_comp_used, train_cs_type, cs_num));
1172
1173                ddr3_tip_ip_training(dev_num, access_type, if_id,
1174                                     pup_access_type, pup_num, result_type,
1175                                     control_element, search_dir_id, direction,
1176                                     interface_mask, init_value_used, num_iter,
1177                                     pattern, edge_comp_used, train_cs_type,
1178                                     cs_num, train_status);
1179                if (access_type == ACCESS_TYPE_MULTICAST) {
1180                        start_if = 0;
1181                        end_if = MAX_INTERFACE_NUM - 1;
1182                } else {
1183                        start_if = if_id;
1184                        end_if = if_id;
1185                }
1186
1187                for (interface_num = start_if; interface_num <= end_if;
1188                     interface_num++) {
1189                        VALIDATE_IF_ACTIVE(tm->if_act_mask, interface_num);
1190                        cs_num = 0;
1191                        CHECK_STATUS(ddr3_tip_read_training_result
1192                                     (dev_num, interface_num, pup_access_type,
1193                                      pup_num, bit_num, search_dir_id,
1194                                      direction, result_type,
1195                                      TRAINING_LOAD_OPERATION_UNLOAD,
1196                                      train_cs_type, NULL, 0, cons_tap,
1197                                      0));
1198                }
1199        }
1200
1201        return MV_OK;
1202}
1203/*
1204 * Training search & read result routine
1205 * This function implements the search algorithm
1206 * first it calls the function ddr3_tip_ip_training_wrapper_int which triggers the search from l2h and h2l
1207 * this function handles rx and tx search cases
1208 * in case of rx it only triggers the search (l2h and h2l)
1209 * in case of tx there are 3 optional algorithm phases:
1210 * phase 1:
1211 * it first triggers the search and handles the results as following (phase 1):
1212 * each bit, which defined by the search two edges (e1 or VW_L and e2 or VW_H), match on of cases:
1213 *  1.  BIT_LOW_UI      0 =< VW =< 31 in case of jitter use: VW_L <= 31, VW_H <= 31
1214 *  2.  BIT_HIGH_UI     32 =< VW =< 63 in case of jitter use: VW_L >= 32, VW_H >= 32
1215 *  3.  BIT_SPLIT_IN    VW_L <= 31 & VW_H >= 32
1216 *  4.  BIT_SPLIT_OUT*  VW_H < 32 &  VW_L > 32
1217 * note: the VW units is adll taps
1218 * phase 2:
1219 * only bit case BIT_SPLIT_OUT requires another search (phase 2) from the middle range in two directions h2l and l2h
1220 * because only this case is not locked by the search engine in the first search trigger (phase 1).
1221 * phase 3:
1222 * each subphy is categorized according to its bits definition.
1223 * the sub-phy cases are as follows:
1224 *  1.BYTE_NOT_DEFINED                  the byte has not yet been categorized
1225 *  2.BYTE_HOMOGENEOUS_LOW              0 =< VW =< 31
1226 *  3.BYTE_HOMOGENEOUS_HIGH             32 =< VW =< 63
1227 *  4.BYTE_HOMOGENEOUS_SPLIT_IN         VW_L <= 31 & VW_H >= 32
1228 *                                      or the center of all bits in the byte  =< 31
1229 *  5.BYTE_HOMOGENEOUS_SPLIT_OUT        VW_H < 32 &  VW_L > 32
1230 *  6.BYTE_SPLIT_OUT_MIX                at least one bits is in split out state and one bit is in other
1231 *                                      or the center of all bits in the byte => 32
1232 * after the two phases above a center valid window for each subphy is calculated accordingly:
1233 * center valid window = maximum center of all bits in the subphy - minimum center of all bits in the subphy.
1234 * now decisions are made in each subphy as following:
1235 * all subphys which are homogeneous remains as is
1236 * all subphys which are homogeneous low | homogeneous high and the subphy center valid window is less than 32
1237 *      mark this subphy as homogeneous split in.
1238 * now the bits in the bytes which are BYTE_SPLIT_OUT_MIX needed to be reorganized and handles as following
1239 * all bits which are BIT_LOW_UI will be added with 64 adll,
1240 * this will hopefully ensures that all the bits in the sub phy can be sampled by the dqs
1241 */
1242int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
1243        u32 if_id,
1244        enum hws_access_type pup_access_type,
1245        u32 pup_num,
1246        enum hws_training_result result_type,
1247        enum hws_control_element control_element,
1248        enum hws_search_dir search_dir,
1249        enum hws_dir direction, u32 interface_mask,
1250        u32 init_value_l2h, u32 init_value_h2l,
1251        u32 num_iter, enum hws_pattern pattern,
1252        enum hws_edge_compare edge_comp,
1253        enum hws_ddr_cs train_cs_type, u32 cs_num,
1254        enum hws_training_ip_stat *train_status)
1255{
1256        u8 e1, e2;
1257        u32 bit_id, start_if, end_if, bit_end = 0;
1258        u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
1259        u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
1260        u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
1261        u8 bit_state[MAX_BUS_NUM * BUS_WIDTH_IN_BITS] = {0};
1262        u8 h2l_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
1263        u8 l2h_adll_value[MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
1264        u8 center_subphy_adll_window[MAX_BUS_NUM];
1265        u8 min_center_subphy_adll[MAX_BUS_NUM];
1266        u8 max_center_subphy_adll[MAX_BUS_NUM];
1267        u32 *l2h_if_train_res = NULL;
1268        u32 *h2l_if_train_res = NULL;
1269        enum hws_search_dir search_dir_id;
1270        int status;
1271        u32 bit_lock_result;
1272
1273        u8 sybphy_id;
1274        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1275        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1276
1277        if (pup_num >= octets_per_if_num) {
1278                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1279                        ("pup_num %d not valid\n", pup_num));
1280        }
1281
1282        if (if_id >= MAX_INTERFACE_NUM) {
1283                DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
1284                        ("if_id %d not valid\n", if_id));
1285        }
1286
1287        status = ddr3_tip_ip_training_wrapper_int
1288                (dev_num, access_type, if_id, pup_access_type, pup_num,
1289                ALL_BITS_PER_PUP, result_type, control_element,
1290                search_dir, direction, interface_mask, init_value_l2h,
1291                init_value_h2l, num_iter, pattern, edge_comp,
1292                train_cs_type, cs_num, train_status);
1293
1294        if (MV_OK != status)
1295                return status;
1296
1297        if (access_type == ACCESS_TYPE_MULTICAST) {
1298                start_if = 0;
1299                end_if = MAX_INTERFACE_NUM - 1;
1300        } else {
1301                start_if = if_id;
1302                end_if = if_id;
1303        }
1304
1305        for (if_id = start_if; if_id <= end_if; if_id++) {
1306                VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1307                /* zero the database */
1308                bit_bit_mask_active = 0;        /* clean the flag for level2 search */
1309                memset(bit_state, 0, sizeof(bit_state));
1310                /* phase 1 */
1311                for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1312                        VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1313                        if (result_type == RESULT_PER_BIT)
1314                                bit_end = BUS_WIDTH_IN_BITS;
1315                        else
1316                                bit_end = 0;
1317
1318                        /* zero the data base */
1319                        bit_bit_mask[sybphy_id] = 0;
1320                        byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
1321                        for (bit_id = 0; bit_id < bit_end; bit_id++) {
1322                                h2l_adll_value[sybphy_id][bit_id] = 64;
1323                                l2h_adll_value[sybphy_id][bit_id] = 0;
1324                                for (search_dir_id = HWS_LOW2HIGH; search_dir_id <= HWS_HIGH2LOW;
1325                                        search_dir_id++) {
1326                                        status = ddr3_tip_read_training_result
1327                                                (dev_num, if_id,
1328                                                        ACCESS_TYPE_UNICAST, sybphy_id, bit_id,
1329                                                        search_dir_id, direction, result_type,
1330                                                        TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1331                                                        &result[search_dir_id], 1, 0, 0);
1332
1333                                        if (MV_OK != status)
1334                                                return status;
1335                                }
1336
1337                                e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0], EDGE_1);
1338                                e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0], EDGE_1);
1339                                DEBUG_TRAINING_IP_ENGINE
1340                                        (DEBUG_LEVEL_INFO,
1341                                         ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
1342                                         if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
1343                                         result[HWS_HIGH2LOW][0], e2));
1344                                bit_lock_result =
1345                                        (GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
1346                                                GET_LOCK_RESULT(result[HWS_HIGH2LOW][0]));
1347
1348                                if (bit_lock_result) {
1349                                        /* in case of read operation set the byte status as homogeneous low */
1350                                        if (direction == OPER_READ) {
1351                                                byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
1352                                        } else if ((e2 - e1) > 32) { /* oper_write */
1353                                                /* split out */
1354                                                bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1355                                                        BIT_SPLIT_OUT;
1356                                                byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_SPLIT_OUT;
1357                                                /* mark problem bits */
1358                                                bit_bit_mask[sybphy_id] |= (1 << bit_id);
1359                                                bit_bit_mask_active = 1;
1360                                                DEBUG_TRAINING_IP_ENGINE
1361                                                        (DEBUG_LEVEL_TRACE,
1362                                                         ("if_id %d sybphy_id %d bit %d BIT_SPLIT_OUT\n",
1363                                                         if_id, sybphy_id, bit_id));
1364                                        } else {
1365                                                /* low ui */
1366                                                if (e1 <= 31 && e2 <= 31) {
1367                                                        bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1368                                                                BIT_LOW_UI;
1369                                                        byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_LOW;
1370                                                        l2h_adll_value[sybphy_id][bit_id] = e1;
1371                                                        h2l_adll_value[sybphy_id][bit_id] = e2;
1372                                                        DEBUG_TRAINING_IP_ENGINE
1373                                                                (DEBUG_LEVEL_TRACE,
1374                                                                 ("if_id %d sybphy_id %d bit %d BIT_LOW_UI\n",
1375                                                                 if_id, sybphy_id, bit_id));
1376                                                }
1377                                                        /* high ui */
1378                                                if (e1 >= 32 && e2 >= 32) {
1379                                                        bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1380                                                                BIT_HIGH_UI;
1381                                                        byte_status[if_id][sybphy_id] |= BYTE_HOMOGENEOUS_HIGH;
1382                                                        l2h_adll_value[sybphy_id][bit_id] = e1;
1383                                                        h2l_adll_value[sybphy_id][bit_id] = e2;
1384                                                        DEBUG_TRAINING_IP_ENGINE
1385                                                                (DEBUG_LEVEL_TRACE,
1386                                                                 ("if_id %d sybphy_id %d bit %d BIT_HIGH_UI\n",
1387                                                                 if_id, sybphy_id, bit_id));
1388                                                }
1389                                                /* split in */
1390                                                if (e1 <= 31 && e2 >= 32) {
1391                                                        bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] =
1392                                                                BIT_SPLIT_IN;
1393                                                        byte_status[if_id][sybphy_id] |=
1394                                                                BYTE_HOMOGENEOUS_SPLIT_IN;
1395                                                        l2h_adll_value[sybphy_id][bit_id] = e1;
1396                                                        h2l_adll_value[sybphy_id][bit_id] = e2;
1397                                                        DEBUG_TRAINING_IP_ENGINE
1398                                                                (DEBUG_LEVEL_TRACE,
1399                                                                 ("if_id %d sybphy_id %d bit %d BIT_SPLIT_IN\n",
1400                                                                 if_id, sybphy_id, bit_id));
1401                                                }
1402                                        }
1403                                } else {
1404                                        DEBUG_TRAINING_IP_ENGINE
1405                                                (DEBUG_LEVEL_INFO,
1406                                                 ("if_id %d sybphy_id %d bit %d l2h 0x%x (e1 0x%x)"
1407                                                 "h2l 0x%x (e2 0x%x): bit cannot be categorized\n",
1408                                                 if_id, sybphy_id, bit_id, result[HWS_LOW2HIGH][0], e1,
1409                                                 result[HWS_HIGH2LOW][0], e2));
1410                                        /* mark the byte as not defined */
1411                                        byte_status[if_id][sybphy_id] = BYTE_NOT_DEFINED;
1412                                        break; /* continue to next pup - no reason to analyze this byte */
1413                                }
1414                        } /* for all bits */
1415                } /* for all PUPs */
1416
1417                /* phase 2 will occur only in write operation */
1418                if (bit_bit_mask_active != 0) {
1419                        l2h_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH, result_type, if_id);
1420                        h2l_if_train_res = ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW, result_type, if_id);
1421                        /* search from middle to end */
1422                        ddr3_tip_ip_training
1423                                (dev_num, ACCESS_TYPE_UNICAST,
1424                                 if_id, ACCESS_TYPE_MULTICAST,
1425                                 PARAM_NOT_CARE, result_type,
1426                                 control_element, HWS_LOW2HIGH,
1427                                 direction, interface_mask,
1428                                 num_iter / 2, num_iter / 2,
1429                                 pattern, EDGE_FP, train_cs_type,
1430                                 cs_num, train_status);
1431
1432                        for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1433                                VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1434                                if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
1435                                        if (bit_bit_mask[sybphy_id] == 0)
1436                                                continue; /* this byte bits have no split out state */
1437
1438                                        for (bit_id = 0; bit_id < bit_end; bit_id++) {
1439                                                if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
1440                                                        continue; /* this bit is non split goto next bit */
1441
1442                                                /* enter the result to the data base */
1443                                                status = ddr3_tip_read_training_result
1444                                                        (dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
1445                                                         bit_id, HWS_LOW2HIGH, direction, result_type,
1446                                                         TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1447                                                         &l2h_if_train_res, 0, 0, 1);
1448
1449                                                if (MV_OK != status)
1450                                                        return status;
1451
1452                                                l2h_adll_value[sybphy_id][bit_id] =
1453                                                        l2h_if_train_res[sybphy_id *
1454                                                        BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
1455                                        }
1456                                }
1457                        }
1458                        /* Search from middle to start */
1459                        ddr3_tip_ip_training
1460                                (dev_num, ACCESS_TYPE_UNICAST,
1461                                 if_id, ACCESS_TYPE_MULTICAST,
1462                                 PARAM_NOT_CARE, result_type,
1463                                 control_element, HWS_HIGH2LOW,
1464                                 direction, interface_mask,
1465                                 num_iter / 2, num_iter / 2,
1466                                 pattern, EDGE_FP, train_cs_type,
1467                                 cs_num, train_status);
1468
1469                        for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1470                                VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1471                                if (byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) {
1472                                        if (bit_bit_mask[sybphy_id] == 0)
1473                                                continue;
1474
1475                                        for (bit_id = 0; bit_id < bit_end; bit_id++) {
1476                                                if ((bit_bit_mask[sybphy_id] & (1 << bit_id)) == 0)
1477                                                        continue;
1478
1479                                                status = ddr3_tip_read_training_result
1480                                                        (dev_num, if_id, ACCESS_TYPE_UNICAST, sybphy_id,
1481                                                         bit_id, HWS_HIGH2LOW, direction, result_type,
1482                                                         TRAINING_LOAD_OPERATION_UNLOAD, CS_SINGLE,
1483                                                         &h2l_if_train_res, 0, cons_tap, 1);
1484
1485                                                if (MV_OK != status)
1486                                                        return status;
1487
1488                                                h2l_adll_value[sybphy_id][bit_id] =
1489                                                        h2l_if_train_res[sybphy_id *
1490                                                        BUS_WIDTH_IN_BITS + bit_id] & PUP_RESULT_EDGE_1_MASK;
1491                                        }
1492                                }
1493                        }
1494                } /* end if bit_bit_mask_active */
1495                /*
1496                        * phase 3 will occur only in write operation
1497                        * find the maximum and the minimum center of each subphy
1498                        */
1499                for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1500                        VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1501
1502                        if ((byte_status[if_id][sybphy_id] != BYTE_NOT_DEFINED) && (direction == OPER_WRITE)) {
1503                                /* clear the arrays and parameters */
1504                                center_subphy_adll_window[sybphy_id] = 0;
1505                                max_center_subphy_adll[sybphy_id] = 0;
1506                                min_center_subphy_adll[sybphy_id] = 64;
1507                                /* find the max and min center adll value in the current subphy */
1508                                for (bit_id = 0; bit_id < bit_end; bit_id++) {
1509                                        /* debug print all the bit edges after alignment */
1510                                        DEBUG_TRAINING_IP_ENGINE
1511                                                (DEBUG_LEVEL_TRACE,
1512                                                 ("if_id %d sybphy_id %d bit %d l2h %d h2l %d\n",
1513                                                 if_id, sybphy_id, bit_id, l2h_adll_value[sybphy_id][bit_id],
1514                                                 h2l_adll_value[sybphy_id][bit_id]));
1515
1516                                        if (((l2h_adll_value[sybphy_id][bit_id] +
1517                                              h2l_adll_value[sybphy_id][bit_id]) / 2) >
1518                                              max_center_subphy_adll[sybphy_id])
1519                                                max_center_subphy_adll[sybphy_id] =
1520                                                (l2h_adll_value[sybphy_id][bit_id] +
1521                                                 h2l_adll_value[sybphy_id][bit_id]) / 2;
1522                                        if (((l2h_adll_value[sybphy_id][bit_id] +
1523                                              h2l_adll_value[sybphy_id][bit_id]) / 2) <
1524                                              min_center_subphy_adll[sybphy_id])
1525                                                min_center_subphy_adll[sybphy_id] =
1526                                                (l2h_adll_value[sybphy_id][bit_id] +
1527                                                 h2l_adll_value[sybphy_id][bit_id]) / 2;
1528                                }
1529
1530                                /* calculate the center of the current subphy */
1531                                center_subphy_adll_window[sybphy_id] =
1532                                        max_center_subphy_adll[sybphy_id] -
1533                                        min_center_subphy_adll[sybphy_id];
1534                                DEBUG_TRAINING_IP_ENGINE
1535                                        (DEBUG_LEVEL_TRACE,
1536                                         ("if_id %d sybphy_id %d min center %d max center %d center %d\n",
1537                                         if_id, sybphy_id, min_center_subphy_adll[sybphy_id],
1538                                         max_center_subphy_adll[sybphy_id],
1539                                         center_subphy_adll_window[sybphy_id]));
1540                        }
1541                }
1542                /*
1543                        * check byte state and fix bits state if needed
1544                        * in case the level 1 and 2 above subphy results are
1545                        * homogeneous continue to the next subphy
1546                        */
1547                for (sybphy_id = 0; sybphy_id < octets_per_if_num; sybphy_id++) {
1548                        VALIDATE_BUS_ACTIVE(tm->bus_act_mask, sybphy_id);
1549                        if ((byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_LOW) ||
1550                            (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_HIGH) ||
1551                            (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_IN) ||
1552                            (byte_status[if_id][sybphy_id] == BYTE_HOMOGENEOUS_SPLIT_OUT) ||
1553                            (byte_status[if_id][sybphy_id] == BYTE_NOT_DEFINED))
1554                        continue;
1555
1556                        /*
1557                         * in case all of the bits in the current subphy are
1558                         * less than 32 which will find alignment in the subphy bits
1559                         * mark this subphy as homogeneous split in
1560                        */
1561                        if (center_subphy_adll_window[sybphy_id] <= 31)
1562                                byte_status[if_id][sybphy_id] = BYTE_HOMOGENEOUS_SPLIT_IN;
1563
1564                        /*
1565                                * in case the current byte is split_out and the center is bigger than 31
1566                                * the byte can be aligned. in this case add 64 to the the low ui bits aligning it
1567                                * to the other ui bits
1568                                */
1569                        if (center_subphy_adll_window[sybphy_id] >= 32) {
1570                                byte_status[if_id][sybphy_id] = BYTE_SPLIT_OUT_MIX;
1571
1572                                DEBUG_TRAINING_IP_ENGINE
1573                                        (DEBUG_LEVEL_TRACE,
1574                                         ("if_id %d sybphy_id %d byte state 0x%x\n",
1575                                         if_id, sybphy_id, byte_status[if_id][sybphy_id]));
1576                                for (bit_id = 0; bit_id < bit_end; bit_id++) {
1577                                        if (bit_state[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] == BIT_LOW_UI) {
1578                                                l2h_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
1579                                                h2l_if_train_res[sybphy_id * BUS_WIDTH_IN_BITS + bit_id] += 64;
1580                                        }
1581                                        DEBUG_TRAINING_IP_ENGINE
1582                                                (DEBUG_LEVEL_TRACE,
1583                                                 ("if_id %d sybphy_id %d bit_id %d added 64 adlls\n",
1584                                                 if_id, sybphy_id, bit_id));
1585                                }
1586                        }
1587                }
1588        } /* for all interfaces */
1589
1590        return MV_OK;
1591}
1592
1593u8 mv_ddr_tip_sub_phy_byte_status_get(u32 if_id, u32 subphy_id)
1594{
1595        return byte_status[if_id][subphy_id];
1596}
1597
1598void mv_ddr_tip_sub_phy_byte_status_set(u32 if_id, u32 subphy_id, u8 byte_status_data)
1599{
1600        byte_status[if_id][subphy_id] = byte_status_data;
1601}
1602
1603/*
1604 * Load phy values
1605 */
1606int ddr3_tip_load_phy_values(int b_load)
1607{
1608        u32 bus_cnt = 0, if_id, dev_num = 0;
1609        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1610        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1611
1612        for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1613                VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1614                for (bus_cnt = 0; bus_cnt < octets_per_if_num; bus_cnt++) {
1615                        VALIDATE_BUS_ACTIVE(tm->bus_act_mask, bus_cnt);
1616                        if (b_load == 1) {
1617                                CHECK_STATUS(ddr3_tip_bus_read
1618                                             (dev_num, if_id,
1619                                              ACCESS_TYPE_UNICAST, bus_cnt,
1620                                              DDR_PHY_DATA,
1621                                              CTX_PHY_REG(effective_cs),
1622                                              &phy_reg_bk[if_id][bus_cnt]
1623                                              [0]));
1624                                CHECK_STATUS(ddr3_tip_bus_read
1625                                             (dev_num, if_id,
1626                                              ACCESS_TYPE_UNICAST, bus_cnt,
1627                                              DDR_PHY_DATA,
1628                                              RL_PHY_REG(effective_cs),
1629                                              &phy_reg_bk[if_id][bus_cnt]
1630                                              [1]));
1631                                CHECK_STATUS(ddr3_tip_bus_read
1632                                             (dev_num, if_id,
1633                                              ACCESS_TYPE_UNICAST, bus_cnt,
1634                                              DDR_PHY_DATA,
1635                                              CRX_PHY_REG(effective_cs),
1636                                              &phy_reg_bk[if_id][bus_cnt]
1637                                              [2]));
1638                        } else {
1639                                CHECK_STATUS(ddr3_tip_bus_write
1640                                             (dev_num, ACCESS_TYPE_UNICAST,
1641                                              if_id, ACCESS_TYPE_UNICAST,
1642                                              bus_cnt, DDR_PHY_DATA,
1643                                              CTX_PHY_REG(effective_cs),
1644                                              phy_reg_bk[if_id][bus_cnt]
1645                                              [0]));
1646                                CHECK_STATUS(ddr3_tip_bus_write
1647                                             (dev_num, ACCESS_TYPE_UNICAST,
1648                                              if_id, ACCESS_TYPE_UNICAST,
1649                                              bus_cnt, DDR_PHY_DATA,
1650                                              RL_PHY_REG(effective_cs),
1651                                              phy_reg_bk[if_id][bus_cnt]
1652                                              [1]));
1653                                CHECK_STATUS(ddr3_tip_bus_write
1654                                             (dev_num, ACCESS_TYPE_UNICAST,
1655                                              if_id, ACCESS_TYPE_UNICAST,
1656                                              bus_cnt, DDR_PHY_DATA,
1657                                              CRX_PHY_REG(effective_cs),
1658                                              phy_reg_bk[if_id][bus_cnt]
1659                                              [2]));
1660                        }
1661                }
1662        }
1663
1664        return MV_OK;
1665}
1666
1667int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
1668                              enum hws_search_dir search_dir,
1669                              enum hws_dir direction,
1670                              enum hws_edge_compare edge,
1671                              u32 init_val1, u32 init_val2,
1672                              u32 num_of_iterations,
1673                              u32 start_pattern, u32 end_pattern)
1674{
1675        u32 pattern, if_id, pup_id;
1676        enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
1677        u32 *res = NULL;
1678        u32 search_state = 0;
1679        u32 octets_per_if_num = ddr3_tip_dev_attr_get(dev_num, MV_ATTR_OCTET_PER_INTERFACE);
1680        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1681
1682        ddr3_tip_load_phy_values(1);
1683
1684        for (pattern = start_pattern; pattern <= end_pattern; pattern++) {
1685                for (search_state = 0; search_state < HWS_SEARCH_DIR_LIMIT;
1686                     search_state++) {
1687                        ddr3_tip_ip_training_wrapper(dev_num,
1688                                                     ACCESS_TYPE_MULTICAST, 0,
1689                                                     ACCESS_TYPE_MULTICAST, 0,
1690                                                     result_type,
1691                                                     HWS_CONTROL_ELEMENT_ADLL,
1692                                                     search_dir, direction,
1693                                                     0xfff, init_val1,
1694                                                     init_val2,
1695                                                     num_of_iterations, pattern,
1696                                                     edge, CS_SINGLE,
1697                                                     PARAM_NOT_CARE,
1698                                                     train_status);
1699
1700                        for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
1701                             if_id++) {
1702                                VALIDATE_IF_ACTIVE(tm->if_act_mask, if_id);
1703                                for (pup_id = 0; pup_id <
1704                                             octets_per_if_num;
1705                                     pup_id++) {
1706                                        VALIDATE_BUS_ACTIVE(tm->bus_act_mask,
1707                                                        pup_id);
1708                                        CHECK_STATUS
1709                                                (ddr3_tip_read_training_result
1710                                                 (dev_num, if_id,
1711                                                  ACCESS_TYPE_UNICAST, pup_id,
1712                                                  ALL_BITS_PER_PUP,
1713                                                  search_state,
1714                                                  direction, result_type,
1715                                                  TRAINING_LOAD_OPERATION_UNLOAD,
1716                                                  CS_SINGLE, &res, 1, 0,
1717                                                  0));
1718                                        if (result_type == RESULT_PER_BYTE) {
1719                                                DEBUG_TRAINING_IP_ENGINE
1720                                                        (DEBUG_LEVEL_INFO,
1721                                                         ("search_state %d if_id %d pup_id %d 0x%x\n",
1722                                                          search_state, if_id,
1723                                                          pup_id, res[0]));
1724                                        } else {
1725                                                DEBUG_TRAINING_IP_ENGINE
1726                                                        (DEBUG_LEVEL_INFO,
1727                                                         ("search_state %d if_id %d pup_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1728                                                          search_state, if_id,
1729                                                          pup_id, res[0],
1730                                                          res[1], res[2],
1731                                                          res[3], res[4],
1732                                                          res[5], res[6],
1733                                                          res[7]));
1734                                        }
1735                                }
1736                        }       /* interface */
1737                }               /* search */
1738        }                       /* pattern */
1739
1740        ddr3_tip_load_phy_values(0);
1741
1742        return MV_OK;
1743}
1744
1745int mv_ddr_pattern_start_addr_set(struct pattern_info *pattern_tbl, enum hws_pattern pattern, u32 addr)
1746{
1747        pattern_tbl[pattern].start_addr = addr;
1748
1749        return 0;
1750}
1751
1752struct pattern_info *ddr3_tip_get_pattern_table()
1753{
1754        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1755
1756        if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask))
1757                return pattern_table_64;
1758        else if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
1759                return pattern_table_32;
1760        else
1761                return pattern_table_16;
1762}
1763
1764u16 *ddr3_tip_get_mask_results_dq_reg()
1765{
1766#if MAX_BUS_NUM == 5
1767        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1768
1769        if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1770                return mask_results_dq_reg_map_pup3_ecc;
1771        else
1772#endif
1773                return mask_results_dq_reg_map;
1774}
1775
1776u16 *ddr3_tip_get_mask_results_pup_reg_map()
1777{
1778#if MAX_BUS_NUM == 5
1779        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1780
1781        if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
1782                return mask_results_pup_reg_map_pup3_ecc;
1783        else
1784#endif
1785                return mask_results_pup_reg_map;
1786}
1787
1788/* load expected dm pattern to odpg */
1789#define LOW_NIBBLE_BYTE_MASK    0xf
1790#define HIGH_NIBBLE_BYTE_MASK   0xf0
1791int mv_ddr_load_dm_pattern_to_odpg(enum hws_access_type access_type, enum hws_pattern pattern,
1792                                   enum dm_direction dm_dir)
1793{
1794        struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
1795        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
1796        u32 pattern_len = 0;
1797        u32 data_low, data_high;
1798        u8 dm_data;
1799
1800        for (pattern_len = 0;
1801             pattern_len < pattern_table[pattern].pattern_len;
1802             pattern_len++) {
1803                if (MV_DDR_IS_64BIT_DRAM_MODE(tm->bus_act_mask)) {
1804                        data_low = pattern_table_get_word(0, pattern, (u8)pattern_len);
1805                        data_high = data_low;
1806                } else {
1807                        data_low = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2));
1808                        data_high = pattern_table_get_word(0, pattern, (u8)(pattern_len * 2 + 1));
1809                }
1810
1811                /* odpg mbus dm definition is opposite to ddr4 protocol */
1812                if (dm_dir == DM_DIR_INVERSE)
1813                        dm_data = ~((data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK));
1814                else
1815                        dm_data = (data_low & LOW_NIBBLE_BYTE_MASK) | (data_high & HIGH_NIBBLE_BYTE_MASK);
1816
1817                ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_LOW_REG, data_low, MASK_ALL_BITS);
1818                ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_DATA_HIGH_REG, data_high, MASK_ALL_BITS);
1819                ddr3_tip_if_write(0, access_type, 0, ODPG_DATA_WR_ADDR_REG,
1820                                  pattern_len | ((dm_data & ODPG_DATA_WR_DATA_MASK) << ODPG_DATA_WR_DATA_OFFS),
1821                                  MASK_ALL_BITS);
1822        }
1823
1824        return MV_OK;
1825}
1826