10f336e9cSThomas Zimmermann // SPDX-License-Identifier: MIT 20f336e9cSThomas Zimmermann /* 30f336e9cSThomas Zimmermann * Copyright 2012 Red Hat Inc. 40f336e9cSThomas Zimmermann * 50f336e9cSThomas Zimmermann * Permission is hereby granted, free of charge, to any person obtaining a 60f336e9cSThomas Zimmermann * copy of this software and associated documentation files (the 70f336e9cSThomas Zimmermann * "Software"), to deal in the Software without restriction, including 80f336e9cSThomas Zimmermann * without limitation the rights to use, copy, modify, merge, publish, 90f336e9cSThomas Zimmermann * distribute, sub license, and/or sell copies of the Software, and to 100f336e9cSThomas Zimmermann * permit persons to whom the Software is furnished to do so, subject to 110f336e9cSThomas Zimmermann * the following conditions: 120f336e9cSThomas Zimmermann * 130f336e9cSThomas Zimmermann * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 140f336e9cSThomas Zimmermann * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 150f336e9cSThomas Zimmermann * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 160f336e9cSThomas Zimmermann * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 170f336e9cSThomas Zimmermann * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 180f336e9cSThomas Zimmermann * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 190f336e9cSThomas Zimmermann * USE OR OTHER DEALINGS IN THE SOFTWARE. 200f336e9cSThomas Zimmermann * 210f336e9cSThomas Zimmermann * The above copyright notice and this permission notice (including the 220f336e9cSThomas Zimmermann * next paragraph) shall be included in all copies or substantial portions 230f336e9cSThomas Zimmermann * of the Software. 240f336e9cSThomas Zimmermann */ 250f336e9cSThomas Zimmermann /* 260f336e9cSThomas Zimmermann * Authors: Dave Airlie <airlied@redhat.com> 270f336e9cSThomas Zimmermann */ 280f336e9cSThomas Zimmermann 290f336e9cSThomas Zimmermann #include <linux/delay.h> 300f336e9cSThomas Zimmermann 310f336e9cSThomas Zimmermann #include "ast_drv.h" 320f336e9cSThomas Zimmermann #include "ast_post.h" 330f336e9cSThomas Zimmermann 340f336e9cSThomas Zimmermann /* 350f336e9cSThomas Zimmermann * POST 360f336e9cSThomas Zimmermann */ 370f336e9cSThomas Zimmermann 38*b1ce4ab0SThomas Zimmermann void ast_2300_set_def_ext_reg(struct ast_device *ast) 39*b1ce4ab0SThomas Zimmermann { 40*b1ce4ab0SThomas Zimmermann static const u8 extreginfo[] = { 0x0f, 0x04, 0x1f, 0xff }; 41*b1ce4ab0SThomas Zimmermann u8 i, index, reg; 42*b1ce4ab0SThomas Zimmermann const u8 *ext_reg_info; 43*b1ce4ab0SThomas Zimmermann 44*b1ce4ab0SThomas Zimmermann /* reset scratch */ 45*b1ce4ab0SThomas Zimmermann for (i = 0x81; i <= 0x9f; i++) 46*b1ce4ab0SThomas Zimmermann ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00); 47*b1ce4ab0SThomas Zimmermann 48*b1ce4ab0SThomas Zimmermann ext_reg_info = extreginfo; 49*b1ce4ab0SThomas Zimmermann index = 0xa0; 50*b1ce4ab0SThomas Zimmermann while (*ext_reg_info != 0xff) { 51*b1ce4ab0SThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info); 52*b1ce4ab0SThomas Zimmermann index++; 53*b1ce4ab0SThomas Zimmermann ext_reg_info++; 54*b1ce4ab0SThomas Zimmermann } 55*b1ce4ab0SThomas Zimmermann 56*b1ce4ab0SThomas Zimmermann /* disable standard IO/MEM decode if secondary */ 57*b1ce4ab0SThomas Zimmermann /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */ 58*b1ce4ab0SThomas Zimmermann 59*b1ce4ab0SThomas Zimmermann /* Set Ext. Default */ 60*b1ce4ab0SThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01); 61*b1ce4ab0SThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00); 62*b1ce4ab0SThomas Zimmermann 63*b1ce4ab0SThomas Zimmermann /* Enable RAMDAC for A1 */ 64*b1ce4ab0SThomas Zimmermann reg = 0x04; 65*b1ce4ab0SThomas Zimmermann reg |= 0x20; 66*b1ce4ab0SThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg); 67*b1ce4ab0SThomas Zimmermann } 68*b1ce4ab0SThomas Zimmermann 690f336e9cSThomas Zimmermann /* AST 2300 DRAM settings */ 700f336e9cSThomas Zimmermann #define AST_DDR3 0 710f336e9cSThomas Zimmermann #define AST_DDR2 1 720f336e9cSThomas Zimmermann 730f336e9cSThomas Zimmermann struct ast2300_dram_param { 740f336e9cSThomas Zimmermann u32 dram_type; 750f336e9cSThomas Zimmermann u32 dram_chipid; 760f336e9cSThomas Zimmermann u32 dram_freq; 770f336e9cSThomas Zimmermann u32 vram_size; 780f336e9cSThomas Zimmermann u32 odt; 790f336e9cSThomas Zimmermann u32 wodt; 800f336e9cSThomas Zimmermann u32 rodt; 810f336e9cSThomas Zimmermann u32 dram_config; 820f336e9cSThomas Zimmermann u32 reg_PERIOD; 830f336e9cSThomas Zimmermann u32 reg_MADJ; 840f336e9cSThomas Zimmermann u32 reg_SADJ; 850f336e9cSThomas Zimmermann u32 reg_MRS; 860f336e9cSThomas Zimmermann u32 reg_EMRS; 870f336e9cSThomas Zimmermann u32 reg_AC1; 880f336e9cSThomas Zimmermann u32 reg_AC2; 890f336e9cSThomas Zimmermann u32 reg_DQSIC; 900f336e9cSThomas Zimmermann u32 reg_DRV; 910f336e9cSThomas Zimmermann u32 reg_IOZ; 920f336e9cSThomas Zimmermann u32 reg_DQIDLY; 930f336e9cSThomas Zimmermann u32 reg_FREQ; 940f336e9cSThomas Zimmermann u32 madj_max; 950f336e9cSThomas Zimmermann u32 dll2_finetune_step; 960f336e9cSThomas Zimmermann }; 970f336e9cSThomas Zimmermann 980f336e9cSThomas Zimmermann /* 990f336e9cSThomas Zimmermann * DQSI DLL CBR Setting 1000f336e9cSThomas Zimmermann */ 1010f336e9cSThomas Zimmermann #define CBR_SIZE0 ((1 << 10) - 1) 1020f336e9cSThomas Zimmermann #define CBR_SIZE1 ((4 << 10) - 1) 1030f336e9cSThomas Zimmermann #define CBR_SIZE2 ((64 << 10) - 1) 1040f336e9cSThomas Zimmermann #define CBR_PASSNUM 5 1050f336e9cSThomas Zimmermann #define CBR_PASSNUM2 5 1060f336e9cSThomas Zimmermann #define CBR_THRESHOLD 10 1070f336e9cSThomas Zimmermann #define CBR_THRESHOLD2 10 1080f336e9cSThomas Zimmermann #define TIMEOUT 5000000 1090f336e9cSThomas Zimmermann #define CBR_PATNUM 8 1100f336e9cSThomas Zimmermann 1110f336e9cSThomas Zimmermann static const u32 pattern[8] = { 1120f336e9cSThomas Zimmermann 0xFF00FF00, 1130f336e9cSThomas Zimmermann 0xCC33CC33, 1140f336e9cSThomas Zimmermann 0xAA55AA55, 1150f336e9cSThomas Zimmermann 0x88778877, 1160f336e9cSThomas Zimmermann 0x92CC4D6E, 1170f336e9cSThomas Zimmermann 0x543D3CDE, 1180f336e9cSThomas Zimmermann 0xF1E843C7, 1190f336e9cSThomas Zimmermann 0x7C61D253 1200f336e9cSThomas Zimmermann }; 1210f336e9cSThomas Zimmermann 1220f336e9cSThomas Zimmermann static u32 mmc_test2(struct ast_device *ast, u32 datagen, u8 test_ctl) 1230f336e9cSThomas Zimmermann { 1240f336e9cSThomas Zimmermann u32 data, timeout; 1250f336e9cSThomas Zimmermann 1260f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e0070, 0x00000000); 1270f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e0070, (datagen << 3) | test_ctl); 1280f336e9cSThomas Zimmermann timeout = 0; 1290f336e9cSThomas Zimmermann do { 1300f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1e6e0070) & 0x1000; 1310f336e9cSThomas Zimmermann if (++timeout > TIMEOUT) { 1320f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e0070, 0x0); 1330f336e9cSThomas Zimmermann return 0xffffffff; 1340f336e9cSThomas Zimmermann } 1350f336e9cSThomas Zimmermann } while (!data); 1360f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1e6e0078); 1370f336e9cSThomas Zimmermann data = (data | (data >> 16)) & 0xffff; 1380f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e0070, 0x00000000); 1390f336e9cSThomas Zimmermann return data; 1400f336e9cSThomas Zimmermann } 1410f336e9cSThomas Zimmermann 1420f336e9cSThomas Zimmermann static u32 mmc_test_burst2(struct ast_device *ast, u32 datagen) 1430f336e9cSThomas Zimmermann { 1440f336e9cSThomas Zimmermann return mmc_test2(ast, datagen, 0x41); 1450f336e9cSThomas Zimmermann } 1460f336e9cSThomas Zimmermann 1470f336e9cSThomas Zimmermann static bool mmc_test_single(struct ast_device *ast, u32 datagen) 1480f336e9cSThomas Zimmermann { 1490f336e9cSThomas Zimmermann return mmc_test(ast, datagen, 0xc5); 1500f336e9cSThomas Zimmermann } 1510f336e9cSThomas Zimmermann 1520f336e9cSThomas Zimmermann static u32 mmc_test_single2(struct ast_device *ast, u32 datagen) 1530f336e9cSThomas Zimmermann { 1540f336e9cSThomas Zimmermann return mmc_test2(ast, datagen, 0x05); 1550f336e9cSThomas Zimmermann } 1560f336e9cSThomas Zimmermann 1570f336e9cSThomas Zimmermann static int cbr_test(struct ast_device *ast) 1580f336e9cSThomas Zimmermann { 1590f336e9cSThomas Zimmermann u32 data; 1600f336e9cSThomas Zimmermann int i; 1610f336e9cSThomas Zimmermann 1620f336e9cSThomas Zimmermann data = mmc_test_single2(ast, 0); 1630f336e9cSThomas Zimmermann if ((data & 0xff) && (data & 0xff00)) 1640f336e9cSThomas Zimmermann return 0; 1650f336e9cSThomas Zimmermann for (i = 0; i < 8; i++) { 1660f336e9cSThomas Zimmermann data = mmc_test_burst2(ast, i); 1670f336e9cSThomas Zimmermann if ((data & 0xff) && (data & 0xff00)) 1680f336e9cSThomas Zimmermann return 0; 1690f336e9cSThomas Zimmermann } 1700f336e9cSThomas Zimmermann if (!data) 1710f336e9cSThomas Zimmermann return 3; 1720f336e9cSThomas Zimmermann else if (data & 0xff) 1730f336e9cSThomas Zimmermann return 2; 1740f336e9cSThomas Zimmermann return 1; 1750f336e9cSThomas Zimmermann } 1760f336e9cSThomas Zimmermann 1770f336e9cSThomas Zimmermann static int cbr_scan(struct ast_device *ast) 1780f336e9cSThomas Zimmermann { 1790f336e9cSThomas Zimmermann u32 data, data2, patcnt, loop; 1800f336e9cSThomas Zimmermann 1810f336e9cSThomas Zimmermann data2 = 3; 1820f336e9cSThomas Zimmermann for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 1830f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 1840f336e9cSThomas Zimmermann for (loop = 0; loop < CBR_PASSNUM2; loop++) { 1850f336e9cSThomas Zimmermann data = cbr_test(ast); 1860f336e9cSThomas Zimmermann if (data != 0) { 1870f336e9cSThomas Zimmermann data2 &= data; 1880f336e9cSThomas Zimmermann if (!data2) 1890f336e9cSThomas Zimmermann return 0; 1900f336e9cSThomas Zimmermann break; 1910f336e9cSThomas Zimmermann } 1920f336e9cSThomas Zimmermann } 1930f336e9cSThomas Zimmermann if (loop == CBR_PASSNUM2) 1940f336e9cSThomas Zimmermann return 0; 1950f336e9cSThomas Zimmermann } 1960f336e9cSThomas Zimmermann return data2; 1970f336e9cSThomas Zimmermann } 1980f336e9cSThomas Zimmermann 1990f336e9cSThomas Zimmermann static u32 cbr_test2(struct ast_device *ast) 2000f336e9cSThomas Zimmermann { 2010f336e9cSThomas Zimmermann u32 data; 2020f336e9cSThomas Zimmermann 2030f336e9cSThomas Zimmermann data = mmc_test_burst2(ast, 0); 2040f336e9cSThomas Zimmermann if (data == 0xffff) 2050f336e9cSThomas Zimmermann return 0; 2060f336e9cSThomas Zimmermann data |= mmc_test_single2(ast, 0); 2070f336e9cSThomas Zimmermann if (data == 0xffff) 2080f336e9cSThomas Zimmermann return 0; 2090f336e9cSThomas Zimmermann 2100f336e9cSThomas Zimmermann return ~data & 0xffff; 2110f336e9cSThomas Zimmermann } 2120f336e9cSThomas Zimmermann 2130f336e9cSThomas Zimmermann static u32 cbr_scan2(struct ast_device *ast) 2140f336e9cSThomas Zimmermann { 2150f336e9cSThomas Zimmermann u32 data, data2, patcnt, loop; 2160f336e9cSThomas Zimmermann 2170f336e9cSThomas Zimmermann data2 = 0xffff; 2180f336e9cSThomas Zimmermann for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 2190f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 2200f336e9cSThomas Zimmermann for (loop = 0; loop < CBR_PASSNUM2; loop++) { 2210f336e9cSThomas Zimmermann data = cbr_test2(ast); 2220f336e9cSThomas Zimmermann if (data != 0) { 2230f336e9cSThomas Zimmermann data2 &= data; 2240f336e9cSThomas Zimmermann if (!data2) 2250f336e9cSThomas Zimmermann return 0; 2260f336e9cSThomas Zimmermann break; 2270f336e9cSThomas Zimmermann } 2280f336e9cSThomas Zimmermann } 2290f336e9cSThomas Zimmermann if (loop == CBR_PASSNUM2) 2300f336e9cSThomas Zimmermann return 0; 2310f336e9cSThomas Zimmermann } 2320f336e9cSThomas Zimmermann return data2; 2330f336e9cSThomas Zimmermann } 2340f336e9cSThomas Zimmermann 2350f336e9cSThomas Zimmermann static bool cbr_test3(struct ast_device *ast) 2360f336e9cSThomas Zimmermann { 2370f336e9cSThomas Zimmermann if (!mmc_test_burst(ast, 0)) 2380f336e9cSThomas Zimmermann return false; 2390f336e9cSThomas Zimmermann if (!mmc_test_single(ast, 0)) 2400f336e9cSThomas Zimmermann return false; 2410f336e9cSThomas Zimmermann return true; 2420f336e9cSThomas Zimmermann } 2430f336e9cSThomas Zimmermann 2440f336e9cSThomas Zimmermann static bool cbr_scan3(struct ast_device *ast) 2450f336e9cSThomas Zimmermann { 2460f336e9cSThomas Zimmermann u32 patcnt, loop; 2470f336e9cSThomas Zimmermann 2480f336e9cSThomas Zimmermann for (patcnt = 0; patcnt < CBR_PATNUM; patcnt++) { 2490f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e007c, pattern[patcnt]); 2500f336e9cSThomas Zimmermann for (loop = 0; loop < 2; loop++) { 2510f336e9cSThomas Zimmermann if (cbr_test3(ast)) 2520f336e9cSThomas Zimmermann break; 2530f336e9cSThomas Zimmermann } 2540f336e9cSThomas Zimmermann if (loop == 2) 2550f336e9cSThomas Zimmermann return false; 2560f336e9cSThomas Zimmermann } 2570f336e9cSThomas Zimmermann return true; 2580f336e9cSThomas Zimmermann } 2590f336e9cSThomas Zimmermann 2600f336e9cSThomas Zimmermann static bool finetuneDQI_L(struct ast_device *ast, struct ast2300_dram_param *param) 2610f336e9cSThomas Zimmermann { 2620f336e9cSThomas Zimmermann u32 gold_sadj[2], dllmin[16], dllmax[16], dlli, data, cnt, mask, passcnt, retry = 0; 2630f336e9cSThomas Zimmermann bool status = false; 2640f336e9cSThomas Zimmermann FINETUNE_START: 2650f336e9cSThomas Zimmermann for (cnt = 0; cnt < 16; cnt++) { 2660f336e9cSThomas Zimmermann dllmin[cnt] = 0xff; 2670f336e9cSThomas Zimmermann dllmax[cnt] = 0x0; 2680f336e9cSThomas Zimmermann } 2690f336e9cSThomas Zimmermann passcnt = 0; 2700f336e9cSThomas Zimmermann for (dlli = 0; dlli < 76; dlli++) { 2710f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, 0x00001400 | (dlli << 16) | (dlli << 24)); 2720f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE1); 2730f336e9cSThomas Zimmermann data = cbr_scan2(ast); 2740f336e9cSThomas Zimmermann if (data != 0) { 2750f336e9cSThomas Zimmermann mask = 0x00010001; 2760f336e9cSThomas Zimmermann for (cnt = 0; cnt < 16; cnt++) { 2770f336e9cSThomas Zimmermann if (data & mask) { 2780f336e9cSThomas Zimmermann if (dllmin[cnt] > dlli) 2790f336e9cSThomas Zimmermann dllmin[cnt] = dlli; 2800f336e9cSThomas Zimmermann if (dllmax[cnt] < dlli) 2810f336e9cSThomas Zimmermann dllmax[cnt] = dlli; 2820f336e9cSThomas Zimmermann } 2830f336e9cSThomas Zimmermann mask <<= 1; 2840f336e9cSThomas Zimmermann } 2850f336e9cSThomas Zimmermann passcnt++; 2860f336e9cSThomas Zimmermann } else if (passcnt >= CBR_THRESHOLD2) { 2870f336e9cSThomas Zimmermann break; 2880f336e9cSThomas Zimmermann } 2890f336e9cSThomas Zimmermann } 2900f336e9cSThomas Zimmermann gold_sadj[0] = 0x0; 2910f336e9cSThomas Zimmermann passcnt = 0; 2920f336e9cSThomas Zimmermann for (cnt = 0; cnt < 16; cnt++) { 2930f336e9cSThomas Zimmermann if ((dllmax[cnt] > dllmin[cnt]) && 2940f336e9cSThomas Zimmermann ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 2950f336e9cSThomas Zimmermann gold_sadj[0] += dllmin[cnt]; 2960f336e9cSThomas Zimmermann passcnt++; 2970f336e9cSThomas Zimmermann } 2980f336e9cSThomas Zimmermann } 2990f336e9cSThomas Zimmermann if (retry++ > 10) 3000f336e9cSThomas Zimmermann goto FINETUNE_DONE; 3010f336e9cSThomas Zimmermann if (passcnt != 16) 3020f336e9cSThomas Zimmermann goto FINETUNE_START; 3030f336e9cSThomas Zimmermann status = true; 3040f336e9cSThomas Zimmermann FINETUNE_DONE: 3050f336e9cSThomas Zimmermann gold_sadj[0] = gold_sadj[0] >> 4; 3060f336e9cSThomas Zimmermann gold_sadj[1] = gold_sadj[0]; 3070f336e9cSThomas Zimmermann 3080f336e9cSThomas Zimmermann data = 0; 3090f336e9cSThomas Zimmermann for (cnt = 0; cnt < 8; cnt++) { 3100f336e9cSThomas Zimmermann data >>= 3; 3110f336e9cSThomas Zimmermann if ((dllmax[cnt] > dllmin[cnt]) && 3120f336e9cSThomas Zimmermann ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 3130f336e9cSThomas Zimmermann dlli = dllmin[cnt]; 3140f336e9cSThomas Zimmermann if (gold_sadj[0] >= dlli) { 3150f336e9cSThomas Zimmermann dlli = ((gold_sadj[0] - dlli) * 19) >> 5; 3160f336e9cSThomas Zimmermann if (dlli > 3) 3170f336e9cSThomas Zimmermann dlli = 3; 3180f336e9cSThomas Zimmermann } else { 3190f336e9cSThomas Zimmermann dlli = ((dlli - gold_sadj[0]) * 19) >> 5; 3200f336e9cSThomas Zimmermann if (dlli > 4) 3210f336e9cSThomas Zimmermann dlli = 4; 3220f336e9cSThomas Zimmermann dlli = (8 - dlli) & 0x7; 3230f336e9cSThomas Zimmermann } 3240f336e9cSThomas Zimmermann data |= dlli << 21; 3250f336e9cSThomas Zimmermann } 3260f336e9cSThomas Zimmermann } 3270f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0080, data); 3280f336e9cSThomas Zimmermann 3290f336e9cSThomas Zimmermann data = 0; 3300f336e9cSThomas Zimmermann for (cnt = 8; cnt < 16; cnt++) { 3310f336e9cSThomas Zimmermann data >>= 3; 3320f336e9cSThomas Zimmermann if ((dllmax[cnt] > dllmin[cnt]) && 3330f336e9cSThomas Zimmermann ((dllmax[cnt] - dllmin[cnt]) >= CBR_THRESHOLD2)) { 3340f336e9cSThomas Zimmermann dlli = dllmin[cnt]; 3350f336e9cSThomas Zimmermann if (gold_sadj[1] >= dlli) { 3360f336e9cSThomas Zimmermann dlli = ((gold_sadj[1] - dlli) * 19) >> 5; 3370f336e9cSThomas Zimmermann if (dlli > 3) 3380f336e9cSThomas Zimmermann dlli = 3; 3390f336e9cSThomas Zimmermann else 3400f336e9cSThomas Zimmermann dlli = (dlli - 1) & 0x7; 3410f336e9cSThomas Zimmermann } else { 3420f336e9cSThomas Zimmermann dlli = ((dlli - gold_sadj[1]) * 19) >> 5; 3430f336e9cSThomas Zimmermann dlli += 1; 3440f336e9cSThomas Zimmermann if (dlli > 4) 3450f336e9cSThomas Zimmermann dlli = 4; 3460f336e9cSThomas Zimmermann dlli = (8 - dlli) & 0x7; 3470f336e9cSThomas Zimmermann } 3480f336e9cSThomas Zimmermann data |= dlli << 21; 3490f336e9cSThomas Zimmermann } 3500f336e9cSThomas Zimmermann } 3510f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0084, data); 3520f336e9cSThomas Zimmermann return status; 3530f336e9cSThomas Zimmermann } /* finetuneDQI_L */ 3540f336e9cSThomas Zimmermann 3550f336e9cSThomas Zimmermann static void finetuneDQSI(struct ast_device *ast) 3560f336e9cSThomas Zimmermann { 3570f336e9cSThomas Zimmermann u32 dlli, dqsip, dqidly; 3580f336e9cSThomas Zimmermann u32 reg_mcr18, reg_mcr0c, passcnt[2], diff; 3590f336e9cSThomas Zimmermann u32 g_dqidly, g_dqsip, g_margin, g_side; 3600f336e9cSThomas Zimmermann u16 pass[32][2][2]; 3610f336e9cSThomas Zimmermann char tag[2][76]; 3620f336e9cSThomas Zimmermann 3630f336e9cSThomas Zimmermann /* Disable DQI CBR */ 3640f336e9cSThomas Zimmermann reg_mcr0c = ast_mindwm(ast, 0x1E6E000C); 3650f336e9cSThomas Zimmermann reg_mcr18 = ast_mindwm(ast, 0x1E6E0018); 3660f336e9cSThomas Zimmermann reg_mcr18 &= 0x0000ffff; 3670f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); 3680f336e9cSThomas Zimmermann 3690f336e9cSThomas Zimmermann for (dlli = 0; dlli < 76; dlli++) { 3700f336e9cSThomas Zimmermann tag[0][dlli] = 0x0; 3710f336e9cSThomas Zimmermann tag[1][dlli] = 0x0; 3720f336e9cSThomas Zimmermann } 3730f336e9cSThomas Zimmermann for (dqidly = 0; dqidly < 32; dqidly++) { 3740f336e9cSThomas Zimmermann pass[dqidly][0][0] = 0xff; 3750f336e9cSThomas Zimmermann pass[dqidly][0][1] = 0x0; 3760f336e9cSThomas Zimmermann pass[dqidly][1][0] = 0xff; 3770f336e9cSThomas Zimmermann pass[dqidly][1][1] = 0x0; 3780f336e9cSThomas Zimmermann } 3790f336e9cSThomas Zimmermann for (dqidly = 0; dqidly < 32; dqidly++) { 3800f336e9cSThomas Zimmermann passcnt[0] = 0; 3810f336e9cSThomas Zimmermann passcnt[1] = 0; 3820f336e9cSThomas Zimmermann for (dqsip = 0; dqsip < 2; dqsip++) { 3830f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0); 3840f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, reg_mcr18 | (dqidly << 16) | (dqsip << 23)); 3850f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, reg_mcr0c); 3860f336e9cSThomas Zimmermann for (dlli = 0; dlli < 76; dlli++) { 3870f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, 3880f336e9cSThomas Zimmermann 0x00001300 | (dlli << 16) | (dlli << 24)); 3890f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0); 3900f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE0); 3910f336e9cSThomas Zimmermann if (cbr_scan3(ast)) { 3920f336e9cSThomas Zimmermann if (dlli == 0) 3930f336e9cSThomas Zimmermann break; 3940f336e9cSThomas Zimmermann passcnt[dqsip]++; 3950f336e9cSThomas Zimmermann tag[dqsip][dlli] = 'P'; 3960f336e9cSThomas Zimmermann if (dlli < pass[dqidly][dqsip][0]) 3970f336e9cSThomas Zimmermann pass[dqidly][dqsip][0] = (u16)dlli; 3980f336e9cSThomas Zimmermann if (dlli > pass[dqidly][dqsip][1]) 3990f336e9cSThomas Zimmermann pass[dqidly][dqsip][1] = (u16)dlli; 4000f336e9cSThomas Zimmermann } else if (passcnt[dqsip] >= 5) { 4010f336e9cSThomas Zimmermann break; 4020f336e9cSThomas Zimmermann } else { 4030f336e9cSThomas Zimmermann pass[dqidly][dqsip][0] = 0xff; 4040f336e9cSThomas Zimmermann pass[dqidly][dqsip][1] = 0x0; 4050f336e9cSThomas Zimmermann } 4060f336e9cSThomas Zimmermann } 4070f336e9cSThomas Zimmermann } 4080f336e9cSThomas Zimmermann if (passcnt[0] == 0 && passcnt[1] == 0) 4090f336e9cSThomas Zimmermann dqidly++; 4100f336e9cSThomas Zimmermann } 4110f336e9cSThomas Zimmermann /* Search margin */ 4120f336e9cSThomas Zimmermann g_dqidly = 0; 4130f336e9cSThomas Zimmermann g_dqsip = 0; 4140f336e9cSThomas Zimmermann g_margin = 0; 4150f336e9cSThomas Zimmermann g_side = 0; 4160f336e9cSThomas Zimmermann 4170f336e9cSThomas Zimmermann for (dqidly = 0; dqidly < 32; dqidly++) { 4180f336e9cSThomas Zimmermann for (dqsip = 0; dqsip < 2; dqsip++) { 4190f336e9cSThomas Zimmermann if (pass[dqidly][dqsip][0] > pass[dqidly][dqsip][1]) 4200f336e9cSThomas Zimmermann continue; 4210f336e9cSThomas Zimmermann diff = pass[dqidly][dqsip][1] - pass[dqidly][dqsip][0]; 4220f336e9cSThomas Zimmermann if ((diff + 2) < g_margin) 4230f336e9cSThomas Zimmermann continue; 4240f336e9cSThomas Zimmermann passcnt[0] = 0; 4250f336e9cSThomas Zimmermann passcnt[1] = 0; 4260f336e9cSThomas Zimmermann for (dlli = pass[dqidly][dqsip][0]; 4270f336e9cSThomas Zimmermann dlli > 0 && tag[dqsip][dlli] != 0; 4280f336e9cSThomas Zimmermann dlli--, passcnt[0]++) { 4290f336e9cSThomas Zimmermann } 4300f336e9cSThomas Zimmermann for (dlli = pass[dqidly][dqsip][1]; 4310f336e9cSThomas Zimmermann dlli < 76 && tag[dqsip][dlli] != 0; 4320f336e9cSThomas Zimmermann dlli++, passcnt[1]++) { 4330f336e9cSThomas Zimmermann } 4340f336e9cSThomas Zimmermann if (passcnt[0] > passcnt[1]) 4350f336e9cSThomas Zimmermann passcnt[0] = passcnt[1]; 4360f336e9cSThomas Zimmermann passcnt[1] = 0; 4370f336e9cSThomas Zimmermann if (passcnt[0] > g_side) 4380f336e9cSThomas Zimmermann passcnt[1] = passcnt[0] - g_side; 4390f336e9cSThomas Zimmermann if (diff > (g_margin + 1) && (passcnt[1] > 0 || passcnt[0] > 8)) { 4400f336e9cSThomas Zimmermann g_margin = diff; 4410f336e9cSThomas Zimmermann g_dqidly = dqidly; 4420f336e9cSThomas Zimmermann g_dqsip = dqsip; 4430f336e9cSThomas Zimmermann g_side = passcnt[0]; 4440f336e9cSThomas Zimmermann } else if (passcnt[1] > 1 && g_side < 8) { 4450f336e9cSThomas Zimmermann if (diff > g_margin) 4460f336e9cSThomas Zimmermann g_margin = diff; 4470f336e9cSThomas Zimmermann g_dqidly = dqidly; 4480f336e9cSThomas Zimmermann g_dqsip = dqsip; 4490f336e9cSThomas Zimmermann g_side = passcnt[0]; 4500f336e9cSThomas Zimmermann } 4510f336e9cSThomas Zimmermann } 4520f336e9cSThomas Zimmermann } 4530f336e9cSThomas Zimmermann reg_mcr18 = reg_mcr18 | (g_dqidly << 16) | (g_dqsip << 23); 4540f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, reg_mcr18); 4550f336e9cSThomas Zimmermann } 4560f336e9cSThomas Zimmermann 4570f336e9cSThomas Zimmermann static bool cbr_dll2(struct ast_device *ast, struct ast2300_dram_param *param) 4580f336e9cSThomas Zimmermann { 4590f336e9cSThomas Zimmermann u32 dllmin[2], dllmax[2], dlli, data, passcnt, retry = 0; 4600f336e9cSThomas Zimmermann bool status = false; 4610f336e9cSThomas Zimmermann 4620f336e9cSThomas Zimmermann finetuneDQSI(ast); 4630f336e9cSThomas Zimmermann if (finetuneDQI_L(ast, param) == false) 4640f336e9cSThomas Zimmermann return status; 4650f336e9cSThomas Zimmermann 4660f336e9cSThomas Zimmermann CBR_START2: 4670f336e9cSThomas Zimmermann dllmin[0] = 0xff; 4680f336e9cSThomas Zimmermann dllmin[1] = 0xff; 4690f336e9cSThomas Zimmermann dllmax[0] = 0x0; 4700f336e9cSThomas Zimmermann dllmax[1] = 0x0; 4710f336e9cSThomas Zimmermann passcnt = 0; 4720f336e9cSThomas Zimmermann for (dlli = 0; dlli < 76; dlli++) { 4730f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, 0x00001300 | (dlli << 16) | (dlli << 24)); 4740f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, CBR_SIZE2); 4750f336e9cSThomas Zimmermann data = cbr_scan(ast); 4760f336e9cSThomas Zimmermann if (data != 0) { 4770f336e9cSThomas Zimmermann if (data & 0x1) { 4780f336e9cSThomas Zimmermann if (dllmin[0] > dlli) 4790f336e9cSThomas Zimmermann dllmin[0] = dlli; 4800f336e9cSThomas Zimmermann if (dllmax[0] < dlli) 4810f336e9cSThomas Zimmermann dllmax[0] = dlli; 4820f336e9cSThomas Zimmermann } 4830f336e9cSThomas Zimmermann if (data & 0x2) { 4840f336e9cSThomas Zimmermann if (dllmin[1] > dlli) 4850f336e9cSThomas Zimmermann dllmin[1] = dlli; 4860f336e9cSThomas Zimmermann if (dllmax[1] < dlli) 4870f336e9cSThomas Zimmermann dllmax[1] = dlli; 4880f336e9cSThomas Zimmermann } 4890f336e9cSThomas Zimmermann passcnt++; 4900f336e9cSThomas Zimmermann } else if (passcnt >= CBR_THRESHOLD) { 4910f336e9cSThomas Zimmermann break; 4920f336e9cSThomas Zimmermann } 4930f336e9cSThomas Zimmermann } 4940f336e9cSThomas Zimmermann if (retry++ > 10) 4950f336e9cSThomas Zimmermann goto CBR_DONE2; 4960f336e9cSThomas Zimmermann if (dllmax[0] == 0 || (dllmax[0] - dllmin[0]) < CBR_THRESHOLD) 4970f336e9cSThomas Zimmermann goto CBR_START2; 4980f336e9cSThomas Zimmermann if (dllmax[1] == 0 || (dllmax[1] - dllmin[1]) < CBR_THRESHOLD) 4990f336e9cSThomas Zimmermann goto CBR_START2; 5000f336e9cSThomas Zimmermann status = true; 5010f336e9cSThomas Zimmermann CBR_DONE2: 5020f336e9cSThomas Zimmermann dlli = (dllmin[1] + dllmax[1]) >> 1; 5030f336e9cSThomas Zimmermann dlli <<= 8; 5040f336e9cSThomas Zimmermann dlli += (dllmin[0] + dllmax[0]) >> 1; 5050f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, ast_mindwm(ast, 0x1E720058) | (dlli << 16)); 5060f336e9cSThomas Zimmermann return status; 5070f336e9cSThomas Zimmermann } /* CBRDLL2 */ 5080f336e9cSThomas Zimmermann 5090f336e9cSThomas Zimmermann static void get_ddr3_info(struct ast_device *ast, struct ast2300_dram_param *param) 5100f336e9cSThomas Zimmermann { 5110f336e9cSThomas Zimmermann u32 trap, trap_AC2, trap_MRS; 5120f336e9cSThomas Zimmermann 5130f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); 5140f336e9cSThomas Zimmermann 5150f336e9cSThomas Zimmermann /* Ger trap info */ 5160f336e9cSThomas Zimmermann trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; 5170f336e9cSThomas Zimmermann trap_AC2 = 0x00020000 + (trap << 16); 5180f336e9cSThomas Zimmermann trap_AC2 |= 0x00300000 + ((trap & 0x2) << 19); 5190f336e9cSThomas Zimmermann trap_MRS = 0x00000010 + (trap << 4); 5200f336e9cSThomas Zimmermann trap_MRS |= ((trap & 0x2) << 18); 5210f336e9cSThomas Zimmermann 5220f336e9cSThomas Zimmermann param->reg_MADJ = 0x00034C4C; 5230f336e9cSThomas Zimmermann param->reg_SADJ = 0x00001800; 5240f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F0; 5250f336e9cSThomas Zimmermann param->reg_PERIOD = param->dram_freq; 5260f336e9cSThomas Zimmermann param->rodt = 0; 5270f336e9cSThomas Zimmermann 5280f336e9cSThomas Zimmermann switch (param->dram_freq) { 5290f336e9cSThomas Zimmermann case 336: 5300f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0190); 5310f336e9cSThomas Zimmermann param->wodt = 0; 5320f336e9cSThomas Zimmermann param->reg_AC1 = 0x22202725; 5330f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA007613 | trap_AC2; 5340f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000BA; 5350f336e9cSThomas Zimmermann param->reg_MRS = 0x04001400 | trap_MRS; 5360f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 5370f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000023; 5380f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000074; 5390f336e9cSThomas Zimmermann param->reg_FREQ = 0x00004DC0; 5400f336e9cSThomas Zimmermann param->madj_max = 96; 5410f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 5420f336e9cSThomas Zimmermann switch (param->dram_chipid) { 5430f336e9cSThomas Zimmermann default: 5440f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 5450f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 5460f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA007613 | trap_AC2; 5470f336e9cSThomas Zimmermann break; 5480f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 5490f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA00761C | trap_AC2; 5500f336e9cSThomas Zimmermann break; 5510f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 5520f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA007636 | trap_AC2; 5530f336e9cSThomas Zimmermann break; 5540f336e9cSThomas Zimmermann } 5550f336e9cSThomas Zimmermann break; 5560f336e9cSThomas Zimmermann default: 5570f336e9cSThomas Zimmermann case 396: 5580f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x03F1); 5590f336e9cSThomas Zimmermann param->wodt = 1; 5600f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302825; 5610f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009617 | trap_AC2; 5620f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000E2; 5630f336e9cSThomas Zimmermann param->reg_MRS = 0x04001600 | trap_MRS; 5640f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 5650f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 5660f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 5670f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000089; 5680f336e9cSThomas Zimmermann param->reg_FREQ = 0x00005040; 5690f336e9cSThomas Zimmermann param->madj_max = 96; 5700f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 5710f336e9cSThomas Zimmermann 5720f336e9cSThomas Zimmermann switch (param->dram_chipid) { 5730f336e9cSThomas Zimmermann default: 5740f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 5750f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 5760f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009617 | trap_AC2; 5770f336e9cSThomas Zimmermann break; 5780f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 5790f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009622 | trap_AC2; 5800f336e9cSThomas Zimmermann break; 5810f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 5820f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00963F | trap_AC2; 5830f336e9cSThomas Zimmermann break; 5840f336e9cSThomas Zimmermann } 5850f336e9cSThomas Zimmermann break; 5860f336e9cSThomas Zimmermann 5870f336e9cSThomas Zimmermann case 408: 5880f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x01F0); 5890f336e9cSThomas Zimmermann param->wodt = 1; 5900f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302825; 5910f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009617 | trap_AC2; 5920f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000E2; 5930f336e9cSThomas Zimmermann param->reg_MRS = 0x04001600 | trap_MRS; 5940f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 5950f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000023; 5960f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 5970f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000089; 5980f336e9cSThomas Zimmermann param->reg_FREQ = 0x000050C0; 5990f336e9cSThomas Zimmermann param->madj_max = 96; 6000f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 6010f336e9cSThomas Zimmermann 6020f336e9cSThomas Zimmermann switch (param->dram_chipid) { 6030f336e9cSThomas Zimmermann default: 6040f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 6050f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 6060f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009617 | trap_AC2; 6070f336e9cSThomas Zimmermann break; 6080f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 6090f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC009622 | trap_AC2; 6100f336e9cSThomas Zimmermann break; 6110f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 6120f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00963F | trap_AC2; 6130f336e9cSThomas Zimmermann break; 6140f336e9cSThomas Zimmermann } 6150f336e9cSThomas Zimmermann 6160f336e9cSThomas Zimmermann break; 6170f336e9cSThomas Zimmermann case 456: 6180f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0230); 6190f336e9cSThomas Zimmermann param->wodt = 0; 6200f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302926; 6210f336e9cSThomas Zimmermann param->reg_AC2 = 0xCD44961A; 6220f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000FC; 6230f336e9cSThomas Zimmermann param->reg_MRS = 0x00081830; 6240f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 6250f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000045; 6260f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000097; 6270f336e9cSThomas Zimmermann param->reg_FREQ = 0x000052C0; 6280f336e9cSThomas Zimmermann param->madj_max = 88; 6290f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 6300f336e9cSThomas Zimmermann break; 6310f336e9cSThomas Zimmermann case 504: 6320f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0270); 6330f336e9cSThomas Zimmermann param->wodt = 1; 6340f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302926; 6350f336e9cSThomas Zimmermann param->reg_AC2 = 0xDE44A61D; 6360f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000117; 6370f336e9cSThomas Zimmermann param->reg_MRS = 0x00081A30; 6380f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 6390f336e9cSThomas Zimmermann param->reg_IOZ = 0x070000BB; 6400f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x000000A0; 6410f336e9cSThomas Zimmermann param->reg_FREQ = 0x000054C0; 6420f336e9cSThomas Zimmermann param->madj_max = 79; 6430f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 6440f336e9cSThomas Zimmermann break; 6450f336e9cSThomas Zimmermann case 528: 6460f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0290); 6470f336e9cSThomas Zimmermann param->wodt = 1; 6480f336e9cSThomas Zimmermann param->rodt = 1; 6490f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302926; 6500f336e9cSThomas Zimmermann param->reg_AC2 = 0xEF44B61E; 6510f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000125; 6520f336e9cSThomas Zimmermann param->reg_MRS = 0x00081A30; 6530f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 6540f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F5; 6550f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000023; 6560f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000088; 6570f336e9cSThomas Zimmermann param->reg_FREQ = 0x000055C0; 6580f336e9cSThomas Zimmermann param->madj_max = 76; 6590f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 6600f336e9cSThomas Zimmermann break; 6610f336e9cSThomas Zimmermann case 576: 6620f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0140); 6630f336e9cSThomas Zimmermann param->reg_MADJ = 0x00136868; 6640f336e9cSThomas Zimmermann param->reg_SADJ = 0x00004534; 6650f336e9cSThomas Zimmermann param->wodt = 1; 6660f336e9cSThomas Zimmermann param->rodt = 1; 6670f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302A37; 6680f336e9cSThomas Zimmermann param->reg_AC2 = 0xEF56B61E; 6690f336e9cSThomas Zimmermann param->reg_DQSIC = 0x0000013F; 6700f336e9cSThomas Zimmermann param->reg_MRS = 0x00101A50; 6710f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 6720f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 6730f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000023; 6740f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000078; 6750f336e9cSThomas Zimmermann param->reg_FREQ = 0x000057C0; 6760f336e9cSThomas Zimmermann param->madj_max = 136; 6770f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 6780f336e9cSThomas Zimmermann break; 6790f336e9cSThomas Zimmermann case 600: 6800f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x02E1); 6810f336e9cSThomas Zimmermann param->reg_MADJ = 0x00136868; 6820f336e9cSThomas Zimmermann param->reg_SADJ = 0x00004534; 6830f336e9cSThomas Zimmermann param->wodt = 1; 6840f336e9cSThomas Zimmermann param->rodt = 1; 6850f336e9cSThomas Zimmermann param->reg_AC1 = 0x32302A37; 6860f336e9cSThomas Zimmermann param->reg_AC2 = 0xDF56B61F; 6870f336e9cSThomas Zimmermann param->reg_DQSIC = 0x0000014D; 6880f336e9cSThomas Zimmermann param->reg_MRS = 0x00101A50; 6890f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000004; 6900f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F5; 6910f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000023; 6920f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000078; 6930f336e9cSThomas Zimmermann param->reg_FREQ = 0x000058C0; 6940f336e9cSThomas Zimmermann param->madj_max = 132; 6950f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 6960f336e9cSThomas Zimmermann break; 6970f336e9cSThomas Zimmermann case 624: 6980f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0160); 6990f336e9cSThomas Zimmermann param->reg_MADJ = 0x00136868; 7000f336e9cSThomas Zimmermann param->reg_SADJ = 0x00004534; 7010f336e9cSThomas Zimmermann param->wodt = 1; 7020f336e9cSThomas Zimmermann param->rodt = 1; 7030f336e9cSThomas Zimmermann param->reg_AC1 = 0x32302A37; 7040f336e9cSThomas Zimmermann param->reg_AC2 = 0xEF56B621; 7050f336e9cSThomas Zimmermann param->reg_DQSIC = 0x0000015A; 7060f336e9cSThomas Zimmermann param->reg_MRS = 0x02101A50; 7070f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000004; 7080f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F5; 7090f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 7100f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000078; 7110f336e9cSThomas Zimmermann param->reg_FREQ = 0x000059C0; 7120f336e9cSThomas Zimmermann param->madj_max = 128; 7130f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 7140f336e9cSThomas Zimmermann break; 7150f336e9cSThomas Zimmermann } /* switch freq */ 7160f336e9cSThomas Zimmermann 7170f336e9cSThomas Zimmermann switch (param->dram_chipid) { 7180f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 7190f336e9cSThomas Zimmermann param->dram_config = 0x130; 7200f336e9cSThomas Zimmermann break; 7210f336e9cSThomas Zimmermann default: 7220f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 7230f336e9cSThomas Zimmermann param->dram_config = 0x131; 7240f336e9cSThomas Zimmermann break; 7250f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 7260f336e9cSThomas Zimmermann param->dram_config = 0x132; 7270f336e9cSThomas Zimmermann break; 7280f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 7290f336e9cSThomas Zimmermann param->dram_config = 0x133; 7300f336e9cSThomas Zimmermann break; 7310f336e9cSThomas Zimmermann } /* switch size */ 7320f336e9cSThomas Zimmermann 7330f336e9cSThomas Zimmermann switch (param->vram_size) { 7340f336e9cSThomas Zimmermann default: 7350f336e9cSThomas Zimmermann case SZ_8M: 7360f336e9cSThomas Zimmermann param->dram_config |= 0x00; 7370f336e9cSThomas Zimmermann break; 7380f336e9cSThomas Zimmermann case SZ_16M: 7390f336e9cSThomas Zimmermann param->dram_config |= 0x04; 7400f336e9cSThomas Zimmermann break; 7410f336e9cSThomas Zimmermann case SZ_32M: 7420f336e9cSThomas Zimmermann param->dram_config |= 0x08; 7430f336e9cSThomas Zimmermann break; 7440f336e9cSThomas Zimmermann case SZ_64M: 7450f336e9cSThomas Zimmermann param->dram_config |= 0x0c; 7460f336e9cSThomas Zimmermann break; 7470f336e9cSThomas Zimmermann } 7480f336e9cSThomas Zimmermann } 7490f336e9cSThomas Zimmermann 7500f336e9cSThomas Zimmermann static void ddr3_init(struct ast_device *ast, struct ast2300_dram_param *param) 7510f336e9cSThomas Zimmermann { 7520f336e9cSThomas Zimmermann u32 data, data2, retry = 0; 7530f336e9cSThomas Zimmermann 7540f336e9cSThomas Zimmermann ddr3_init_start: 7550f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 7560f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x00000100); 7570f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0024, 0x00000000); 7580f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00000000); 7590f336e9cSThomas Zimmermann udelay(10); 7600f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); 7610f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); 7620f336e9cSThomas Zimmermann udelay(10); 7630f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); 7640f336e9cSThomas Zimmermann udelay(10); 7650f336e9cSThomas Zimmermann 7660f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, param->dram_config); 7670f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0008, 0x90040f); 7680f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); 7690f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); 7700f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); 7710f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0080, 0x00000000); 7720f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0084, 0x00000000); 7730f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); 7740f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x4000A170); 7750f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x00002370); 7760f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0038, 0x00000000); 7770f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0040, 0xFF444444); 7780f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0044, 0x22222222); 7790f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0048, 0x22222222); 7800f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E004C, 0x00000002); 7810f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 7820f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 7830f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0054, 0); 7840f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); 7850f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); 7860f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 7870f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, 0x00000000); 7880f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0078, 0x00000000); 7890f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 7900f336e9cSThomas Zimmermann /* Wait MCLK2X lock to MCLK */ 7910f336e9cSThomas Zimmermann do { 7920f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 7930f336e9cSThomas Zimmermann } while (!(data & 0x08000000)); 7940f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 7950f336e9cSThomas Zimmermann data = (data >> 8) & 0xff; 7960f336e9cSThomas Zimmermann while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { 7970f336e9cSThomas Zimmermann data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; 7980f336e9cSThomas Zimmermann if ((data2 & 0xff) > param->madj_max) 7990f336e9cSThomas Zimmermann break; 8000f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, data2); 8010f336e9cSThomas Zimmermann if (data2 & 0x00100000) 8020f336e9cSThomas Zimmermann data2 = ((data2 & 0xff) >> 3) + 3; 8030f336e9cSThomas Zimmermann else 8040f336e9cSThomas Zimmermann data2 = ((data2 & 0xff) >> 2) + 5; 8050f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; 8060f336e9cSThomas Zimmermann data2 += data & 0xff; 8070f336e9cSThomas Zimmermann data = data | (data2 << 8); 8080f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, data); 8090f336e9cSThomas Zimmermann udelay(10); 8100f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); 8110f336e9cSThomas Zimmermann udelay(10); 8120f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; 8130f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 8140f336e9cSThomas Zimmermann data = data | 0x200; 8150f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 8160f336e9cSThomas Zimmermann do { 8170f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 8180f336e9cSThomas Zimmermann } while (!(data & 0x08000000)); 8190f336e9cSThomas Zimmermann 8200f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 8210f336e9cSThomas Zimmermann data = (data >> 8) & 0xff; 8220f336e9cSThomas Zimmermann } 8230f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0068) & 0xffff); 8240f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; 8250f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 8260f336e9cSThomas Zimmermann 8270f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00000001); 8280f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00000040); 8290f336e9cSThomas Zimmermann udelay(50); 8300f336e9cSThomas Zimmermann /* Mode Register Setting */ 8310f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); 8320f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 8330f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000005); 8340f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000007); 8350f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 8360f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 8370f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); 8380f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); 8390f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 8400f336e9cSThomas Zimmermann 8410f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); 8420f336e9cSThomas Zimmermann data = 0; 8430f336e9cSThomas Zimmermann if (param->wodt) 8440f336e9cSThomas Zimmermann data = 0x300; 8450f336e9cSThomas Zimmermann if (param->rodt) 8460f336e9cSThomas Zimmermann data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); 8470f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, data | 0x3); 8480f336e9cSThomas Zimmermann 8490f336e9cSThomas Zimmermann /* Calibrate the DQSI delay */ 8500f336e9cSThomas Zimmermann if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) 8510f336e9cSThomas Zimmermann goto ddr3_init_start; 8520f336e9cSThomas Zimmermann 8530f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); 8540f336e9cSThomas Zimmermann /* ECC Memory Initialization */ 8550f336e9cSThomas Zimmermann #ifdef ECC 8560f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 8570f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x221); 8580f336e9cSThomas Zimmermann do { 8590f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0070); 8600f336e9cSThomas Zimmermann } while (!(data & 0x00001000)); 8610f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 8620f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 8630f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 8640f336e9cSThomas Zimmermann #endif 8650f336e9cSThomas Zimmermann } 8660f336e9cSThomas Zimmermann 8670f336e9cSThomas Zimmermann static void get_ddr2_info(struct ast_device *ast, struct ast2300_dram_param *param) 8680f336e9cSThomas Zimmermann { 8690f336e9cSThomas Zimmermann u32 trap, trap_AC2, trap_MRS; 8700f336e9cSThomas Zimmermann 8710f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); 8720f336e9cSThomas Zimmermann 8730f336e9cSThomas Zimmermann /* Ger trap info */ 8740f336e9cSThomas Zimmermann trap = (ast_mindwm(ast, 0x1E6E2070) >> 25) & 0x3; 8750f336e9cSThomas Zimmermann trap_AC2 = (trap << 20) | (trap << 16); 8760f336e9cSThomas Zimmermann trap_AC2 += 0x00110000; 8770f336e9cSThomas Zimmermann trap_MRS = 0x00000040 | (trap << 4); 8780f336e9cSThomas Zimmermann 8790f336e9cSThomas Zimmermann param->reg_MADJ = 0x00034C4C; 8800f336e9cSThomas Zimmermann param->reg_SADJ = 0x00001800; 8810f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F0; 8820f336e9cSThomas Zimmermann param->reg_PERIOD = param->dram_freq; 8830f336e9cSThomas Zimmermann param->rodt = 0; 8840f336e9cSThomas Zimmermann 8850f336e9cSThomas Zimmermann switch (param->dram_freq) { 8860f336e9cSThomas Zimmermann case 264: 8870f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0130); 8880f336e9cSThomas Zimmermann param->wodt = 0; 8890f336e9cSThomas Zimmermann param->reg_AC1 = 0x11101513; 8900f336e9cSThomas Zimmermann param->reg_AC2 = 0x78117011; 8910f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000092; 8920f336e9cSThomas Zimmermann param->reg_MRS = 0x00000842; 8930f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 8940f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F0; 8950f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 8960f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x0000005A; 8970f336e9cSThomas Zimmermann param->reg_FREQ = 0x00004AC0; 8980f336e9cSThomas Zimmermann param->madj_max = 138; 8990f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 9000f336e9cSThomas Zimmermann break; 9010f336e9cSThomas Zimmermann case 336: 9020f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0190); 9030f336e9cSThomas Zimmermann param->wodt = 1; 9040f336e9cSThomas Zimmermann param->reg_AC1 = 0x22202613; 9050f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA009016 | trap_AC2; 9060f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000BA; 9070f336e9cSThomas Zimmermann param->reg_MRS = 0x00000A02 | trap_MRS; 9080f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 9090f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 9100f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 9110f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000074; 9120f336e9cSThomas Zimmermann param->reg_FREQ = 0x00004DC0; 9130f336e9cSThomas Zimmermann param->madj_max = 96; 9140f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 9150f336e9cSThomas Zimmermann switch (param->dram_chipid) { 9160f336e9cSThomas Zimmermann default: 9170f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 9180f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA009012 | trap_AC2; 9190f336e9cSThomas Zimmermann break; 9200f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 9210f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA009016 | trap_AC2; 9220f336e9cSThomas Zimmermann break; 9230f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 9240f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA009023 | trap_AC2; 9250f336e9cSThomas Zimmermann break; 9260f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 9270f336e9cSThomas Zimmermann param->reg_AC2 = 0xAA00903B | trap_AC2; 9280f336e9cSThomas Zimmermann break; 9290f336e9cSThomas Zimmermann } 9300f336e9cSThomas Zimmermann break; 9310f336e9cSThomas Zimmermann default: 9320f336e9cSThomas Zimmermann case 396: 9330f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x03F1); 9340f336e9cSThomas Zimmermann param->wodt = 1; 9350f336e9cSThomas Zimmermann param->rodt = 0; 9360f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302714; 9370f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B01B | trap_AC2; 9380f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000E2; 9390f336e9cSThomas Zimmermann param->reg_MRS = 0x00000C02 | trap_MRS; 9400f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 9410f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 9420f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 9430f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000089; 9440f336e9cSThomas Zimmermann param->reg_FREQ = 0x00005040; 9450f336e9cSThomas Zimmermann param->madj_max = 96; 9460f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 9470f336e9cSThomas Zimmermann 9480f336e9cSThomas Zimmermann switch (param->dram_chipid) { 9490f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 9500f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B016 | trap_AC2; 9510f336e9cSThomas Zimmermann break; 9520f336e9cSThomas Zimmermann default: 9530f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 9540f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B01B | trap_AC2; 9550f336e9cSThomas Zimmermann break; 9560f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 9570f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B02B | trap_AC2; 9580f336e9cSThomas Zimmermann break; 9590f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 9600f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B03F | trap_AC2; 9610f336e9cSThomas Zimmermann break; 9620f336e9cSThomas Zimmermann } 9630f336e9cSThomas Zimmermann 9640f336e9cSThomas Zimmermann break; 9650f336e9cSThomas Zimmermann 9660f336e9cSThomas Zimmermann case 408: 9670f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x01F0); 9680f336e9cSThomas Zimmermann param->wodt = 1; 9690f336e9cSThomas Zimmermann param->rodt = 0; 9700f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302714; 9710f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B01B | trap_AC2; 9720f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000E2; 9730f336e9cSThomas Zimmermann param->reg_MRS = 0x00000C02 | trap_MRS; 9740f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 9750f336e9cSThomas Zimmermann param->reg_DRV = 0x000000FA; 9760f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 9770f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000089; 9780f336e9cSThomas Zimmermann param->reg_FREQ = 0x000050C0; 9790f336e9cSThomas Zimmermann param->madj_max = 96; 9800f336e9cSThomas Zimmermann param->dll2_finetune_step = 4; 9810f336e9cSThomas Zimmermann 9820f336e9cSThomas Zimmermann switch (param->dram_chipid) { 9830f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 9840f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B016 | trap_AC2; 9850f336e9cSThomas Zimmermann break; 9860f336e9cSThomas Zimmermann default: 9870f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 9880f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B01B | trap_AC2; 9890f336e9cSThomas Zimmermann break; 9900f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 9910f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B02B | trap_AC2; 9920f336e9cSThomas Zimmermann break; 9930f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 9940f336e9cSThomas Zimmermann param->reg_AC2 = 0xCC00B03F | trap_AC2; 9950f336e9cSThomas Zimmermann break; 9960f336e9cSThomas Zimmermann } 9970f336e9cSThomas Zimmermann 9980f336e9cSThomas Zimmermann break; 9990f336e9cSThomas Zimmermann case 456: 10000f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0230); 10010f336e9cSThomas Zimmermann param->wodt = 0; 10020f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302815; 10030f336e9cSThomas Zimmermann param->reg_AC2 = 0xCD44B01E; 10040f336e9cSThomas Zimmermann param->reg_DQSIC = 0x000000FC; 10050f336e9cSThomas Zimmermann param->reg_MRS = 0x00000E72; 10060f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000000; 10070f336e9cSThomas Zimmermann param->reg_DRV = 0x00000000; 10080f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000034; 10090f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x00000097; 10100f336e9cSThomas Zimmermann param->reg_FREQ = 0x000052C0; 10110f336e9cSThomas Zimmermann param->madj_max = 88; 10120f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 10130f336e9cSThomas Zimmermann break; 10140f336e9cSThomas Zimmermann case 504: 10150f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0261); 10160f336e9cSThomas Zimmermann param->wodt = 1; 10170f336e9cSThomas Zimmermann param->rodt = 1; 10180f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302815; 10190f336e9cSThomas Zimmermann param->reg_AC2 = 0xDE44C022; 10200f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000117; 10210f336e9cSThomas Zimmermann param->reg_MRS = 0x00000E72; 10220f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 10230f336e9cSThomas Zimmermann param->reg_DRV = 0x0000000A; 10240f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000045; 10250f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x000000A0; 10260f336e9cSThomas Zimmermann param->reg_FREQ = 0x000054C0; 10270f336e9cSThomas Zimmermann param->madj_max = 79; 10280f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 10290f336e9cSThomas Zimmermann break; 10300f336e9cSThomas Zimmermann case 528: 10310f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0120); 10320f336e9cSThomas Zimmermann param->wodt = 1; 10330f336e9cSThomas Zimmermann param->rodt = 1; 10340f336e9cSThomas Zimmermann param->reg_AC1 = 0x33302815; 10350f336e9cSThomas Zimmermann param->reg_AC2 = 0xEF44D024; 10360f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000125; 10370f336e9cSThomas Zimmermann param->reg_MRS = 0x00000E72; 10380f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000004; 10390f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F9; 10400f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000045; 10410f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x000000A7; 10420f336e9cSThomas Zimmermann param->reg_FREQ = 0x000055C0; 10430f336e9cSThomas Zimmermann param->madj_max = 76; 10440f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 10450f336e9cSThomas Zimmermann break; 10460f336e9cSThomas Zimmermann case 552: 10470f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x02A1); 10480f336e9cSThomas Zimmermann param->wodt = 1; 10490f336e9cSThomas Zimmermann param->rodt = 1; 10500f336e9cSThomas Zimmermann param->reg_AC1 = 0x43402915; 10510f336e9cSThomas Zimmermann param->reg_AC2 = 0xFF44E025; 10520f336e9cSThomas Zimmermann param->reg_DQSIC = 0x00000132; 10530f336e9cSThomas Zimmermann param->reg_MRS = 0x00000E72; 10540f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000040; 10550f336e9cSThomas Zimmermann param->reg_DRV = 0x0000000A; 10560f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000045; 10570f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x000000AD; 10580f336e9cSThomas Zimmermann param->reg_FREQ = 0x000056C0; 10590f336e9cSThomas Zimmermann param->madj_max = 76; 10600f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 10610f336e9cSThomas Zimmermann break; 10620f336e9cSThomas Zimmermann case 576: 10630f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, 0x0140); 10640f336e9cSThomas Zimmermann param->wodt = 1; 10650f336e9cSThomas Zimmermann param->rodt = 1; 10660f336e9cSThomas Zimmermann param->reg_AC1 = 0x43402915; 10670f336e9cSThomas Zimmermann param->reg_AC2 = 0xFF44E027; 10680f336e9cSThomas Zimmermann param->reg_DQSIC = 0x0000013F; 10690f336e9cSThomas Zimmermann param->reg_MRS = 0x00000E72; 10700f336e9cSThomas Zimmermann param->reg_EMRS = 0x00000004; 10710f336e9cSThomas Zimmermann param->reg_DRV = 0x000000F5; 10720f336e9cSThomas Zimmermann param->reg_IOZ = 0x00000045; 10730f336e9cSThomas Zimmermann param->reg_DQIDLY = 0x000000B3; 10740f336e9cSThomas Zimmermann param->reg_FREQ = 0x000057C0; 10750f336e9cSThomas Zimmermann param->madj_max = 76; 10760f336e9cSThomas Zimmermann param->dll2_finetune_step = 3; 10770f336e9cSThomas Zimmermann break; 10780f336e9cSThomas Zimmermann } 10790f336e9cSThomas Zimmermann 10800f336e9cSThomas Zimmermann switch (param->dram_chipid) { 10810f336e9cSThomas Zimmermann case AST_DRAM_512Mx16: 10820f336e9cSThomas Zimmermann param->dram_config = 0x100; 10830f336e9cSThomas Zimmermann break; 10840f336e9cSThomas Zimmermann default: 10850f336e9cSThomas Zimmermann case AST_DRAM_1Gx16: 10860f336e9cSThomas Zimmermann param->dram_config = 0x121; 10870f336e9cSThomas Zimmermann break; 10880f336e9cSThomas Zimmermann case AST_DRAM_2Gx16: 10890f336e9cSThomas Zimmermann param->dram_config = 0x122; 10900f336e9cSThomas Zimmermann break; 10910f336e9cSThomas Zimmermann case AST_DRAM_4Gx16: 10920f336e9cSThomas Zimmermann param->dram_config = 0x123; 10930f336e9cSThomas Zimmermann break; 10940f336e9cSThomas Zimmermann } /* switch size */ 10950f336e9cSThomas Zimmermann 10960f336e9cSThomas Zimmermann switch (param->vram_size) { 10970f336e9cSThomas Zimmermann default: 10980f336e9cSThomas Zimmermann case SZ_8M: 10990f336e9cSThomas Zimmermann param->dram_config |= 0x00; 11000f336e9cSThomas Zimmermann break; 11010f336e9cSThomas Zimmermann case SZ_16M: 11020f336e9cSThomas Zimmermann param->dram_config |= 0x04; 11030f336e9cSThomas Zimmermann break; 11040f336e9cSThomas Zimmermann case SZ_32M: 11050f336e9cSThomas Zimmermann param->dram_config |= 0x08; 11060f336e9cSThomas Zimmermann break; 11070f336e9cSThomas Zimmermann case SZ_64M: 11080f336e9cSThomas Zimmermann param->dram_config |= 0x0c; 11090f336e9cSThomas Zimmermann break; 11100f336e9cSThomas Zimmermann } 11110f336e9cSThomas Zimmermann } 11120f336e9cSThomas Zimmermann 11130f336e9cSThomas Zimmermann static void ddr2_init(struct ast_device *ast, struct ast2300_dram_param *param) 11140f336e9cSThomas Zimmermann { 11150f336e9cSThomas Zimmermann u32 data, data2, retry = 0; 11160f336e9cSThomas Zimmermann 11170f336e9cSThomas Zimmermann ddr2_init_start: 11180f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 11190f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x00000100); 11200f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0024, 0x00000000); 11210f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ); 11220f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, param->reg_SADJ); 11230f336e9cSThomas Zimmermann udelay(10); 11240f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, param->reg_MADJ | 0xC0000); 11250f336e9cSThomas Zimmermann udelay(10); 11260f336e9cSThomas Zimmermann 11270f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, param->dram_config); 11280f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0008, 0x90040f); 11290f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0010, param->reg_AC1); 11300f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0014, param->reg_AC2); 11310f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0020, param->reg_DQSIC); 11320f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0080, 0x00000000); 11330f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0084, 0x00000000); 11340f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0088, param->reg_DQIDLY); 11350f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x4000A130); 11360f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, 0x00002330); 11370f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0038, 0x00000000); 11380f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0040, 0xFF808000); 11390f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0044, 0x88848466); 11400f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0048, 0x44440008); 11410f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E004C, 0x00000000); 11420f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 11430f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 11440f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0054, 0); 11450f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, param->reg_DRV); 11460f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E006C, param->reg_IOZ); 11470f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 11480f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, 0x00000000); 11490f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0078, 0x00000000); 11500f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 11510f336e9cSThomas Zimmermann 11520f336e9cSThomas Zimmermann /* Wait MCLK2X lock to MCLK */ 11530f336e9cSThomas Zimmermann do { 11540f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 11550f336e9cSThomas Zimmermann } while (!(data & 0x08000000)); 11560f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 11570f336e9cSThomas Zimmermann data = (data >> 8) & 0xff; 11580f336e9cSThomas Zimmermann while ((data & 0x08) || ((data & 0x7) < 2) || (data < 4)) { 11590f336e9cSThomas Zimmermann data2 = (ast_mindwm(ast, 0x1E6E0064) & 0xfff3ffff) + 4; 11600f336e9cSThomas Zimmermann if ((data2 & 0xff) > param->madj_max) 11610f336e9cSThomas Zimmermann break; 11620f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, data2); 11630f336e9cSThomas Zimmermann if (data2 & 0x00100000) 11640f336e9cSThomas Zimmermann data2 = ((data2 & 0xff) >> 3) + 3; 11650f336e9cSThomas Zimmermann else 11660f336e9cSThomas Zimmermann data2 = ((data2 & 0xff) >> 2) + 5; 11670f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0068) & 0xffff00ff; 11680f336e9cSThomas Zimmermann data2 += data & 0xff; 11690f336e9cSThomas Zimmermann data = data | (data2 << 8); 11700f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0068, data); 11710f336e9cSThomas Zimmermann udelay(10); 11720f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0064, ast_mindwm(ast, 0x1E6E0064) | 0xC0000); 11730f336e9cSThomas Zimmermann udelay(10); 11740f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0018) & 0xfffff1ff; 11750f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 11760f336e9cSThomas Zimmermann data = data | 0x200; 11770f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 11780f336e9cSThomas Zimmermann do { 11790f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 11800f336e9cSThomas Zimmermann } while (!(data & 0x08000000)); 11810f336e9cSThomas Zimmermann 11820f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E001C); 11830f336e9cSThomas Zimmermann data = (data >> 8) & 0xff; 11840f336e9cSThomas Zimmermann } 11850f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E720058, ast_mindwm(ast, 0x1E6E0008) & 0xffff); 11860f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0018) | 0xC00; 11870f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, data); 11880f336e9cSThomas Zimmermann 11890f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00000001); 11900f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00000000); 11910f336e9cSThomas Zimmermann udelay(50); 11920f336e9cSThomas Zimmermann /* Mode Register Setting */ 11930f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS | 0x100); 11940f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 11950f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000005); 11960f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000007); 11970f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 11980f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 11990f336e9cSThomas Zimmermann 12000f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00005C08); 12010f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, param->reg_MRS); 12020f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000001); 12030f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS | 0x380); 12040f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 12050f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, param->reg_EMRS); 12060f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0028, 0x00000003); 12070f336e9cSThomas Zimmermann 12080f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x7FFF5C01); 12090f336e9cSThomas Zimmermann data = 0; 12100f336e9cSThomas Zimmermann if (param->wodt) 12110f336e9cSThomas Zimmermann data = 0x500; 12120f336e9cSThomas Zimmermann if (param->rodt) 12130f336e9cSThomas Zimmermann data = data | 0x3000 | ((param->reg_AC2 & 0x60000) >> 3); 12140f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, data | 0x3); 12150f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0120, param->reg_FREQ); 12160f336e9cSThomas Zimmermann 12170f336e9cSThomas Zimmermann /* Calibrate the DQSI delay */ 12180f336e9cSThomas Zimmermann if ((cbr_dll2(ast, param) == false) && (retry++ < 10)) 12190f336e9cSThomas Zimmermann goto ddr2_init_start; 12200f336e9cSThomas Zimmermann 12210f336e9cSThomas Zimmermann /* ECC Memory Initialization */ 12220f336e9cSThomas Zimmermann #ifdef ECC 12230f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0x00000000); 12240f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x221); 12250f336e9cSThomas Zimmermann do { 12260f336e9cSThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0070); 12270f336e9cSThomas Zimmermann } while (!(data & 0x00001000)); 12280f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0070, 0x00000000); 12290f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 12300f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x00000000); 12310f336e9cSThomas Zimmermann #endif 12320f336e9cSThomas Zimmermann } 12330f336e9cSThomas Zimmermann 12340f336e9cSThomas Zimmermann static void ast_post_chip_2300(struct ast_device *ast) 12350f336e9cSThomas Zimmermann { 12360f336e9cSThomas Zimmermann struct ast2300_dram_param param; 12370f336e9cSThomas Zimmermann u32 temp; 12380f336e9cSThomas Zimmermann u8 reg; 12390f336e9cSThomas Zimmermann 12400f336e9cSThomas Zimmermann reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 12410f336e9cSThomas Zimmermann if ((reg & 0x80) == 0) {/* vga only */ 12420f336e9cSThomas Zimmermann ast_write32(ast, 0xf004, 0x1e6e0000); 12430f336e9cSThomas Zimmermann ast_write32(ast, 0xf000, 0x1); 12440f336e9cSThomas Zimmermann ast_write32(ast, 0x12000, 0x1688a8a8); 12450f336e9cSThomas Zimmermann do { 12460f336e9cSThomas Zimmermann ; 12470f336e9cSThomas Zimmermann } while (ast_read32(ast, 0x12000) != 0x1); 12480f336e9cSThomas Zimmermann 12490f336e9cSThomas Zimmermann ast_write32(ast, 0x10000, 0xfc600309); 12500f336e9cSThomas Zimmermann do { 12510f336e9cSThomas Zimmermann ; 12520f336e9cSThomas Zimmermann } while (ast_read32(ast, 0x10000) != 0x1); 12530f336e9cSThomas Zimmermann 12540f336e9cSThomas Zimmermann /* Slow down CPU/AHB CLK in VGA only mode */ 12550f336e9cSThomas Zimmermann temp = ast_read32(ast, 0x12008); 12560f336e9cSThomas Zimmermann temp |= 0x73; 12570f336e9cSThomas Zimmermann ast_write32(ast, 0x12008, temp); 12580f336e9cSThomas Zimmermann 12590f336e9cSThomas Zimmermann param.dram_freq = 396; 12600f336e9cSThomas Zimmermann param.dram_type = AST_DDR3; 12610f336e9cSThomas Zimmermann temp = ast_mindwm(ast, 0x1e6e2070); 12620f336e9cSThomas Zimmermann if (temp & 0x01000000) 12630f336e9cSThomas Zimmermann param.dram_type = AST_DDR2; 12640f336e9cSThomas Zimmermann switch (temp & 0x18000000) { 12650f336e9cSThomas Zimmermann case 0: 12660f336e9cSThomas Zimmermann param.dram_chipid = AST_DRAM_512Mx16; 12670f336e9cSThomas Zimmermann break; 12680f336e9cSThomas Zimmermann default: 12690f336e9cSThomas Zimmermann case 0x08000000: 12700f336e9cSThomas Zimmermann param.dram_chipid = AST_DRAM_1Gx16; 12710f336e9cSThomas Zimmermann break; 12720f336e9cSThomas Zimmermann case 0x10000000: 12730f336e9cSThomas Zimmermann param.dram_chipid = AST_DRAM_2Gx16; 12740f336e9cSThomas Zimmermann break; 12750f336e9cSThomas Zimmermann case 0x18000000: 12760f336e9cSThomas Zimmermann param.dram_chipid = AST_DRAM_4Gx16; 12770f336e9cSThomas Zimmermann break; 12780f336e9cSThomas Zimmermann } 12790f336e9cSThomas Zimmermann switch (temp & 0x0c) { 12800f336e9cSThomas Zimmermann default: 12810f336e9cSThomas Zimmermann case 0x00: 12820f336e9cSThomas Zimmermann param.vram_size = SZ_8M; 12830f336e9cSThomas Zimmermann break; 12840f336e9cSThomas Zimmermann case 0x04: 12850f336e9cSThomas Zimmermann param.vram_size = SZ_16M; 12860f336e9cSThomas Zimmermann break; 12870f336e9cSThomas Zimmermann case 0x08: 12880f336e9cSThomas Zimmermann param.vram_size = SZ_32M; 12890f336e9cSThomas Zimmermann break; 12900f336e9cSThomas Zimmermann case 0x0c: 12910f336e9cSThomas Zimmermann param.vram_size = SZ_64M; 12920f336e9cSThomas Zimmermann break; 12930f336e9cSThomas Zimmermann } 12940f336e9cSThomas Zimmermann 12950f336e9cSThomas Zimmermann if (param.dram_type == AST_DDR3) { 12960f336e9cSThomas Zimmermann get_ddr3_info(ast, ¶m); 12970f336e9cSThomas Zimmermann ddr3_init(ast, ¶m); 12980f336e9cSThomas Zimmermann } else { 12990f336e9cSThomas Zimmermann get_ddr2_info(ast, ¶m); 13000f336e9cSThomas Zimmermann ddr2_init(ast, ¶m); 13010f336e9cSThomas Zimmermann } 13020f336e9cSThomas Zimmermann 13030f336e9cSThomas Zimmermann temp = ast_mindwm(ast, 0x1e6e2040); 13040f336e9cSThomas Zimmermann ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); 13050f336e9cSThomas Zimmermann } 13060f336e9cSThomas Zimmermann 13070f336e9cSThomas Zimmermann /* wait ready */ 13080f336e9cSThomas Zimmermann do { 13090f336e9cSThomas Zimmermann reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 13100f336e9cSThomas Zimmermann } while ((reg & 0x40) == 0); 13110f336e9cSThomas Zimmermann } 13120f336e9cSThomas Zimmermann 13130f336e9cSThomas Zimmermann int ast_2300_post(struct ast_device *ast) 13140f336e9cSThomas Zimmermann { 1315*b1ce4ab0SThomas Zimmermann ast_2300_set_def_ext_reg(ast); 1316*b1ce4ab0SThomas Zimmermann 13170f336e9cSThomas Zimmermann if (ast->config_mode == ast_use_p2a) { 13180f336e9cSThomas Zimmermann ast_post_chip_2300(ast); 13190f336e9cSThomas Zimmermann ast_init_3rdtx(ast); 13200f336e9cSThomas Zimmermann } else { 13210f336e9cSThomas Zimmermann if (ast->tx_chip == AST_TX_SIL164) { 13220f336e9cSThomas Zimmermann /* Enable DVO */ 13230f336e9cSThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); 13240f336e9cSThomas Zimmermann } 13250f336e9cSThomas Zimmermann } 13260f336e9cSThomas Zimmermann 13270f336e9cSThomas Zimmermann return 0; 13280f336e9cSThomas Zimmermann } 1329