linux/drivers/gpu/drm/ast/ast_post.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Red Hat Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the
   6 * "Software"), to deal in the Software without restriction, including
   7 * without limitation the rights to use, copy, modify, merge, publish,
   8 * distribute, sub license, and/or sell copies of the Software, and to
   9 * permit persons to whom the Software is furnished to do so, subject to
  10 * the following conditions:
  11 *
  12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  15 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  17 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  18 * USE OR OTHER DEALINGS IN THE SOFTWARE.
  19 *
  20 * The above copyright notice and this permission notice (including the
  21 * next paragraph) shall be included in all copies or substantial portions
  22 * of the Software.
  23 *
  24 */
  25/*
  26 * Authors: Dave Airlie <airlied@redhat.com>
  27 */
  28
  29#include <drm/drmP.h>
  30#include "ast_drv.h"
  31
  32#include "ast_dram_tables.h"
  33
  34static void ast_init_dram_2300(struct drm_device *dev);
  35
  36static void
  37ast_enable_vga(struct drm_device *dev)
  38{
  39        struct ast_private *ast = dev->dev_private;
  40
  41        ast_io_write8(ast, 0x43, 0x01);
  42        ast_io_write8(ast, 0x42, 0x01);
  43}
  44
  45#if 0 /* will use later */
  46static bool
  47ast_is_vga_enabled(struct drm_device *dev)
  48{
  49        struct ast_private *ast = dev->dev_private;
  50        u8 ch;
  51
  52        if (ast->chip == AST1180) {
  53                /* TODO 1180 */
  54        } else {
  55                ch = ast_io_read8(ast, 0x43);
  56                if (ch) {
  57                        ast_open_key(ast);
  58                        ch = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff);
  59                        return ch & 0x04;
  60                }
  61        }
  62        return 0;
  63}
  64#endif
  65
  66static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
  67static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
  68static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
  69
  70static void
  71ast_set_def_ext_reg(struct drm_device *dev)
  72{
  73        struct ast_private *ast = dev->dev_private;
  74        u8 i, index, reg;
  75        const u8 *ext_reg_info;
  76
  77        /* reset scratch */
  78        for (i = 0x81; i <= 0x8f; i++)
  79                ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00);
  80
  81        if (ast->chip == AST2300) {
  82                if (dev->pdev->revision >= 0x20)
  83                        ext_reg_info = extreginfo_ast2300;
  84                else
  85                        ext_reg_info = extreginfo_ast2300a0;
  86        } else
  87                ext_reg_info = extreginfo;
  88
  89        index = 0xa0;
  90        while (*ext_reg_info != 0xff) {
  91                ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info);
  92                index++;
  93                ext_reg_info++;
  94        }
  95
  96        /* disable standard IO/MEM decode if secondary */
  97        /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */
  98
  99        /* Set Ext. Default */
 100        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01);
 101        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00);
 102
 103        /* Enable RAMDAC for A1 */
 104        reg = 0x04;
 105        if (ast->chip == AST2300)
 106                reg |= 0x20;
 107        ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg);
 108}
 109
 110static inline u32 mindwm(struct ast_private *ast, u32 r)
 111{
 112        ast_write32(ast, 0xf004, r & 0xffff0000);
 113        ast_write32(ast, 0xf000, 0x1);
 114
 115        return ast_read32(ast, 0x10000 + (r & 0x0000ffff));
 116}
 117
 118static inline void moutdwm(struct ast_private *ast, u32 r, u32 v)
 119{
 120        ast_write32(ast, 0xf004, r & 0xffff0000);
 121        ast_write32(ast, 0xf000, 0x1);
 122        ast_write32(ast, 0x10000 + (r & 0x0000ffff), v);
 123}
 124
 125/*
 126 * AST2100/2150 DLL CBR Setting
 127 */
 128#define CBR_SIZE_AST2150             ((16 << 10) - 1)
 129#define CBR_PASSNUM_AST2150          5
 130#define CBR_THRESHOLD_AST2150        10
 131#define CBR_THRESHOLD2_AST2150       10
 132#define TIMEOUT_AST2150              5000000
 133
 134#define CBR_PATNUM_AST2150           8
 135
 136static const u32 pattern_AST2150[14] = {
 137        0xFF00FF00,
 138        0xCC33CC33,
 139        0xAA55AA55,
 140        0xFFFE0001,
 141        0x683501FE,
 142        0x0F1929B0,
 143        0x2D0B4346,
 144        0x60767F02,
 145        0x6FBE36A6,
 146        0x3A253035,
 147        0x3019686D,
 148        0x41C6167E,
 149        0x620152BF,
 150        0x20F050E0
 151};
 152
 153static u32 mmctestburst2_ast2150(struct ast_private *ast, u32 datagen)
 154{
 155        u32 data, timeout;
 156
 157        moutdwm(ast, 0x1e6e0070, 0x00000000);
 158        moutdwm(ast, 0x1e6e0070, 0x00000001 | (datagen << 3));
 159        timeout = 0;
 160        do {
 161                data = mindwm(ast, 0x1e6e0070) & 0x40;
 162                if (++timeout > TIMEOUT_AST2150) {
 163                        moutdwm(ast, 0x1e6e0070, 0x00000000);
 164                        return 0xffffffff;
 165                }
 166        } while (!data);
 167        moutdwm(ast, 0x1e6e0070, 0x00000000);
 168        moutdwm(ast, 0x1e6e0070, 0x00000003 | (datagen << 3));
 169        timeout = 0;
 170        do {
 171                data = mindwm(ast, 0x1e6e0070) & 0x40;
 172                if (++timeout > TIMEOUT_AST2150) {
 173                        moutdwm(ast, 0x1e6e0070, 0x00000000);
 174                        return 0xffffffff;
 175                }
 176        } while (!data);
 177        data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
 178        moutdwm(ast, 0x1e6e0070, 0x00000000);
 179        return data;
 180}
 181
 182#if 0 /* unused in DDX driver - here for completeness */
 183static u32 mmctestsingle2_ast2150(struct ast_private *ast, u32 datagen)
 184{
 185        u32 data, timeout;
 186
 187        moutdwm(ast, 0x1e6e0070, 0x00000000);
 188        moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
 189        timeout = 0;
 190        do {
 191                data = mindwm(ast, 0x1e6e0070) & 0x40;
 192                if (++timeout > TIMEOUT_AST2150) {
 193                        moutdwm(ast, 0x1e6e0070, 0x00000000);
 194                        return 0xffffffff;
 195                }
 196        } while (!data);
 197        data = (mindwm(ast, 0x1e6e0070) & 0x80) >> 7;
 198        moutdwm(ast, 0x1e6e0070, 0x00000000);
 199        return data;
 200}
 201#endif
 202
 203static int cbrtest_ast2150(struct ast_private *ast)
 204{
 205        int i;
 206
 207        for (i = 0; i < 8; i++)
 208                if (mmctestburst2_ast2150(ast, i))
 209                        return 0;
 210        return 1;
 211}
 212
 213static int cbrscan_ast2150(struct ast_private *ast, int busw)
 214{
 215        u32 patcnt, loop;
 216
 217        for (patcnt = 0; patcnt < CBR_PATNUM_AST2150; patcnt++) {
 218                moutdwm(ast, 0x1e6e007c, pattern_AST2150[patcnt]);
 219                for (loop = 0; loop < CBR_PASSNUM_AST2150; loop++) {
 220                        if (cbrtest_ast2150(ast))
 221                                break;
 222                }
 223                if (loop == CBR_PASSNUM_AST2150)
 224                        return 0;
 225        }
 226        return 1;
 227}
 228
 229
 230static void cbrdlli_ast2150(struct ast_private *ast, int busw)
 231{
 232        u32 dll_min[4], dll_max[4], dlli, data, passcnt;
 233
 234cbr_start:
 235        dll_min[0] = dll_min[1] = dll_min[2] = dll_min[3] = 0xff;
 236        dll_max[0] = dll_max[1] = dll_max[2] = dll_max[3] = 0x0;
 237        passcnt = 0;
 238
 239        for (dlli = 0; dlli < 100; dlli++) {
 240                moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
 241                data = cbrscan_ast2150(ast, busw);
 242                if (data != 0) {
 243                        if (data & 0x1) {
 244                                if (dll_min[0] > dlli)
 245                                        dll_min[0] = dlli;
 246                                if (dll_max[0] < dlli)
 247                                        dll_max[0] = dlli;
 248                        }
 249                        passcnt++;
 250                } else if (passcnt >= CBR_THRESHOLD_AST2150)
 251                        goto cbr_start;
 252        }
 253        if (dll_max[0] == 0 || (dll_max[0]-dll_min[0]) < CBR_THRESHOLD_AST2150)
 254                goto cbr_start;
 255
 256        dlli = dll_min[0] + (((dll_max[0] - dll_min[0]) * 7) >> 4);
 257        moutdwm(ast, 0x1e6e0068, dlli | (dlli << 8) | (dlli << 16) | (dlli << 24));
 258}
 259
 260
 261
 262static void ast_init_dram_reg(struct drm_device *dev)
 263{
 264        struct ast_private *ast = dev->dev_private;
 265        u8 j;
 266        u32 data, temp, i;
 267        const struct ast_dramstruct *dram_reg_info;
 268
 269        j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
 270
 271        if ((j & 0x80) == 0) { /* VGA only */
 272                if (ast->chip == AST2000) {
 273                        dram_reg_info = ast2000_dram_table_data;
 274                        ast_write32(ast, 0xf004, 0x1e6e0000);
 275                        ast_write32(ast, 0xf000, 0x1);
 276                        ast_write32(ast, 0x10100, 0xa8);
 277
 278                        do {
 279                                ;
 280                        } while (ast_read32(ast, 0x10100) != 0xa8);
 281                } else {/* AST2100/1100 */
 282                        if (ast->chip == AST2100 || ast->chip == 2200)
 283                                dram_reg_info = ast2100_dram_table_data;
 284                        else
 285                                dram_reg_info = ast1100_dram_table_data;
 286
 287                        ast_write32(ast, 0xf004, 0x1e6e0000);
 288                        ast_write32(ast, 0xf000, 0x1);
 289                        ast_write32(ast, 0x12000, 0x1688A8A8);
 290                        do {
 291                                ;
 292                        } while (ast_read32(ast, 0x12000) != 0x01);
 293
 294                        ast_write32(ast, 0x10000, 0xfc600309);
 295                        do {
 296                                ;
 297                        } while (ast_read32(ast, 0x10000) != 0x01);
 298                }
 299
 300                while (dram_reg_info->index != 0xffff) {
 301                        if (dram_reg_info->index == 0xff00) {/* delay fn */
 302                                for (i = 0; i < 15; i++)
 303                                        udelay(dram_reg_info->data);
 304                        } else if (dram_reg_info->index == 0x4 && ast->chip != AST2000) {
 305                                data = dram_reg_info->data;
 306                                if (ast->dram_type == AST_DRAM_1Gx16)
 307                                        data = 0x00000d89;
 308                                else if (ast->dram_type == AST_DRAM_1Gx32)
 309                                        data = 0x00000c8d;
 310
 311                                temp = ast_read32(ast, 0x12070);
 312                                temp &= 0xc;
 313                                temp <<= 2;
 314                                ast_write32(ast, 0x10000 + dram_reg_info->index, data | temp);
 315                        } else
 316                                ast_write32(ast, 0x10000 + dram_reg_info->index, dram_reg_info->data);
 317                        dram_reg_info++;
 318                }
 319
 320                /* AST 2100/2150 DRAM calibration */
 321                data = ast_read32(ast, 0x10120);
 322                if (data == 0x5061) { /* 266Mhz */
 323                        data = ast_read32(ast, 0x10004);
 324                        if (data & 0x40)
 325                                cbrdlli_ast2150(ast, 16); /* 16 bits */
 326                        else
 327                                cbrdlli_ast2150(ast, 32); /* 32 bits */
 328                }
 329
 330                switch (ast->chip) {
 331                case AST2000:
 332                        temp = ast_read32(ast, 0x10140);
 333                        ast_write32(ast, 0x10140, temp | 0x40);
 334                        break;
 335                case AST1100:
 336                case AST2100:
 337                case AST2200:
 338                case AST2150:
 339                        temp = ast_read32(ast, 0x1200c);
 340                        ast_write32(ast, 0x1200c, temp & 0xfffffffd);
 341                        temp = ast_read32(ast, 0x12040);
 342                        ast_write32(ast, 0x12040, temp | 0x40);
 343                        break;
 344                default:
 345                        break;
 346                }
 347        }
 348
 349        /* wait ready */
 350        do {
 351                j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
 352        } while ((j & 0x40) == 0);
 353}
 354
 355void ast_post_gpu(struct drm_device *dev)
 356{
 357        u32 reg;
 358        struct ast_private *ast = dev->dev_private;
 359
 360        pci_read_config_dword(ast->dev->pdev, 0x04, &reg);
 361        reg |= 0x3;
 362        pci_write_config_dword(ast->dev->pdev, 0x04, reg);
 363
 364        ast_enable_vga(dev);
 365        ast_open_key(ast);
 366        ast_set_def_ext_reg(dev);
 367
 368        if (ast->chip == AST2300)
 369                ast_init_dram_2300(dev);
 370        else
 371                ast_init_dram_reg(dev);
 372}
 373
 374/* AST 2300 DRAM settings */
 375#define AST_DDR3 0
 376#define AST_DDR2 1
 377
 378struct ast2300_dram_param {
 379        u32 dram_type;
 380        u32 dram_chipid;
 381        u32 dram_freq;
 382        u32 vram_size;
 383        u32 odt;
 384        u32 wodt;
 385        u32 rodt;
 386        u32 dram_config;
 387        u32 reg_PERIOD;
 388        u32 reg_MADJ;
 389        u32 reg_SADJ;
 390        u32 reg_MRS;
 391        u32 reg_EMRS;
 392        u32 reg_AC1;
 393        u32 reg_AC2;
 394        u32 reg_DQSIC;
 395        u32 reg_DRV;
 396        u32 reg_IOZ;
 397        u32 reg_DQIDLY;
 398        u32 reg_FREQ;
 399        u32 madj_max;
 400        u32 dll2_finetune_step;
 401};
 402
 403/*
 404 * DQSI DLL CBR Setting
 405 */
 406#define CBR_SIZE1            ((4  << 10) - 1)
 407#define CBR_SIZE2            ((64 << 10) - 1)
 408#define CBR_PASSNUM          5
 409#define CBR_PASSNUM2         5
 410#define CBR_THRESHOLD        10
 411#define CBR_THRESHOLD2       10
 412#define TIMEOUT              5000000
 413#define CBR_PATNUM           8
 414
 415static const u32 pattern[8] = {
 416        0xFF00FF00,
 417        0xCC33CC33,
 418        0xAA55AA55,
 419        0x88778877,
 420        0x92CC4D6E,
 421        0x543D3CDE,
 422        0xF1E843C7,
 423        0x7C61D253
 424};
 425
 426#if 0 /* unused in DDX, included for completeness */
 427static int mmc_test_burst(struct ast_private *ast, u32 datagen)
 428{
 429        u32 data, timeout;
 430
 431        moutdwm(ast, 0x1e6e0070, 0x00000000);
 432        moutdwm(ast, 0x1e6e0070, 0x000000c1 | (datagen << 3));
 433        timeout = 0;
 434        do {
 435                data = mindwm(ast, 0x1e6e0070) & 0x3000;
 436                if (data & 0x2000) {
 437                        return 0;
 438                }
 439                if (++timeout > TIMEOUT) {
 440                        moutdwm(ast, 0x1e6e0070, 0x00000000);
 441                        return 0;
 442                }
 443        } while (!data);
 444        moutdwm(ast, 0x1e6e0070, 0x00000000);
 445        return 1;
 446}
 447#endif
 448
 449static int mmc_test_burst2(struct ast_private *ast, u32 datagen)
 450{
 451        u32 data, timeout;
 452
 453        moutdwm(ast, 0x1e6e0070, 0x00000000);
 454        moutdwm(ast, 0x1e6e0070, 0x00000041 | (datagen << 3));
 455        timeout = 0;
 456        do {
 457                data = mindwm(ast, 0x1e6e0070) & 0x1000;
 458                if (++timeout > TIMEOUT) {
 459                        moutdwm(ast, 0x1e6e0070, 0x0);
 460                        return -1;
 461                }
 462        } while (!data);
 463        data = mindwm(ast, 0x1e6e0078);
 464        data = (data | (data >> 16)) & 0xffff;
 465        moutdwm(ast, 0x1e6e0070, 0x0);
 466        return data;
 467}
 468
 469#if 0 /* Unused in DDX here for completeness */
 470static int mmc_test_single(struct ast_private *ast, u32 datagen)
 471{
 472        u32 data, timeout;
 473
 474        moutdwm(ast, 0x1e6e0070, 0x00000000);
 475        moutdwm(ast, 0x1e6e0070, 0x000000c5 | (datagen << 3));
 476        timeout = 0;
 477        do {
 478                data = mindwm(ast, 0x1e6e0070) & 0x3000;
 479                if (data & 0x2000)
 480                        return 0;
 481                if (++timeout > TIMEOUT) {
 482                        moutdwm(ast, 0x1e6e0070, 0x0);
 483                        return 0;
 484                }
 485        } while (!data);
 486        moutdwm(ast, 0x1e6e0070, 0x0);
 487        return 1;
 488}
 489#endif
 490
 491static int mmc_test_single2(struct ast_private *ast, u32 datagen)
 492{
 493        u32 data, timeout;
 494
 495        moutdwm(ast, 0x1e6e0070, 0x00000000);
 496        moutdwm(ast, 0x1e6e0070, 0x00000005 | (datagen << 3));
 497        timeout = 0;
 498        do {
 499                data = mindwm(ast, 0x1e6e0070) & 0x1000;
 500                if (++timeout > TIMEOUT) {
 501                        moutdwm(ast, 0x1e6e0070, 0x0);
 502                        return -1;
 503                }
 504        } while (!data);
 505        data = mindwm(ast, 0x1e6e0078);
 506        data = (data | (data >> 16)) & 0xffff;
 507        moutdwm(ast, 0x1e6e0070, 0x0);
 508        return data;
 509}
 510
 511static int cbr_test(struct ast_private *ast)
 512{
 513        u32 data;
 514        int i;
 515        data = mmc_test_single2(ast, 0);
 516        if ((data & 0xff) && (data & 0xff00))
 517                return 0;
 518        for (i = 0; i < 8; i++) {
 519                data = mmc_test_burst2(ast, i);
 520                if ((data & 0xff) && (data & 0xff00))
 521                        return 0;
 522        }
 523        if (!data)
 524                return 3;
 525        else if (data & 0xff)
 526                return 2;
 527        return 1;
 528}
 529
 530static int cbr_scan(struct ast_private *ast)
 531{
 532        u32 data, data2, patcnt, loop;
 533
 534        data2 = 3;
 535        for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
 536                moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
 537                for (loop = 0; loop < CBR_PASSNUM2; loop++) {
 538                        if ((data = cbr_test(ast)) != 0) {
 539                                data2 &= data;
 540                                if (!data2)
 541                                        return 0;
 542                                break;
 543                        }
 544                }
 545                if (loop == CBR_PASSNUM2)
 546                        return 0;
 547        }
 548        return data2;
 549}
 550
 551static u32 cbr_test2(struct ast_private *ast)
 552{
 553        u32 data;
 554
 555        data = mmc_test_burst2(ast, 0);
 556        if (data == 0xffff)
 557                return 0;
 558        data |= mmc_test_single2(ast, 0);
 559        if (data == 0xffff)
 560                return 0;
 561
 562        return ~data & 0xffff;
 563}
 564
 565static u32 cbr_scan2(struct ast_private *ast)
 566{
 567        u32 data, data2, patcnt, loop;
 568
 569        data2 = 0xffff;
 570        for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) {
 571                moutdwm(ast, 0x1e6e007c, pattern[patcnt]);
 572                for (loop = 0; loop < CBR_PASSNUM2; loop++) {
 573                        if ((data = cbr_test2(ast)) != 0) {
 574                                data2 &= data;
 575                                if (!data)
 576                                        return 0;
 577                                break;
 578                        }
 579                }
 580                if (loop == CBR_PASSNUM2)
 581                        return 0;
 582        }
 583        return data2;
 584}
 585
 586#if 0 /* unused in DDX - added for completeness */
 587static void finetuneDQI(struct ast_private *ast, struct ast2300_dram_param *param)
 588{
 589        u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
 590
 591        gold_sadj[0] = (mindwm(ast, 0x1E6E0024) >> 16) & 0xffff;
 592        gold_sadj[1] = gold_sadj[0] >> 8;
 593        gold_sadj[0] = gold_sadj[0] & 0xff;
 594        gold_sadj[0] = (gold_sadj[0] + gold_sadj[1]) >> 1;
 595        gold_sadj[1] = gold_sadj[0];
 596
 597        for (cnt = 0; cnt < 16; cnt++) {
 598                dllmin[cnt] = 0xff;
 599                dllmax[cnt] = 0x0;
 600        }
 601        passcnt = 0;
 602        for (dlli = 0; dlli < 76; dlli++) {
 603                moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
 604                /* Wait DQSI latch phase calibration */
 605                moutdwm(ast, 0x1E6E0074, 0x00000010);
 606                moutdwm(ast, 0x1E6E0070, 0x00000003);
 607                do {
 608                        data = mindwm(ast, 0x1E6E0070);
 609                } while (!(data & 0x00001000));
 610                moutdwm(ast, 0x1E6E0070, 0x00000000);
 611
 612                moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
 613                data = cbr_scan2(ast);
 614                if (data != 0) {
 615                        mask = 0x00010001;
 616                        for (cnt = 0; cnt < 16; cnt++) {
 617                                if (data & mask) {
 618                                        if (dllmin[cnt] > dlli) {
 619                                                dllmin[cnt] = dlli;
 620                                        }
 621                                        if (dllmax[cnt] < dlli) {
 622                                                dllmax[cnt] = dlli;
 623                                        }
 624                                }
 625                                mask <<= 1;
 626                        }
 627                        passcnt++;
 628                } else if (passcnt >= CBR_THRESHOLD) {
 629                        break;
 630                }
 631        }
 632        data = 0;
 633        for (cnt = 0; cnt < 8; cnt++) {
 634                data >>= 3;
 635                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
 636                        dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
 637                        if (gold_sadj[0] >= dlli) {
 638                                dlli = (gold_sadj[0] - dlli) >> 1;
 639                                if (dlli > 3) {
 640                                        dlli = 3;
 641                                }
 642                        } else {
 643                                dlli = (dlli - gold_sadj[0]) >> 1;
 644                                if (dlli > 4) {
 645                                        dlli = 4;
 646                                }
 647                                dlli = (8 - dlli) & 0x7;
 648                        }
 649                        data |= dlli << 21;
 650                }
 651        }
 652        moutdwm(ast, 0x1E6E0080, data);
 653
 654        data = 0;
 655        for (cnt = 8; cnt < 16; cnt++) {
 656                data >>= 3;
 657                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD)) {
 658                        dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
 659                        if (gold_sadj[1] >= dlli) {
 660                                dlli = (gold_sadj[1] - dlli) >> 1;
 661                                if (dlli > 3) {
 662                                        dlli = 3;
 663                                } else {
 664                                        dlli = (dlli - 1) & 0x7;
 665                                }
 666                        } else {
 667                                dlli = (dlli - gold_sadj[1]) >> 1;
 668                                dlli += 1;
 669                                if (dlli > 4) {
 670                                        dlli = 4;
 671                                }
 672                                dlli = (8 - dlli) & 0x7;
 673                        }
 674                        data |= dlli << 21;
 675                }
 676        }
 677        moutdwm(ast, 0x1E6E0084, data);
 678
 679} /* finetuneDQI */
 680#endif
 681
 682static void finetuneDQI_L(struct ast_private *ast, struct ast2300_dram_param *param)
 683{
 684        u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt;
 685
 686FINETUNE_START:
 687        for (cnt = 0; cnt < 16; cnt++) {
 688                dllmin[cnt] = 0xff;
 689                dllmax[cnt] = 0x0;
 690        }
 691        passcnt = 0;
 692        for (dlli = 0; dlli < 76; dlli++) {
 693                moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
 694                /* Wait DQSI latch phase calibration */
 695                moutdwm(ast, 0x1E6E0074, 0x00000010);
 696                moutdwm(ast, 0x1E6E0070, 0x00000003);
 697                do {
 698                        data = mindwm(ast, 0x1E6E0070);
 699                } while (!(data & 0x00001000));
 700                moutdwm(ast, 0x1E6E0070, 0x00000000);
 701
 702                moutdwm(ast, 0x1E6E0074, CBR_SIZE1);
 703                data = cbr_scan2(ast);
 704                if (data != 0) {
 705                        mask = 0x00010001;
 706                        for (cnt = 0; cnt < 16; cnt++) {
 707                                if (data & mask) {
 708                                        if (dllmin[cnt] > dlli) {
 709                                                dllmin[cnt] = dlli;
 710                                        }
 711                                        if (dllmax[cnt] < dlli) {
 712                                                dllmax[cnt] = dlli;
 713                                        }
 714                                }
 715                                mask <<= 1;
 716                        }
 717                        passcnt++;
 718                } else if (passcnt >= CBR_THRESHOLD2) {
 719                        break;
 720                }
 721        }
 722        gold_sadj[0] = 0x0;
 723        passcnt = 0;
 724        for (cnt = 0; cnt < 16; cnt++) {
 725                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 726                        gold_sadj[0] += dllmin[cnt];
 727                        passcnt++;
 728                }
 729        }
 730        if (passcnt != 16) {
 731                goto FINETUNE_START;
 732        }
 733        gold_sadj[0] = gold_sadj[0] >> 4;
 734        gold_sadj[1] = gold_sadj[0];
 735
 736        data = 0;
 737        for (cnt = 0; cnt < 8; cnt++) {
 738                data >>= 3;
 739                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 740                        dlli = dllmin[cnt];
 741                        if (gold_sadj[0] >= dlli) {
 742                                dlli = ((gold_sadj[0] - dlli) * 19) >> 5;
 743                                if (dlli > 3) {
 744                                        dlli = 3;
 745                                }
 746                        } else {
 747                                dlli = ((dlli - gold_sadj[0]) * 19) >> 5;
 748                                if (dlli > 4) {
 749                                        dlli = 4;
 750                                }
 751                                dlli = (8 - dlli) & 0x7;
 752                        }
 753                        data |= dlli << 21;
 754                }
 755        }
 756        moutdwm(ast, 0x1E6E0080, data);
 757
 758        data = 0;
 759        for (cnt = 8; cnt < 16; cnt++) {
 760                data >>= 3;
 761                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 762                        dlli = dllmin[cnt];
 763                        if (gold_sadj[1] >= dlli) {
 764                                dlli = ((gold_sadj[1] - dlli) * 19) >> 5;
 765                                if (dlli > 3) {
 766                                        dlli = 3;
 767                                } else {
 768                                        dlli = (dlli - 1) & 0x7;
 769                                }
 770                        } else {
 771                                dlli = ((dlli - gold_sadj[1]) * 19) >> 5;
 772                                dlli += 1;
 773                                if (dlli > 4) {
 774                                        dlli = 4;
 775                                }
 776                                dlli = (8 - dlli) & 0x7;
 777                        }
 778                        data |= dlli << 21;
 779                }
 780        }
 781        moutdwm(ast, 0x1E6E0084, data);
 782
 783} /* finetuneDQI_L */
 784
 785static void finetuneDQI_L2(struct ast_private *ast, struct ast2300_dram_param *param)
 786{
 787        u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, data2;
 788
 789        for (cnt = 0; cnt < 16; cnt++) {
 790                dllmin[cnt] = 0xff;
 791                dllmax[cnt] = 0x0;
 792        }
 793        passcnt = 0;
 794        for (dlli = 0; dlli < 76; dlli++) {
 795                moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24));
 796                /* Wait DQSI latch phase calibration */
 797                moutdwm(ast, 0x1E6E0074, 0x00000010);
 798                moutdwm(ast, 0x1E6E0070, 0x00000003);
 799                do {
 800                        data = mindwm(ast, 0x1E6E0070);
 801                } while (!(data & 0x00001000));
 802                moutdwm(ast, 0x1E6E0070, 0x00000000);
 803
 804                moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
 805                data = cbr_scan2(ast);
 806                if (data != 0) {
 807                        mask = 0x00010001;
 808                        for (cnt = 0; cnt < 16; cnt++) {
 809                                if (data & mask) {
 810                                        if (dllmin[cnt] > dlli) {
 811                                                dllmin[cnt] = dlli;
 812                                        }
 813                                        if (dllmax[cnt] < dlli) {
 814                                                dllmax[cnt] = dlli;
 815                                        }
 816                                }
 817                                mask <<= 1;
 818                        }
 819                        passcnt++;
 820                } else if (passcnt >= CBR_THRESHOLD2) {
 821                        break;
 822                }
 823        }
 824        gold_sadj[0] = 0x0;
 825        gold_sadj[1] = 0xFF;
 826        for (cnt = 0; cnt < 8; cnt++) {
 827                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 828                        if (gold_sadj[0] < dllmin[cnt]) {
 829                                gold_sadj[0] = dllmin[cnt];
 830                        }
 831                        if (gold_sadj[1] > dllmax[cnt]) {
 832                                gold_sadj[1] = dllmax[cnt];
 833                        }
 834                }
 835        }
 836        gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
 837        gold_sadj[1] = mindwm(ast, 0x1E6E0080);
 838
 839        data = 0;
 840        for (cnt = 0; cnt < 8; cnt++) {
 841                data >>= 3;
 842                data2 = gold_sadj[1] & 0x7;
 843                gold_sadj[1] >>= 3;
 844                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 845                        dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
 846                        if (gold_sadj[0] >= dlli) {
 847                                dlli = (gold_sadj[0] - dlli) >> 1;
 848                                if (dlli > 0) {
 849                                        dlli = 1;
 850                                }
 851                                if (data2 != 3) {
 852                                        data2 = (data2 + dlli) & 0x7;
 853                                }
 854                        } else {
 855                                dlli = (dlli - gold_sadj[0]) >> 1;
 856                                if (dlli > 0) {
 857                                        dlli = 1;
 858                                }
 859                                if (data2 != 4) {
 860                                        data2 = (data2 - dlli) & 0x7;
 861                                }
 862                        }
 863                }
 864                data |= data2 << 21;
 865        }
 866        moutdwm(ast, 0x1E6E0080, data);
 867
 868        gold_sadj[0] = 0x0;
 869        gold_sadj[1] = 0xFF;
 870        for (cnt = 8; cnt < 16; cnt++) {
 871                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 872                        if (gold_sadj[0] < dllmin[cnt]) {
 873                                gold_sadj[0] = dllmin[cnt];
 874                        }
 875                        if (gold_sadj[1] > dllmax[cnt]) {
 876                                gold_sadj[1] = dllmax[cnt];
 877                        }
 878                }
 879        }
 880        gold_sadj[0] = (gold_sadj[1] + gold_sadj[0]) >> 1;
 881        gold_sadj[1] = mindwm(ast, 0x1E6E0084);
 882
 883        data = 0;
 884        for (cnt = 8; cnt < 16; cnt++) {
 885                data >>= 3;
 886                data2 = gold_sadj[1] & 0x7;
 887                gold_sadj[1] >>= 3;
 888                if ((dllmax[cnt] > dllmin[cnt]) && ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) {
 889                        dlli = (dllmin[cnt] + dllmax[cnt]) >> 1;
 890                        if (gold_sadj[0] >= dlli) {
 891                                dlli = (gold_sadj[0] - dlli) >> 1;
 892                                if (dlli > 0) {
 893                                        dlli = 1;
 894                                }
 895                                if (data2 != 3) {
 896                                        data2 = (data2 + dlli) & 0x7;
 897                                }
 898                        } else {
 899                                dlli = (dlli - gold_sadj[0]) >> 1;
 900                                if (dlli > 0) {
 901                                        dlli = 1;
 902                                }
 903                                if (data2 != 4) {
 904                                        data2 = (data2 - dlli) & 0x7;
 905                                }
 906                        }
 907                }
 908                data |= data2 << 21;
 909        }
 910        moutdwm(ast, 0x1E6E0084, data);
 911
 912} /* finetuneDQI_L2 */
 913
 914static void cbr_dll2(struct ast_private *ast, struct ast2300_dram_param *param)
 915{
 916        u32 dllmin[2], dllmax[2], dlli, data, data2, passcnt;
 917
 918
 919        finetuneDQI_L(ast, param);
 920        finetuneDQI_L2(ast, param);
 921
 922CBR_START2:
 923        dllmin[0] = dllmin[1] = 0xff;
 924        dllmax[0] = dllmax[1] = 0x0;
 925        passcnt = 0;
 926        for (dlli = 0; dlli < 76; dlli++) {
 927                moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24));
 928                /* Wait DQSI latch phase calibration */
 929                moutdwm(ast, 0x1E6E0074, 0x00000010);
 930                moutdwm(ast, 0x1E6E0070, 0x00000003);
 931                do {
 932                        data = mindwm(ast, 0x1E6E0070);
 933                } while (!(data & 0x00001000));
 934                moutdwm(ast, 0x1E6E0070, 0x00000000);
 935
 936                moutdwm(ast, 0x1E6E0074, CBR_SIZE2);
 937                data = cbr_scan(ast);
 938                if (data != 0) {
 939                        if (data & 0x1) {
 940                                if (dllmin[0] > dlli) {
 941                                        dllmin[0] = dlli;
 942                                }
 943                                if (dllmax[0] < dlli) {
 944                                        dllmax[0] = dlli;
 945                                }
 946                        }
 947                        if (data & 0x2) {
 948                                if (dllmin[1] > dlli) {
 949                                        dllmin[1] = dlli;
 950                                }
 951                                if (dllmax[1] < dlli) {
 952                                        dllmax[1] = dlli;
 953                                }
 954                        }
 955                        passcnt++;
 956                } else if (passcnt >= CBR_THRESHOLD) {
 957                        break;
 958                }
 959        }
 960        if (dllmax[0] == 0 || (dllmax[0]-dllmin[0]) < CBR_THRESHOLD) {
 961                goto CBR_START2;
 962        }
 963        if (dllmax[1] == 0 || (dllmax[1]-dllmin[1]) < CBR_THRESHOLD) {
 964                goto CBR_START2;
 965        }
 966        dlli  = (dllmin[1] + dllmax[1]) >> 1;
 967        dlli <<= 8;
 968        dlli += (dllmin[0] + dllmax[0]) >> 1;
 969        moutdwm(ast, 0x1E6E0068, (mindwm(ast, 0x1E6E0068) & 0xFFFF) | (dlli << 16));
 970
 971        data  = (mindwm(ast, 0x1E6E0080) >> 24) & 0x1F;
 972        data2 = (mindwm(ast, 0x1E6E0018) & 0xff80ffff) | (data << 16);
 973        moutdwm(ast, 0x1E6E0018, data2);
 974        moutdwm(ast, 0x1E6E0024, 0x8001 | (data << 1) | (param->dll2_finetune_step << 8));
 975
 976        /* Wait DQSI latch phase calibration */
 977        moutdwm(ast, 0x1E6E0074, 0x00000010);
 978        moutdwm(ast, 0x1E6E0070, 0x00000003);
 979        do {
 980                data = mindwm(ast, 0x1E6E0070);
 981        } while (!(data & 0x00001000));
 982        moutdwm(ast, 0x1E6E0070, 0x00000000);
 983        moutdwm(ast, 0x1E6E0070, 0x00000003);
 984        do {
 985                data = mindwm(ast, 0x1E6E0070);
 986        } while (!(data & 0x00001000));
 987        moutdwm(ast, 0x1E6E0070, 0x00000000);
 988} /* CBRDLL2 */
 989
 990static void get_ddr3_info(struct ast_private *ast, struct ast2300_dram_param *param)
 991{
 992        u32 trap, trap_AC2, trap_MRS;
 993
 994        moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
 995
 996        /* Ger trap info */
 997        trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
 998        trap_AC2  = 0x00020000 + (trap << 16);
 999        trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19);
