Home | History | Annotate | Line # | Download | only in ast
ast_post.c revision 1.1.1.1.8.2
      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 (at) redhat.com>
     27  */
     28 
     29 #include <drm/drmP.h>
     30 #include "ast_drv.h"
     31 
     32 #include "ast_dram_tables.h"
     33 
     34 static void ast_init_dram_2300(struct drm_device *dev);
     35 
     36 static void
     37 ast_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 */
     46 static bool
     47 ast_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 
     66 static const u8 extreginfo[] = { 0x0f, 0x04, 0x1c, 0xff };
     67 static const u8 extreginfo_ast2300a0[] = { 0x0f, 0x04, 0x1c, 0xff };
     68 static const u8 extreginfo_ast2300[] = { 0x0f, 0x04, 0x1f, 0xff };
     69 
     70 static void
     71 ast_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 
    110 static 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 
    118 static 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 
    136 static 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 
    153 static 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 */
    183 static 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 
    203 static 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 
    213 static 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 
    230 static void cbrdlli_ast2150(struct ast_private *ast, int busw)
    231 {
    232 	u32 dll_min[4], dll_max[4], dlli, data, passcnt;
    233 
    234 cbr_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 
    262 static 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 
    355 void 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 
    378 struct 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 
    415 static 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 */
    427 static 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 
    449 static 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 */
    470 static 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 
    491 static 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 
    511 static 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 
    530 static 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 
    551 static 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 
    565 static 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 */
    587 static 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 
    682 static 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 
    686 FINETUNE_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 
    785 static 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 
    914 static 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 
    922 CBR_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 
    990 static 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 
   1219 static 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 
   1357 static 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 
   1589 static 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 
   1730 static 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