uboot/drivers/ddr/marvell/a38x/ddr3_training_db.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) Marvell International Ltd. and its affiliates
   4 */
   5
   6#include "ddr_ml_wrapper.h"
   7
   8#include "ddr3_training_ip_flow.h"
   9#include "mv_ddr_topology.h"
  10#include "mv_ddr_training_db.h"
  11#include "ddr3_training_ip_db.h"
  12
  13/* Device attributes structures */
  14enum mv_ddr_dev_attribute ddr_dev_attributes[MV_ATTR_LAST];
  15int ddr_dev_attr_init_done = 0;
  16
  17static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index);
  18static inline u32 pattern_table_get_sso_word(u8 sso, u8 index);
  19static inline u32 pattern_table_get_vref_word(u8 index);
  20static inline u32 pattern_table_get_vref_word16(u8 index);
  21static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index);
  22static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index);
  23static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index);
  24static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index);
  25static inline u32 pattern_table_get_isi_word(u8 index);
  26static inline u32 pattern_table_get_isi_word16(u8 index);
  27
  28/* List of allowed frequency listed in order of enum mv_ddr_freq */
  29static unsigned int freq_val[MV_DDR_FREQ_LAST] = {
  30        0,                      /*MV_DDR_FREQ_LOW_FREQ */
  31        400,                    /*MV_DDR_FREQ_400, */
  32        533,                    /*MV_DDR_FREQ_533, */
  33        666,                    /*MV_DDR_FREQ_667, */
  34        800,                    /*MV_DDR_FREQ_800, */
  35        933,                    /*MV_DDR_FREQ_933, */
  36        1066,                   /*MV_DDR_FREQ_1066, */
  37        311,                    /*MV_DDR_FREQ_311, */
  38        333,                    /*MV_DDR_FREQ_333, */
  39        467,                    /*MV_DDR_FREQ_467, */
  40        850,                    /*MV_DDR_FREQ_850, */
  41        600,                    /*MV_DDR_FREQ_600 */
  42        300,                    /*MV_DDR_FREQ_300 */
  43        900,                    /*MV_DDR_FREQ_900 */
  44        360,                    /*MV_DDR_FREQ_360 */
  45        1000                    /*MV_DDR_FREQ_1000 */
  46};
  47
  48unsigned int *mv_ddr_freq_tbl_get(void)
  49{
  50        return &freq_val[0];
  51}
  52
  53u32 mv_ddr_freq_get(enum mv_ddr_freq freq)
  54{
  55        return freq_val[freq];
  56}
  57
  58/* cas latency values per frequency for each speed bin index */
  59static struct mv_ddr_cl_val_per_freq cl_table[] = {
  60        /*
  61         * 400M   667M     933M   311M     467M  600M    360
  62         * 100M    533M    800M    1066M   333M    850M      900
  63         * 1000 (the order is 100, 400, 533 etc.)
  64         */
  65        /* DDR3-800D */
  66        { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
  67        /* DDR3-800E */
  68        { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
  69        /* DDR3-1066E */
  70        { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
  71        /* DDR3-1066F */
  72        { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
  73        /* DDR3-1066G */
  74        { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
  75        /* DDR3-1333F* */
  76        { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
  77        /* DDR3-1333G */
  78        { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
  79        /* DDR3-1333H */
  80        { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
  81        /* DDR3-1333J* */
  82        { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6,  0}
  83         /* DDR3-1600G* */},
  84        { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
  85        /* DDR3-1600H */
  86        { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
  87        /* DDR3-1600J */
  88        { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
  89        /* DDR3-1600K */
  90        { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
  91        /* DDR3-1866J* */
  92        { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
  93        /* DDR3-1866K */
  94        { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
  95        /* DDR3-1866L */
  96        { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
  97        /* DDR3-1866M* */
  98        { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
  99        /* DDR3-2133K* */
 100        { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
 101        /* DDR3-2133L */
 102        { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
 103        /* DDR3-2133M */
 104        { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
 105        /* DDR3-2133N* */
 106        { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14,  6, 14} },
 107        /* DDR3-1333H-ext */
 108        { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
 109        /* DDR3-1600K-ext */
 110        { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
 111        /* DDR3-1866M-ext */
 112        { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
 113};
 114
 115u32 mv_ddr_cl_val_get(u32 index, u32 freq)
 116{
 117        return cl_table[index].cl_val[freq];
 118}
 119
 120/* cas write latency values per frequency for each speed bin index */
 121static struct mv_ddr_cl_val_per_freq cwl_table[] = {
 122        /*
 123         * 400M   667M     933M   311M     467M  600M    360
 124         * 100M    533M    800M    1066M   333M    850M      900
 125         * (the order is 100, 400, 533 etc.)
 126         */
 127        /* DDR3-800D  */
 128        { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
 129        /* DDR3-800E  */
 130        { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
 131        /* DDR3-1066E  */
 132        { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 133        /* DDR3-1066F  */
 134        { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 135        /* DDR3-1066G  */
 136        { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 137        /* DDR3-1333F*  */
 138        { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 139        /* DDR3-1333G  */
 140        { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 141        /* DDR3-1333H  */
 142        { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 143        /* DDR3-1333J*  */
 144        { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 145        /* DDR3-1600G*  */
 146        { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 147        /* DDR3-1600H  */
 148        { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 149        /* DDR3-1600J  */
 150        { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 151        /* DDR3-1600K  */
 152        { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 153        /* DDR3-1866J*  */
 154        { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
 155        /* DDR3-1866K  */
 156        { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
 157        /* DDR3-1866L  */
 158        { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 159        /* DDR3-1866M*   */
 160        { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 161        /* DDR3-2133K*  */
 162        { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 163        /* DDR3-2133L  */
 164        { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 165        /* DDR3-2133M  */
 166        { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 167        /* DDR3-2133N*  */
 168        { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
 169        /* DDR3-1333H-ext  */
 170        { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 171        /* DDR3-1600K-ext  */
 172        { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
 173        /* DDR3-1866M-ext  */
 174        { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
 175};
 176
 177u32 mv_ddr_cwl_val_get(u32 index, u32 freq)
 178{
 179        return cwl_table[index].cl_val[freq];
 180}
 181
 182u8 twr_mask_table[] = {
 183        10,
 184        10,
 185        10,
 186        10,
 187        10,
 188        1,                      /* 5 */
 189        2,                      /* 6 */
 190        3,                      /* 7 */
 191        4,                      /* 8 */
 192        10,
 193        5,                      /* 10 */
 194        10,
 195        6,                      /* 12 */
 196        10,
 197        7,                      /* 14 */
 198        10,
 199        0                       /* 16 */
 200};
 201
 202u8 cl_mask_table[] = {
 203        0,
 204        0,
 205        0,
 206        0,
 207        0,
 208        0x2,
 209        0x4,
 210        0x6,
 211        0x8,
 212        0xa,
 213        0xc,
 214        0xe,
 215        0x1,
 216        0x3,
 217        0x5,
 218        0x5
 219};
 220
 221u8 cwl_mask_table[] = {
 222        0,
 223        0,
 224        0,
 225        0,
 226        0,
 227        0,
 228        0x1,
 229        0x2,
 230        0x3,
 231        0x4,
 232        0x5,
 233        0x6,
 234        0x7,
 235        0x8,
 236        0x9,
 237        0x9
 238};
 239
 240/* RFC values (in ns) */
 241static unsigned int rfc_table[] = {
 242        90,     /* 512M */
 243        110,    /* 1G */
 244        160,    /* 2G */
 245        260,    /* 4G */
 246        350,    /* 8G */
 247        0,      /* TODO: placeholder for 16-Mbit dev width */
 248        0,      /* TODO: placeholder for 32-Mbit dev width */
 249        0,      /* TODO: placeholder for 12-Mbit dev width */
 250        0       /* TODO: placeholder for 24-Mbit dev width */
 251};
 252
 253u32 mv_ddr_rfc_get(u32 mem)
 254{
 255        return rfc_table[mem];
 256}
 257
 258u32 speed_bin_table_t_rc[] = {
 259        50000,
 260        52500,
 261        48750,
 262        50625,
 263        52500,
 264        46500,
 265        48000,
 266        49500,
 267        51000,
 268        45000,
 269        46250,
 270        47500,
 271        48750,
 272        44700,
 273        45770,
 274        46840,
 275        47910,
 276        43285,
 277        44220,
 278        45155,
 279        46090
 280};
 281
 282u32 speed_bin_table_t_rcd_t_rp[] = {
 283        12500,
 284        15000,
 285        11250,
 286        13125,
 287        15000,
 288        10500,
 289        12000,
 290        13500,
 291        15000,
 292        10000,
 293        11250,
 294        12500,
 295        13750,
 296        10700,
 297        11770,
 298        12840,
 299        13910,
 300        10285,
 301        11220,
 302        12155,
 303        13090,
 304};
 305
 306enum {
 307        PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
 308        PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
 309};
 310
 311static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
 312        /*Aggressor / Victim */
 313        {1, 0},
 314        {0, 0},
 315        {1, 0},
 316        {1, 1},
 317        {0, 1},
 318        {0, 1},
 319        {1, 0},
 320        {0, 1},
 321        {1, 0},
 322        {0, 1},
 323        {1, 0},
 324        {1, 0},
 325        {0, 1},
 326        {1, 0},
 327        {0, 1},
 328        {0, 0},
 329        {1, 1},
 330        {0, 0},
 331        {1, 1},
 332        {0, 0},
 333        {1, 1},
 334        {0, 0},
 335        {1, 1},
 336        {1, 0},
 337        {0, 0},
 338        {1, 1},
 339        {0, 0},
 340        {1, 1},
 341        {0, 0},
 342        {0, 0},
 343        {0, 0},
 344        {0, 1},
 345        {0, 1},
 346        {1, 1},
 347        {0, 0},
 348        {0, 0},
 349        {1, 1},
 350        {1, 1},
 351        {0, 0},
 352        {1, 1},
 353        {0, 0},
 354        {1, 1},
 355        {1, 1},
 356        {0, 0},
 357        {0, 0},
 358        {1, 1},
 359        {0, 0},
 360        {1, 1},
 361        {0, 1},
 362        {0, 0},
 363        {0, 1},
 364        {0, 1},
 365        {0, 0},
 366        {1, 1},
 367        {1, 1},
 368        {1, 0},
 369        {1, 0},
 370        {1, 1},
 371        {1, 1},
 372        {1, 1},
 373        {1, 1},
 374        {1, 1},
 375        {1, 1},
 376        {1, 1}
 377};
 378
 379static u8 pattern_vref_pattern_table_map[] = {
 380        /* 1 means 0xffffffff, 0 is 0x0 */
 381        0xb8,
 382        0x52,
 383        0x55,
 384        0x8a,
 385        0x33,
 386        0xa6,
 387        0x6d,
 388        0xfe
 389};
 390
 391static struct mv_ddr_page_element page_tbl[] = {
 392        /* 8-bit, 16-bit page size */
 393        {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 512M */
 394        {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 1G */
 395        {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 2G */
 396        {MV_DDR_PAGE_SIZE_1K, MV_DDR_PAGE_SIZE_2K}, /* 4G */
 397        {MV_DDR_PAGE_SIZE_2K, MV_DDR_PAGE_SIZE_2K}, /* 8G */
 398        {0, 0}, /* TODO: placeholder for 16-Mbit die capacity */
 399        {0, 0}, /* TODO: placeholder for 32-Mbit die capacity */
 400        {0, 0}, /* TODO: placeholder for 12-Mbit die capacity */
 401        {0, 0}  /* TODO: placeholder for 24-Mbit die capacity */
 402};
 403
 404u32 mv_ddr_page_size_get(enum mv_ddr_dev_width bus_width, enum mv_ddr_die_capacity mem_size)
 405{
 406        if (bus_width == MV_DDR_DEV_WIDTH_8BIT)
 407                return page_tbl[mem_size].page_size_8bit;
 408        else
 409                return page_tbl[mem_size].page_size_16bit;
 410}
 411
 412/* Return speed Bin value for selected index and t* element */
 413unsigned int mv_ddr_speed_bin_timing_get(enum mv_ddr_speed_bin index, enum mv_ddr_speed_bin_timing element)
 414{
 415        u32 result = 0;
 416
 417        switch (element) {
 418        case SPEED_BIN_TRCD:
 419        case SPEED_BIN_TRP:
 420                result = speed_bin_table_t_rcd_t_rp[index];
 421                break;
 422        case SPEED_BIN_TRAS:
 423                if (index <= SPEED_BIN_DDR_1066G)
 424                        result = 37500;
 425                else if (index <= SPEED_BIN_DDR_1333J)
 426                        result = 36000;
 427                else if (index <= SPEED_BIN_DDR_1600K)
 428                        result = 35000;
 429                else if (index <= SPEED_BIN_DDR_1866M)
 430                        result = 34000;
 431                else
 432                        result = 33000;
 433                break;
 434        case SPEED_BIN_TRC:
 435                result = speed_bin_table_t_rc[index];
 436                break;
 437        case SPEED_BIN_TRRD1K:
 438                if (index <= SPEED_BIN_DDR_800E)
 439                        result = 10000;
 440                else if (index <= SPEED_BIN_DDR_1066G)
 441                        result = 7500;
 442                else if (index <= SPEED_BIN_DDR_1600K)
 443                        result = 6000;
 444                else
 445                        result = 5000;
 446                break;
 447        case SPEED_BIN_TRRD2K:
 448                if (index <= SPEED_BIN_DDR_1066G)
 449                        result = 10000;
 450                else if (index <= SPEED_BIN_DDR_1600K)
 451                        result = 7500;
 452                else
 453                        result = 6000;
 454                break;
 455        case SPEED_BIN_TPD:
 456                if (index < SPEED_BIN_DDR_800E)
 457                        result = 7500;
 458                else if (index < SPEED_BIN_DDR_1333J)
 459                        result = 5625;
 460                else
 461                        result = 5000;
 462                break;
 463        case SPEED_BIN_TFAW1K:
 464                if (index <= SPEED_BIN_DDR_800E)
 465                        result = 40000;
 466                else if (index <= SPEED_BIN_DDR_1066G)
 467                        result = 37500;
 468                else if (index <= SPEED_BIN_DDR_1600K)
 469                        result = 30000;
 470                else if (index <= SPEED_BIN_DDR_1866M)
 471                        result = 27000;
 472                else
 473                        result = 25000;
 474                break;
 475        case SPEED_BIN_TFAW2K:
 476                if (index <= SPEED_BIN_DDR_1066G)
 477                        result = 50000;
 478                else if (index <= SPEED_BIN_DDR_1333J)
 479                        result = 45000;
 480                else if (index <= SPEED_BIN_DDR_1600K)
 481                        result = 40000;
 482                else
 483                        result = 35000;
 484                break;
 485        case SPEED_BIN_TWTR:
 486                result = 7500;
 487                break;
 488        case SPEED_BIN_TRTP:
 489                result = 7500;
 490                break;
 491        case SPEED_BIN_TWR:
 492                result = 15000;
 493                break;
 494        case SPEED_BIN_TMOD:
 495                result = 15000;
 496                break;
 497        case SPEED_BIN_TXPDLL:
 498                result = 24000;
 499                break;
 500        case SPEED_BIN_TXSDLL:
 501                result = 512;
 502                break;
 503        default:
 504                break;
 505        }
 506
 507        return result;
 508}
 509
 510static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
 511{
 512        u8 i, byte = 0;
 513        u8 role;
 514
 515        for (i = 0; i < 8; i++) {
 516                role = (i == dqs) ?
 517                        (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
 518                        (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
 519                byte |= pattern_killer_pattern_table_map[index][role] << i;
 520        }
 521
 522        return byte | (byte << 8) | (byte << 16) | (byte << 24);
 523}
 524
 525static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
 526{
 527        u8 i, byte0 = 0, byte1 = 0;
 528        u8 role;
 529
 530        for (i = 0; i < 8; i++) {
 531                role = (i == dqs) ?
 532                        (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
 533                        (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
 534                byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
 535                byte1 |= pattern_killer_pattern_table_map[index * 2 + 1][role] << i;
 536        }
 537
 538        return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
 539}
 540
 541static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
 542{
 543        u8 step = sso + 1;
 544
 545        if (0 == ((index / step) & 1))
 546                return 0x0;
 547        else
 548                return 0xffffffff;
 549}
 550
 551static inline u32 pattern_table_get_sso_full_xtalk_word(u8 bit, u8 index)
 552{
 553        u8 byte = (1 << bit);
 554
 555        if ((index & 1) == 1)
 556                byte = ~byte;
 557
 558        return byte | (byte << 8) | (byte << 16) | (byte << 24);
 559
 560}
 561
 562static inline u32 pattern_table_get_sso_xtalk_free_word(u8 bit, u8 index)
 563{
 564        u8 byte = (1 << bit);
 565
 566        if ((index & 1) == 1)
 567                byte = 0;
 568
 569        return byte | (byte << 8) | (byte << 16) | (byte << 24);
 570}
 571
 572static inline u32 pattern_table_get_isi_word(u8 index)
 573{
 574        u8 i0 = index % 32;
 575        u8 i1 = index % 8;
 576        u32 word;
 577
 578        if (i0 > 15)
 579                word = ((i1 == 5) | (i1 == 7)) ? 0xffffffff : 0x0;
 580        else
 581                word = (i1 == 6) ? 0xffffffff : 0x0;
 582
 583        word = ((i0 % 16) > 7) ? ~word : word;
 584
 585        return word;
 586}
 587
 588static inline u32 pattern_table_get_sso_full_xtalk_word16(u8 bit, u8 index)
 589{
 590        u8 byte = (1 << bit);
 591
 592        if ((index & 1) == 1)
 593                byte = ~byte;
 594
 595        return byte | (byte << 8) | ((~byte) << 16) | ((~byte) << 24);
 596}
 597
 598static inline u32 pattern_table_get_sso_xtalk_free_word16(u8 bit, u8 index)
 599{
 600        u8 byte = (1 << bit);
 601
 602        if ((index & 1) == 0)
 603                return (byte << 16) | (byte << 24);
 604        else
 605                return byte | (byte << 8);
 606}
 607
 608static inline u32 pattern_table_get_isi_word16(u8 index)
 609{
 610        u8 i0 = index % 16;
 611        u8 i1 = index % 4;
 612        u32 word;
 613
 614        if (i0 > 7)
 615                word = (i1 > 1) ? 0x0000ffff : 0x0;
 616        else
 617                word = (i1 == 3) ? 0xffff0000 : 0x0;
 618
 619        word = ((i0 % 8) > 3) ? ~word : word;
 620
 621        return word;
 622}
 623
 624static inline u32 pattern_table_get_vref_word(u8 index)
 625{
 626        if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
 627                   (index % 8)) & 1))
 628                return 0x0;
 629        else
 630                return 0xffffffff;
 631}
 632
 633static inline u32 pattern_table_get_vref_word16(u8 index)
 634{
 635        if (0 == pattern_killer_pattern_table_map
 636            [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 637            0 == pattern_killer_pattern_table_map
 638            [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 639                return 0x00000000;
 640        else if (1 == pattern_killer_pattern_table_map
 641                 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 642                 0 == pattern_killer_pattern_table_map
 643                 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 644                return 0xffff0000;
 645        else if (0 == pattern_killer_pattern_table_map
 646                 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
 647                 1 == pattern_killer_pattern_table_map
 648                 [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
 649                return 0x0000ffff;
 650        else
 651                return 0xffffffff;
 652}
 653
 654static inline u32 pattern_table_get_static_pbs_word(u8 index)
 655{
 656        u16 temp;
 657
 658        temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
 659
 660        return temp | (temp << 8) | (temp << 16) | (temp << 24);
 661}
 662
 663u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
 664{
 665        u32 pattern = 0;
 666        struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
 667
 668        if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
 669                /* 32/64-bit patterns */
 670                switch (type) {
 671                case PATTERN_PBS1:
 672                case PATTERN_PBS2:
 673                        if (index == 0 || index == 2 || index == 5 ||
 674                            index == 7)
 675                                pattern = PATTERN_55;
 676                        else
 677                                pattern = PATTERN_AA;
 678                        break;
 679                case PATTERN_PBS3:
 680                        if (0 == (index & 1))
 681                                pattern = PATTERN_55;
 682                        else
 683                                pattern = PATTERN_AA;
 684                        break;
 685                case PATTERN_RL:
 686                        if (index < 6)
 687                                pattern = PATTERN_00;
 688                        else
 689                                pattern = PATTERN_80;
 690                        break;
 691                case PATTERN_STATIC_PBS:
 692                        pattern = pattern_table_get_static_pbs_word(index);
 693                        break;
 694                case PATTERN_KILLER_DQ0:
 695                case PATTERN_KILLER_DQ1:
 696                case PATTERN_KILLER_DQ2:
 697                case PATTERN_KILLER_DQ3:
 698                case PATTERN_KILLER_DQ4:
 699                case PATTERN_KILLER_DQ5:
 700                case PATTERN_KILLER_DQ6:
 701                case PATTERN_KILLER_DQ7:
 702                        pattern = pattern_table_get_killer_word(
 703                                (u8)(type - PATTERN_KILLER_DQ0), index);
 704                        break;
 705                case PATTERN_RL2:
 706                        if (index < 6)
 707                                pattern = PATTERN_00;
 708                        else
 709                                pattern = PATTERN_01;
 710                        break;
 711                case PATTERN_TEST:
 712                        if (index > 1 && index < 6)
 713                                pattern = PATTERN_00;
 714                        else
 715                                pattern = PATTERN_FF;
 716                        break;
 717                case PATTERN_FULL_SSO0:
 718                case PATTERN_FULL_SSO1:
 719                case PATTERN_FULL_SSO2:
 720                case PATTERN_FULL_SSO3:
 721                        pattern = pattern_table_get_sso_word(
 722                                (u8)(type - PATTERN_FULL_SSO0), index);
 723                        break;
 724                case PATTERN_VREF:
 725                        pattern = pattern_table_get_vref_word(index);
 726                        break;
 727                case PATTERN_SSO_FULL_XTALK_DQ0:
 728                case PATTERN_SSO_FULL_XTALK_DQ1:
 729                case PATTERN_SSO_FULL_XTALK_DQ2:
 730                case PATTERN_SSO_FULL_XTALK_DQ3:
 731                case PATTERN_SSO_FULL_XTALK_DQ4:
 732                case PATTERN_SSO_FULL_XTALK_DQ5:
 733                case PATTERN_SSO_FULL_XTALK_DQ6:
 734                case PATTERN_SSO_FULL_XTALK_DQ7:
 735                        pattern = pattern_table_get_sso_full_xtalk_word(
 736                                (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
 737                        break;
 738                case PATTERN_SSO_XTALK_FREE_DQ0:
 739                case PATTERN_SSO_XTALK_FREE_DQ1:
 740                case PATTERN_SSO_XTALK_FREE_DQ2:
 741                case PATTERN_SSO_XTALK_FREE_DQ3:
 742                case PATTERN_SSO_XTALK_FREE_DQ4:
 743                case PATTERN_SSO_XTALK_FREE_DQ5:
 744                case PATTERN_SSO_XTALK_FREE_DQ6:
 745                case PATTERN_SSO_XTALK_FREE_DQ7:
 746                        pattern = pattern_table_get_sso_xtalk_free_word(
 747                                (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
 748                        break;
 749                case PATTERN_ISI_XTALK_FREE:
 750                        pattern = pattern_table_get_isi_word(index);
 751                        break;
 752                default:
 753                        printf("error: %s: unsupported pattern type [%d] found\n",
 754                               __func__, (int)type);
 755                        pattern = 0;
 756                        break;
 757                }
 758        } else {
 759                /* 16bit patterns */
 760                switch (type) {
 761                case PATTERN_PBS1:
 762                case PATTERN_PBS2:
 763                case PATTERN_PBS3:
 764                        pattern = PATTERN_55AA;
 765                        break;
 766                case PATTERN_RL:
 767                        if (index < 3)
 768                                pattern = PATTERN_00;
 769                        else
 770                                pattern = PATTERN_80;
 771                        break;
 772                case PATTERN_STATIC_PBS:
 773                        pattern = PATTERN_00FF;
 774                        break;
 775                case PATTERN_KILLER_DQ0:
 776                case PATTERN_KILLER_DQ1:
 777                case PATTERN_KILLER_DQ2:
 778                case PATTERN_KILLER_DQ3:
 779                case PATTERN_KILLER_DQ4:
 780                case PATTERN_KILLER_DQ5:
 781                case PATTERN_KILLER_DQ6:
 782                case PATTERN_KILLER_DQ7:
 783                        pattern = pattern_table_get_killer_word16(
 784                                (u8)(type - PATTERN_KILLER_DQ0), index);
 785                        break;
 786                case PATTERN_RL2:
 787                        if (index < 3)
 788                                pattern = PATTERN_00;
 789                        else
 790                                pattern = PATTERN_01;
 791                        break;
 792                case PATTERN_TEST:
 793                        if ((index == 0) || (index == 3))
 794                                pattern = 0x00000000;
 795                        else
 796                                pattern = 0xFFFFFFFF;
 797                        break;
 798                case PATTERN_FULL_SSO0:
 799                        pattern = 0x0000ffff;
 800                        break;
 801                case PATTERN_FULL_SSO1:
 802                case PATTERN_FULL_SSO2:
 803                case PATTERN_FULL_SSO3:
 804                        pattern = pattern_table_get_sso_word(
 805                                (u8)(type - PATTERN_FULL_SSO1), index);
 806                        break;
 807                case PATTERN_VREF:
 808                        pattern = pattern_table_get_vref_word16(index);
 809                        break;
 810                case PATTERN_SSO_FULL_XTALK_DQ0:
 811                case PATTERN_SSO_FULL_XTALK_DQ1:
 812                case PATTERN_SSO_FULL_XTALK_DQ2:
 813                case PATTERN_SSO_FULL_XTALK_DQ3:
 814                case PATTERN_SSO_FULL_XTALK_DQ4:
 815                case PATTERN_SSO_FULL_XTALK_DQ5:
 816                case PATTERN_SSO_FULL_XTALK_DQ6:
 817                case PATTERN_SSO_FULL_XTALK_DQ7:
 818                        pattern = pattern_table_get_sso_full_xtalk_word16(
 819                                (u8)(type - PATTERN_SSO_FULL_XTALK_DQ0), index);
 820                        break;
 821                case PATTERN_SSO_XTALK_FREE_DQ0:
 822                case PATTERN_SSO_XTALK_FREE_DQ1:
 823                case PATTERN_SSO_XTALK_FREE_DQ2:
 824                case PATTERN_SSO_XTALK_FREE_DQ3:
 825                case PATTERN_SSO_XTALK_FREE_DQ4:
 826                case PATTERN_SSO_XTALK_FREE_DQ5:
 827                case PATTERN_SSO_XTALK_FREE_DQ6:
 828                case PATTERN_SSO_XTALK_FREE_DQ7:
 829                        pattern = pattern_table_get_sso_xtalk_free_word16(
 830                                (u8)(type - PATTERN_SSO_XTALK_FREE_DQ0), index);
 831                        break;
 832                case PATTERN_ISI_XTALK_FREE:
 833                        pattern = pattern_table_get_isi_word16(index);
 834                        break;
 835                default:
 836                        if (((int)type == 29) || ((int)type == 30))
 837                                break;
 838
 839                        printf("error: %s: unsupported pattern type [%d] found\n",
 840                               __func__, (int)type);
 841                        pattern = 0;
 842                        break;
 843                }
 844        }
 845
 846        return pattern;
 847}
 848
 849/* Device attribute functions */
 850void ddr3_tip_dev_attr_init(u32 dev_num)
 851{
 852        u32 attr_id;
 853
 854        for (attr_id = 0; attr_id < MV_ATTR_LAST; attr_id++)
 855                ddr_dev_attributes[attr_id] = 0xFF;
 856
 857        ddr_dev_attr_init_done = 1;
 858}
 859
 860u32 ddr3_tip_dev_attr_get(u32 dev_num, enum mv_ddr_dev_attribute attr_id)
 861{
 862        if (ddr_dev_attr_init_done == 0)
 863                ddr3_tip_dev_attr_init(dev_num);
 864
 865        return ddr_dev_attributes[attr_id];
 866}
 867
 868void ddr3_tip_dev_attr_set(u32 dev_num, enum mv_ddr_dev_attribute attr_id, u32 value)
 869{
 870        if (ddr_dev_attr_init_done == 0)
 871                ddr3_tip_dev_attr_init(dev_num);
 872
 873        ddr_dev_attributes[attr_id] = value;
 874}
 875