1000        trap_MRS  = 0x00000010 + (trap << 4);
1001        trap_MRS |= ((trap & 0x2) << 18);
1002
1003        param->reg_MADJ       = 0x00034C4C;
1004        param->reg_SADJ       = 0x00001800;
1005        param->reg_DRV        = 0x000000F0;
1006        param->reg_PERIOD     = param->dram_freq;
1007        param->rodt           = 0;
1008
1009        switch (param->dram_freq) {
1010        case 336:
1011                moutdwm(ast, 0x1E6E2020, 0x0190);
1012                param->wodt          = 0;
1013                param->reg_AC1       = 0x22202725;
1014                param->reg_AC2       = 0xAA007613 | trap_AC2;
1015                param->reg_DQSIC     = 0x000000BA;
1016                param->reg_MRS       = 0x04001400 | trap_MRS;
1017                param->reg_EMRS      = 0x00000000;
1018                param->reg_IOZ       = 0x00000034;
1019                param->reg_DQIDLY    = 0x00000074;
1020                param->reg_FREQ      = 0x00004DC0;
1021                param->madj_max      = 96;
1022                param->dll2_finetune_step = 3;
1023                break;
1024        default:
1025        case 396:
1026                moutdwm(ast, 0x1E6E2020, 0x03F1);
1027                param->wodt          = 1;
1028                param->reg_AC1       = 0x33302825;
1029                param->reg_AC2       = 0xCC009617 | trap_AC2;
1030                param->reg_DQSIC     = 0x000000E2;
1031                param->reg_MRS       = 0x04001600 | trap_MRS;
1032                param->reg_EMRS      = 0x00000000;
1033                param->reg_IOZ       = 0x00000034;
1034                param->reg_DRV       = 0x000000FA;
1035                param->reg_DQIDLY    = 0x00000089;
1036                param->reg_FREQ      = 0x000050C0;
1037                param->madj_max      = 96;
1038                param->dll2_finetune_step = 4;
1039
1040                switch (param->dram_chipid) {
1041                default:
1042                case AST_DRAM_512Mx16:
1043                case AST_DRAM_1Gx16:
1044                        param->reg_AC2   = 0xCC009617 | trap_AC2;
1045                        break;
1046                case AST_DRAM_2Gx16:
1047                        param->reg_AC2   = 0xCC009622 | trap_AC2;
1048                        break;
1049                case AST_DRAM_4Gx16:
1050                        param->reg_AC2   = 0xCC00963F | trap_AC2;
1051                        break;
1052                }
1053                break;
1054
1055        case 408:
1056                moutdwm(ast, 0x1E6E2020, 0x01F0);
1057                param->wodt          = 1;
1058                param->reg_AC1       = 0x33302825;
1059                param->reg_AC2       = 0xCC009617 | trap_AC2;
1060                param->reg_DQSIC     = 0x000000E2;
1061                param->reg_MRS       = 0x04001600 | trap_MRS;
1062                param->reg_EMRS      = 0x00000000;
1063                param->reg_IOZ       = 0x00000034;
1064                param->reg_DRV       = 0x000000FA;
1065                param->reg_DQIDLY    = 0x00000089;
1066                param->reg_FREQ      = 0x000050C0;
1067                param->madj_max      = 96;
1068                param->dll2_finetune_step = 4;
1069
1070                switch (param->dram_chipid) {
1071                default:
1072                case AST_DRAM_512Mx16:
1073                case AST_DRAM_1Gx16:
1074                        param->reg_AC2   = 0xCC009617 | trap_AC2;
1075                        break;
1076                case AST_DRAM_2Gx16:
1077                        param->reg_AC2   = 0xCC009622 | trap_AC2;
1078                        break;
1079                case AST_DRAM_4Gx16:
1080                        param->reg_AC2   = 0xCC00963F | trap_AC2;
1081                        break;
1082                }
1083
1084                break;
1085        case 456:
1086                moutdwm(ast, 0x1E6E2020, 0x0230);
1087                param->wodt          = 0;
1088                param->reg_AC1       = 0x33302926;
1089                param->reg_AC2       = 0xCD44961A;
1090                param->reg_DQSIC     = 0x000000FC;
1091                param->reg_MRS       = 0x00081830;
1092                param->reg_EMRS      = 0x00000000;
1093                param->reg_IOZ       = 0x00000045;
1094                param->reg_DQIDLY    = 0x00000097;
1095                param->reg_FREQ      = 0x000052C0;
1096                param->madj_max      = 88;
1097                param->dll2_finetune_step = 4;
1098                break;
1099        case 504:
1100                moutdwm(ast, 0x1E6E2020, 0x0270);
1101                param->wodt          = 1;
1102                param->reg_AC1       = 0x33302926;
1103                param->reg_AC2       = 0xDE44A61D;
1104                param->reg_DQSIC     = 0x00000117;
1105                param->reg_MRS       = 0x00081A30;
1106                param->reg_EMRS      = 0x00000000;
1107                param->reg_IOZ       = 0x070000BB;
1108                param->reg_DQIDLY    = 0x000000A0;
1109                param->reg_FREQ      = 0x000054C0;
1110                param->madj_max      = 79;
1111                param->dll2_finetune_step = 4;
1112                break;
1113        case 528:
1114                moutdwm(ast, 0x1E6E2020, 0x0290);
1115                param->wodt          = 1;
1116                param->rodt          = 1;
1117                param->reg_AC1       = 0x33302926;
1118                param->reg_AC2       = 0xEF44B61E;
1119                param->reg_DQSIC     = 0x00000125;
1120                param->reg_MRS       = 0x00081A30;
1121                param->reg_EMRS      = 0x00000040;
1122                param->reg_DRV       = 0x000000F5;
1123                param->reg_IOZ       = 0x00000023;
1124                param->reg_DQIDLY    = 0x00000088;
1125                param->reg_FREQ      = 0x000055C0;
1126                param->madj_max      = 76;
1127                param->dll2_finetune_step = 3;
1128                break;
1129        case 576:
1130                moutdwm(ast, 0x1E6E2020, 0x0140);
1131                param->reg_MADJ      = 0x00136868;
1132                param->reg_SADJ      = 0x00004534;
1133                param->wodt          = 1;
1134                param->rodt          = 1;
1135                param->reg_AC1       = 0x33302A37;
1136                param->reg_AC2       = 0xEF56B61E;
1137                param->reg_DQSIC     = 0x0000013F;
1138                param->reg_MRS       = 0x00101A50;
1139                param->reg_EMRS      = 0x00000040;
1140                param->reg_DRV       = 0x000000FA;
1141                param->reg_IOZ       = 0x00000023;
1142                param->reg_DQIDLY    = 0x00000078;
1143                param->reg_FREQ      = 0x000057C0;
1144                param->madj_max      = 136;
1145                param->dll2_finetune_step = 3;
1146                break;
1147        case 600:
1148                moutdwm(ast, 0x1E6E2020, 0x02E1);
1149                param->reg_MADJ      = 0x00136868;
1150                param->reg_SADJ      = 0x00004534;
1151                param->wodt          = 1;
1152                param->rodt          = 1;
1153                param->reg_AC1       = 0x32302A37;
1154                param->reg_AC2       = 0xDF56B61F;
1155                param->reg_DQSIC     = 0x0000014D;
1156                param->reg_MRS       = 0x00101A50;
1157                param->reg_EMRS      = 0x00000004;
1158                param->reg_DRV       = 0x000000F5;
1159                param->reg_IOZ       = 0x00000023;
1160                param->reg_DQIDLY    = 0x00000078;
1161                param->reg_FREQ      = 0x000058C0;
1162                param->madj_max      = 132;
1163                param->dll2_finetune_step = 3;
1164                break;
1165        case 624:
1166                moutdwm(ast, 0x1E6E2020, 0x0160);
1167                param->reg_MADJ      = 0x00136868;
1168                param->reg_SADJ      = 0x00004534;
1169                param->wodt          = 1;
1170                param->rodt          = 1;
1171                param->reg_AC1       = 0x32302A37;
1172                param->reg_AC2       = 0xEF56B621;
1173                param->reg_DQSIC     = 0x0000015A;
1174                param->reg_MRS       = 0x02101A50;
1175                param->reg_EMRS      = 0x00000004;
1176                param->reg_DRV       = 0x000000F5;
1177                param->reg_IOZ       = 0x00000034;
1178                param->reg_DQIDLY    = 0x00000078;
1179                param->reg_FREQ      = 0x000059C0;
1180                param->madj_max      = 128;
1181                param->dll2_finetune_step = 3;
1182                break;
1183        } /* switch freq */
1184
1185        switch (param->dram_chipid) {
1186        case AST_DRAM_512Mx16:
1187                param->dram_config = 0x130;
1188                break;
1189        default:
1190        case AST_DRAM_1Gx16:
1191                param->dram_config = 0x131;
1192                break;
1193        case AST_DRAM_2Gx16:
1194                param->dram_config = 0x132;
1195                break;
1196        case AST_DRAM_4Gx16:
1197                param->dram_config = 0x133;
1198                break;
1199        }; /* switch size */
1200
1201        switch (param->vram_size) {
1202        default:
1203        case AST_VIDMEM_SIZE_8M:
1204                param->dram_config |= 0x00;
1205                break;
1206        case AST_VIDMEM_SIZE_16M:
1207                param->dram_config |= 0x04;
1208                break;
1209        case AST_VIDMEM_SIZE_32M:
1210                param->dram_config |= 0x08;
1211                break;
1212        case AST_VIDMEM_SIZE_64M:
1213                param->dram_config |= 0x0c;
1214                break;
1215        }
1216
1217}
1218
1219static void ddr3_init(struct ast_private *ast, struct ast2300_dram_param *param)
1220{
1221        u32 data, data2;
1222
1223        moutdwm(ast, 0x1E6E0000, 0xFC600309);
1224        moutdwm(ast, 0x1E6E0018, 0x00000100);
1225        moutdwm(ast, 0x1E6E0024, 0x00000000);
1226        moutdwm(ast, 0x1E6E0034, 0x00000000);
1227        udelay(10);
1228        moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1229        moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1230        udelay(10);
1231        moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1232        udelay(10);
1233
1234        moutdwm(ast, 0x1E6E0004, param->dram_config);
1235        moutdwm(ast, 0x1E6E0008, 0x90040f);
1236        moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1237        moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1238        moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1239        moutdwm(ast, 0x1E6E0080, 0x00000000);
1240        moutdwm(ast, 0x1E6E0084, 0x00000000);
1241        moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1242        moutdwm(ast, 0x1E6E0018, 0x4040A170);
1243        moutdwm(ast, 0x1E6E0018, 0x20402370);
1244        moutdwm(ast, 0x1E6E0038, 0x00000000);
1245        moutdwm(ast, 0x1E6E0040, 0xFF444444);
1246        moutdwm(ast, 0x1E6E0044, 0x22222222);
1247        moutdwm(ast, 0x1E6E0048, 0x22222222);
1248        moutdwm(ast, 0x1E6E004C, 0x00000002);
1249        moutdwm(ast, 0x1E6E0050, 0x80000000);
1250        moutdwm(ast, 0x1E6E0050, 0x00000000);
1251        moutdwm(ast, 0x1E6E0054, 0);
1252        moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1253        moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1254        moutdwm(ast, 0x1E6E0070, 0x00000000);
1255        moutdwm(ast, 0x1E6E0074, 0x00000000);
1256        moutdwm(ast, 0x1E6E0078, 0x00000000);
1257        moutdwm(ast, 0x1E6E007C, 0x00000000);
1258        /* Wait MCLK2X lock to MCLK */
1259        do {
1260                data = mindwm(ast, 0x1E6E001C);
1261        } while (!(data & 0x08000000));
1262        moutdwm(ast, 0x1E6E0034, 0x00000001);
1263        moutdwm(ast, 0x1E6E000C, 0x00005C04);
1264        udelay(10);
1265        moutdwm(ast, 0x1E6E000C, 0x00000000);
1266        moutdwm(ast, 0x1E6E0034, 0x00000000);
1267        data = mindwm(ast, 0x1E6E001C);
1268        data = (data >> 8) & 0xff;
1269        while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1270                data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1271                if ((data2 & 0xff) > param->madj_max) {
1272                        break;
1273                }
1274                moutdwm(ast, 0x1E6E0064, data2);
1275                if (data2 & 0x00100000) {
1276                        data2 = ((data2 & 0xff) >> 3) + 3;
1277                } else {
1278                        data2 = ((data2 & 0xff) >> 2) + 5;
1279                }
1280                data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1281                data2 += data & 0xff;
1282                data = data | (data2 << 8);
1283                moutdwm(ast, 0x1E6E0068, data);
1284                udelay(10);
1285                moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1286                udelay(10);
1287                data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1288                moutdwm(ast, 0x1E6E0018, data);
1289                data = data | 0x200;
1290                moutdwm(ast, 0x1E6E0018, data);
1291                do {
1292                        data = mindwm(ast, 0x1E6E001C);
1293                } while (!(data & 0x08000000));
1294
1295                moutdwm(ast, 0x1E6E0034, 0x00000001);
1296                moutdwm(ast, 0x1E6E000C, 0x00005C04);
1297                udelay(10);
1298                moutdwm(ast, 0x1E6E000C, 0x00000000);
1299                moutdwm(ast, 0x1E6E0034, 0x00000000);
1300                data = mindwm(ast, 0x1E6E001C);
1301                data = (data >> 8) & 0xff;
1302        }
1303        data = mindwm(ast, 0x1E6E0018) | 0xC00;
1304        moutdwm(ast, 0x1E6E0018, data);
1305
1306        moutdwm(ast, 0x1E6E0034, 0x00000001);
1307        moutdwm(ast, 0x1E6E000C, 0x00000040);
1308        udelay(50);
1309        /* Mode Register Setting */
1310        moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1311        moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1312        moutdwm(ast, 0x1E6E0028, 0x00000005);
1313        moutdwm(ast, 0x1E6E0028, 0x00000007);
1314        moutdwm(ast, 0x1E6E0028, 0x00000003);
1315        moutdwm(ast, 0x1E6E0028, 0x00000001);
1316        moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1317        moutdwm(ast, 0x1E6E000C, 0x00005C08);
1318        moutdwm(ast, 0x1E6E0028, 0x00000001);
1319
1320        moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1321        data = 0;
1322        if (param->wodt) {
1323                data = 0x300;
1324        }
1325        if (param->rodt) {
1326                data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1327        }
1328        moutdwm(ast, 0x1E6E0034, data | 0x3);
1329
1330        /* Wait DQI delay lock */
1331        do {
1332                data = mindwm(ast, 0x1E6E0080);
1333        } while (!(data & 0x40000000));
1334        /* Wait DQSI delay lock */
1335        do {
1336                data = mindwm(ast, 0x1E6E0020);
1337        } while (!(data & 0x00000800));
1338        /* Calibrate the DQSI delay */
1339        cbr_dll2(ast, param);
1340
1341        moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1342        /* ECC Memory Initialization */
1343#ifdef ECC
1344        moutdwm(ast, 0x1E6E007C, 0x00000000);
1345        moutdwm(ast, 0x1E6E0070, 0x221);
1346        do {
1347                data = mindwm(ast, 0x1E6E0070);
1348        } while (!(data & 0x00001000));
1349        moutdwm(ast, 0x1E6E0070, 0x00000000);
1350        moutdwm(ast, 0x1E6E0050, 0x80000000);
1351        moutdwm(ast, 0x1E6E0050, 0x00000000);
1352#endif
1353
1354
1355}
1356
1357static void get_ddr2_info(struct ast_private *ast, struct ast2300_dram_param *param)
1358{
1359        u32 trap, trap_AC2, trap_MRS;
1360
1361        moutdwm(ast, 0x1E6E2000, 0x1688A8A8);
1362
1363        /* Ger trap info */
1364        trap = (mindwm(ast, 0x1E6E2070) >> 25) & 0x3;
1365        trap_AC2  = (trap << 20) | (trap << 16);
1366        trap_AC2 += 0x00110000;
1367        trap_MRS  = 0x00000040 | (trap << 4);
1368
1369
1370        param->reg_MADJ       = 0x00034C4C;
1371        param->reg_SADJ       = 0x00001800;
1372        param->reg_DRV        = 0x000000F0;
1373        param->reg_PERIOD     = param->dram_freq;
1374        param->rodt           = 0;
1375
1376        switch (param->dram_freq) {
1377        case 264:
1378                moutdwm(ast, 0x1E6E2020, 0x0130);
1379                param->wodt          = 0;
1380                param->reg_AC1       = 0x11101513;
1381                param->reg_AC2       = 0x78117011;
1382                param->reg_DQSIC     = 0x00000092;
1383                param->reg_MRS       = 0x00000842;
1384                param->reg_EMRS      = 0x00000000;
1385                param->reg_DRV       = 0x000000F0;
1386                param->reg_IOZ       = 0x00000034;
1387                param->reg_DQIDLY    = 0x0000005A;
1388                param->reg_FREQ      = 0x00004AC0;
1389                param->madj_max      = 138;
1390                param->dll2_finetune_step = 3;
1391                break;
1392        case 336:
1393                moutdwm(ast, 0x1E6E2020, 0x0190);
1394                param->wodt          = 1;
1395                param->reg_AC1       = 0x22202613;
1396                param->reg_AC2       = 0xAA009016 | trap_AC2;
1397                param->reg_DQSIC     = 0x000000BA;
1398                param->reg_MRS       = 0x00000A02 | trap_MRS;
1399                param->reg_EMRS      = 0x00000040;
1400                param->reg_DRV       = 0x000000FA;
1401                param->reg_IOZ       = 0x00000034;
1402                param->reg_DQIDLY    = 0x00000074;
1403                param->reg_FREQ      = 0x00004DC0;
1404                param->madj_max      = 96;
1405                param->dll2_finetune_step = 3;
1406                break;
1407        default:
1408        case 396:
1409                moutdwm(ast, 0x1E6E2020, 0x03F1);
1410                param->wodt          = 1;
1411                param->rodt          = 0;
1412                param->reg_AC1       = 0x33302714;
1413                param->reg_AC2       = 0xCC00B01B | trap_AC2;
1414                param->reg_DQSIC     = 0x000000E2;
1415                param->reg_MRS       = 0x00000C02 | trap_MRS;
1416                param->reg_EMRS      = 0x00000040;
1417                param->reg_DRV       = 0x000000FA;
1418                param->reg_IOZ       = 0x00000034;
1419                param->reg_DQIDLY    = 0x00000089;
1420                param->reg_FREQ      = 0x000050C0;
1421                param->madj_max      = 96;
1422                param->dll2_finetune_step = 4;
1423
1424                switch (param->dram_chipid) {
1425                case AST_DRAM_512Mx16:
1426                        param->reg_AC2   = 0xCC00B016 | trap_AC2;
1427                        break;
1428                default:
1429                case AST_DRAM_1Gx16:
1430                        param->reg_AC2   = 0xCC00B01B | trap_AC2;
1431                        break;
1432                case AST_DRAM_2Gx16:
1433                        param->reg_AC2   = 0xCC00B02B | trap_AC2;
1434                        break;
1435                case AST_DRAM_4Gx16:
1436                        param->reg_AC2   = 0xCC00B03F | trap_AC2;
1437                        break;
1438                }
1439
1440                break;
1441
1442        case 408:
1443                moutdwm(ast, 0x1E6E2020, 0x01F0);
1444                param->wodt          = 1;
1445                param->rodt          = 0;
1446                param->reg_AC1       = 0x33302714;
1447                param->reg_AC2       = 0xCC00B01B | trap_AC2;
1448                param->reg_DQSIC     = 0x000000E2;
1449                param->reg_MRS       = 0x00000C02 | trap_MRS;
1450                param->reg_EMRS      = 0x00000040;
1451                param->reg_DRV       = 0x000000FA;
1452                param->reg_IOZ       = 0x00000034;
1453                param->reg_DQIDLY    = 0x00000089;
1454                param->reg_FREQ      = 0x000050C0;
1455                param->madj_max      = 96;
1456                param->dll2_finetune_step = 4;
1457
1458                switch (param->dram_chipid) {
1459                case AST_DRAM_512Mx16:
1460                        param->reg_AC2   = 0xCC00B016 | trap_AC2;
1461                        break;
1462                default:
1463                case AST_DRAM_1Gx16:
1464                        param->reg_AC2   = 0xCC00B01B | trap_AC2;
1465                        break;
1466                case AST_DRAM_2Gx16:
1467                        param->reg_AC2   = 0xCC00B02B | trap_AC2;
1468                        break;
1469                case AST_DRAM_4Gx16:
1470                        param->reg_AC2   = 0xCC00B03F | trap_AC2;
1471                        break;
1472                }
1473
1474                break;
1475        case 456:
1476                moutdwm(ast, 0x1E6E2020, 0x0230);
1477                param->wodt          = 0;
1478                param->reg_AC1       = 0x33302815;
1479                param->reg_AC2       = 0xCD44B01E;
1480                param->reg_DQSIC     = 0x000000FC;
1481                param->reg_MRS       = 0x00000E72;
1482                param->reg_EMRS      = 0x00000000;
1483                param->reg_DRV       = 0x00000000;
1484                param->reg_IOZ       = 0x00000034;
1485                param->reg_DQIDLY    = 0x00000097;
1486                param->reg_FREQ      = 0x000052C0;
1487                param->madj_max      = 88;
1488                param->dll2_finetune_step = 3;
1489                break;
1490        case 504:
1491                moutdwm(ast, 0x1E6E2020, 0x0261);
1492                param->wodt          = 1;
1493                param->rodt          = 1;
1494                param->reg_AC1       = 0x33302815;
1495                param->reg_AC2       = 0xDE44C022;
1496                param->reg_DQSIC     = 0x00000117;
1497                param->reg_MRS       = 0x00000E72;
1498                param->reg_EMRS      = 0x00000040;
1499                param->reg_DRV       = 0x0000000A;
1500                param->reg_IOZ       = 0x00000045;
1501                param->reg_DQIDLY    = 0x000000A0;
1502                param->reg_FREQ      = 0x000054C0;
1503                param->madj_max      = 79;
1504                param->dll2_finetune_step = 3;
1505                break;
1506        case 528:
1507                moutdwm(ast, 0x1E6E2020, 0x0120);
1508                param->wodt          = 1;
1509                param->rodt          = 1;
1510                param->reg_AC1       = 0x33302815;
1511                param->reg_AC2       = 0xEF44D024;
1512                param->reg_DQSIC     = 0x00000125;
1513                param->reg_MRS       = 0x00000E72;
1514                param->reg_EMRS      = 0x00000004;
1515                param->reg_DRV       = 0x000000F9;
1516                param->reg_IOZ       = 0x00000045;
1517                param->reg_DQIDLY    = 0x000000A7;
1518                param->reg_FREQ      = 0x000055C0;
1519                param->madj_max      = 76;
1520                param->dll2_finetune_step = 3;
1521                break;
1522        case 552:
1523                moutdwm(ast, 0x1E6E2020, 0x02A1);
1524                param->wodt          = 1;
1525                param->rodt          = 1;
1526                param->reg_AC1       = 0x43402915;
1527                param->reg_AC2       = 0xFF44E025;
1528                param->reg_DQSIC     = 0x00000132;
1529                param->reg_MRS       = 0x00000E72;
1530                param->reg_EMRS      = 0x00000040;
1531                param->reg_DRV       = 0x0000000A;
1532                param->reg_IOZ       = 0x00000045;
1533                param->reg_DQIDLY    = 0x000000AD;
1534                param->reg_FREQ      = 0x000056C0;
1535                param->madj_max      = 76;
1536                param->dll2_finetune_step = 3;
1537                break;
1538        case 576:
1539                moutdwm(ast, 0x1E6E2020, 0x0140);
1540                param->wodt          = 1;
1541                param->rodt          = 1;
1542                param->reg_AC1       = 0x43402915;
1543                param->reg_AC2       = 0xFF44E027;
1544                param->reg_DQSIC     = 0x0000013F;
1545                param->reg_MRS       = 0x00000E72;
1546                param->reg_EMRS      = 0x00000004;
1547                param->reg_DRV       = 0x000000F5;
1548                param->reg_IOZ       = 0x00000045;
1549                param->reg_DQIDLY    = 0x000000B3;
1550                param->reg_FREQ      = 0x000057C0;
1551                param->madj_max      = 76;
1552                param->dll2_finetune_step = 3;
1553                break;
1554        }
1555
1556        switch (param->dram_chipid) {
1557        case AST_DRAM_512Mx16:
1558                param->dram_config = 0x100;
1559                break;
1560        default:
1561        case AST_DRAM_1Gx16:
1562                param->dram_config = 0x121;
1563                break;
1564        case AST_DRAM_2Gx16:
1565                param->dram_config = 0x122;
1566                break;
1567        case AST_DRAM_4Gx16:
1568                param->dram_config = 0x123;
1569                break;
1570        }; /* switch size */
1571
1572        switch (param->vram_size) {
1573        default:
1574        case AST_VIDMEM_SIZE_8M:
1575                param->dram_config |= 0x00;
1576                break;
1577        case AST_VIDMEM_SIZE_16M:
1578                param->dram_config |= 0x04;
1579                break;
1580        case AST_VIDMEM_SIZE_32M:
1581                param->dram_config |= 0x08;
1582                break;
1583        case AST_VIDMEM_SIZE_64M:
1584                param->dram_config |= 0x0c;
1585                break;
1586        }
1587}
1588
1589static void ddr2_init(struct ast_private *ast, struct ast2300_dram_param *param)
1590{
1591        u32 data, data2;
1592
1593        moutdwm(ast, 0x1E6E0000, 0xFC600309);
1594        moutdwm(ast, 0x1E6E0018, 0x00000100);
1595        moutdwm(ast, 0x1E6E0024, 0x00000000);
1596        moutdwm(ast, 0x1E6E0064, param->reg_MADJ);
1597        moutdwm(ast, 0x1E6E0068, param->reg_SADJ);
1598        udelay(10);
1599        moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000);
1600        udelay(10);
1601
1602        moutdwm(ast, 0x1E6E0004, param->dram_config);
1603        moutdwm(ast, 0x1E6E0008, 0x90040f);
1604        moutdwm(ast, 0x1E6E0010, param->reg_AC1);
1605        moutdwm(ast, 0x1E6E0014, param->reg_AC2);
1606        moutdwm(ast, 0x1E6E0020, param->reg_DQSIC);
1607        moutdwm(ast, 0x1E6E0080, 0x00000000);
1608        moutdwm(ast, 0x1E6E0084, 0x00000000);
1609        moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY);
1610        moutdwm(ast, 0x1E6E0018, 0x4040A130);
1611        moutdwm(ast, 0x1E6E0018, 0x20402330);
1612        moutdwm(ast, 0x1E6E0038, 0x00000000);
1613        moutdwm(ast, 0x1E6E0040, 0xFF808000);
1614        moutdwm(ast, 0x1E6E0044, 0x88848466);
1615        moutdwm(ast, 0x1E6E0048, 0x44440008);
1616        moutdwm(ast, 0x1E6E004C, 0x00000000);
1617        moutdwm(ast, 0x1E6E0050, 0x80000000);
1618        moutdwm(ast, 0x1E6E0050, 0x00000000);
1619        moutdwm(ast, 0x1E6E0054, 0);
1620        moutdwm(ast, 0x1E6E0060, param->reg_DRV);
1621        moutdwm(ast, 0x1E6E006C, param->reg_IOZ);
1622        moutdwm(ast, 0x1E6E0070, 0x00000000);
1623        moutdwm(ast, 0x1E6E0074, 0x00000000);
1624        moutdwm(ast, 0x1E6E0078, 0x00000000);
1625        moutdwm(ast, 0x1E6E007C, 0x00000000);
1626
1627        /* Wait MCLK2X lock to MCLK */
1628        do {
1629                data = mindwm(ast, 0x1E6E001C);
1630        } while (!(data & 0x08000000));
1631        moutdwm(ast, 0x1E6E0034, 0x00000001);
1632        moutdwm(ast, 0x1E6E000C, 0x00005C04);
1633        udelay(10);
1634        moutdwm(ast, 0x1E6E000C, 0x00000000);
1635        moutdwm(ast, 0x1E6E0034, 0x00000000);
1636        data = mindwm(ast, 0x1E6E001C);
1637        data = (data >> 8) & 0xff;
1638        while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) {
1639                data2 = (mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4;
1640                if ((data2 & 0xff) > param->madj_max) {
1641                        break;
1642                }
1643                moutdwm(ast, 0x1E6E0064, data2);
1644                if (data2 & 0x00100000) {
1645                        data2 = ((data2 & 0xff) >> 3) + 3;
1646                } else {
1647                        data2 = ((data2 & 0xff) >> 2) + 5;
1648                }
1649                data = mindwm(ast, 0x1E6E0068) & 0xffff00ff;
1650                data2 += data & 0xff;
1651                data = data | (data2 << 8);
1652                moutdwm(ast, 0x1E6E0068, data);
1653                udelay(10);
1654                moutdwm(ast, 0x1E6E0064, mindwm(ast, 0x1E6E0064) | 0xC0000);
1655                udelay(10);
1656                data = mindwm(ast, 0x1E6E0018) & 0xfffff1ff;
1657                moutdwm(ast, 0x1E6E0018, data);
1658                data = data | 0x200;
1659                moutdwm(ast, 0x1E6E0018, data);
1660                do {
1661                        data = mindwm(ast, 0x1E6E001C);
1662                } while (!(data & 0x08000000));
1663
1664                moutdwm(ast, 0x1E6E0034, 0x00000001);
1665                moutdwm(ast, 0x1E6E000C, 0x00005C04);
1666                udelay(10);
1667                moutdwm(ast, 0x1E6E000C, 0x00000000);
1668                moutdwm(ast, 0x1E6E0034, 0x00000000);
1669                data = mindwm(ast, 0x1E6E001C);
1670                data = (data >> 8) & 0xff;
1671        }
1672        data = mindwm(ast, 0x1E6E0018) | 0xC00;
1673        moutdwm(ast, 0x1E6E0018, data);
1674
1675        moutdwm(ast, 0x1E6E0034, 0x00000001);
1676        moutdwm(ast, 0x1E6E000C, 0x00000000);
1677        udelay(50);
1678        /* Mode Register Setting */
1679        moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100);
1680        moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1681        moutdwm(ast, 0x1E6E0028, 0x00000005);
1682        moutdwm(ast, 0x1E6E0028, 0x00000007);
1683        moutdwm(ast, 0x1E6E0028, 0x00000003);
1684        moutdwm(ast, 0x1E6E0028, 0x00000001);
1685
1686        moutdwm(ast, 0x1E6E000C, 0x00005C08);
1687        moutdwm(ast, 0x1E6E002C, param->reg_MRS);
1688        moutdwm(ast, 0x1E6E0028, 0x00000001);
1689        moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380);
1690        moutdwm(ast, 0x1E6E0028, 0x00000003);
1691        moutdwm(ast, 0x1E6E0030, param->reg_EMRS);
1692        moutdwm(ast, 0x1E6E0028, 0x00000003);
1693
1694        moutdwm(ast, 0x1E6E000C, 0x7FFF5C01);
1695        data = 0;
1696        if (param->wodt) {
1697                data = 0x500;
1698        }
1699        if (param->rodt) {
1700                data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3);
1701        }
1702        moutdwm(ast, 0x1E6E0034, data | 0x3);
1703        moutdwm(ast, 0x1E6E0120, param->reg_FREQ);
1704
1705        /* Wait DQI delay lock */
1706        do {
1707                data = mindwm(ast, 0x1E6E0080);
1708        } while (!(data & 0x40000000));
1709        /* Wait DQSI delay lock */
1710        do {
1711                data = mindwm(ast, 0x1E6E0020);
1712        } while (!(data & 0x00000800));
1713        /* Calibrate the DQSI delay */
1714        cbr_dll2(ast, param);
1715
1716        /* ECC Memory Initialization */
1717#ifdef ECC
1718        moutdwm(ast, 0x1E6E007C, 0x00000000);
1719        moutdwm(ast, 0x1E6E0070, 0x221);
1720        do {
1721                data = mindwm(ast, 0x1E6E0070);
1722        } while (!(data & 0x00001000));
1723        moutdwm(ast, 0x1E6E0070, 0x00000000);
1724        moutdwm(ast, 0x1E6E0050, 0x80000000);
1725        moutdwm(ast, 0x1E6E0050, 0x00000000);
1726#endif
1727
1728}
1729
1730static void ast_init_dram_2300(struct drm_device *dev)
1731{
1732        struct ast_private *ast = dev->dev_private;
1733        struct ast2300_dram_param param;
1734        u32 temp;
1735        u8 reg;
1736
1737        reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1738        if ((reg & 0x80) == 0) {/* vga only */
1739                ast_write32(ast, 0xf004, 0x1e6e0000);
1740                ast_write32(ast, 0xf000, 0x1);
1741                ast_write32(ast, 0x12000, 0x1688a8a8);
1742                do {
1743                        ;
1744                } while (ast_read32(ast, 0x12000) != 0x1);
1745
1746                ast_write32(ast, 0x10000, 0xfc600309);
1747                do {
1748                        ;
1749                } while (ast_read32(ast, 0x10000) != 0x1);
1750
1751                /* Slow down CPU/AHB CLK in VGA only mode */
1752                temp = ast_read32(ast, 0x12008);
1753                temp |= 0x73;
1754                ast_write32(ast, 0x12008, temp);
1755
1756                param.dram_type = AST_DDR3;
1757                if (temp & 0x01000000)
1758                        param.dram_type = AST_DDR2;
1759                param.dram_chipid = ast->dram_type;
1760                param.dram_freq = ast->mclk;
1761                param.vram_size = ast->vram_size;
1762
1763                if (param.dram_type == AST_DDR3) {
1764                        get_ddr3_info(ast, &param);
1765                        ddr3_init(ast, &param);
1766                } else {
1767                        get_ddr2_info(ast, &param);
1768                        ddr2_init(ast, &param);
1769                }
1770
1771                temp = mindwm(ast, 0x1e6e2040);
1772                moutdwm(ast, 0x1e6e2040, temp | 0x40);
1773        }
1774
1775        /* wait ready */
1776        do {
1777                reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
1778        } while ((reg & 0x40) == 0);
1779}
1780
1781