13c1ec4e8SThomas Zimmermann // SPDX-License-Identifier: MIT 23c1ec4e8SThomas Zimmermann /* 33c1ec4e8SThomas Zimmermann * Copyright 2012 Red Hat Inc. 43c1ec4e8SThomas Zimmermann * 53c1ec4e8SThomas Zimmermann * Permission is hereby granted, free of charge, to any person obtaining a 63c1ec4e8SThomas Zimmermann * copy of this software and associated documentation files (the 73c1ec4e8SThomas Zimmermann * "Software"), to deal in the Software without restriction, including 83c1ec4e8SThomas Zimmermann * without limitation the rights to use, copy, modify, merge, publish, 93c1ec4e8SThomas Zimmermann * distribute, sub license, and/or sell copies of the Software, and to 103c1ec4e8SThomas Zimmermann * permit persons to whom the Software is furnished to do so, subject to 113c1ec4e8SThomas Zimmermann * the following conditions: 123c1ec4e8SThomas Zimmermann * 133c1ec4e8SThomas Zimmermann * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 143c1ec4e8SThomas Zimmermann * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 153c1ec4e8SThomas Zimmermann * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 163c1ec4e8SThomas Zimmermann * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 173c1ec4e8SThomas Zimmermann * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 183c1ec4e8SThomas Zimmermann * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 193c1ec4e8SThomas Zimmermann * USE OR OTHER DEALINGS IN THE SOFTWARE. 203c1ec4e8SThomas Zimmermann * 213c1ec4e8SThomas Zimmermann * The above copyright notice and this permission notice (including the 223c1ec4e8SThomas Zimmermann * next paragraph) shall be included in all copies or substantial portions 233c1ec4e8SThomas Zimmermann * of the Software. 243c1ec4e8SThomas Zimmermann */ 253c1ec4e8SThomas Zimmermann /* 263c1ec4e8SThomas Zimmermann * Authors: Dave Airlie <airlied@redhat.com> 273c1ec4e8SThomas Zimmermann */ 283c1ec4e8SThomas Zimmermann 293c1ec4e8SThomas Zimmermann #include <linux/delay.h> 303c1ec4e8SThomas Zimmermann 313c1ec4e8SThomas Zimmermann #include <drm/drm_print.h> 323c1ec4e8SThomas Zimmermann 333c1ec4e8SThomas Zimmermann #include "ast_drv.h" 343c1ec4e8SThomas Zimmermann #include "ast_post.h" 353c1ec4e8SThomas Zimmermann 363c1ec4e8SThomas Zimmermann /* 373c1ec4e8SThomas Zimmermann * POST 383c1ec4e8SThomas Zimmermann */ 393c1ec4e8SThomas Zimmermann 403c1ec4e8SThomas Zimmermann /* 413c1ec4e8SThomas Zimmermann * AST2500 DRAM settings modules 423c1ec4e8SThomas Zimmermann */ 433c1ec4e8SThomas Zimmermann 443c1ec4e8SThomas Zimmermann #define REGTBL_NUM 17 453c1ec4e8SThomas Zimmermann #define REGIDX_010 0 463c1ec4e8SThomas Zimmermann #define REGIDX_014 1 473c1ec4e8SThomas Zimmermann #define REGIDX_018 2 483c1ec4e8SThomas Zimmermann #define REGIDX_020 3 493c1ec4e8SThomas Zimmermann #define REGIDX_024 4 503c1ec4e8SThomas Zimmermann #define REGIDX_02C 5 513c1ec4e8SThomas Zimmermann #define REGIDX_030 6 523c1ec4e8SThomas Zimmermann #define REGIDX_214 7 533c1ec4e8SThomas Zimmermann #define REGIDX_2E0 8 543c1ec4e8SThomas Zimmermann #define REGIDX_2E4 9 553c1ec4e8SThomas Zimmermann #define REGIDX_2E8 10 563c1ec4e8SThomas Zimmermann #define REGIDX_2EC 11 573c1ec4e8SThomas Zimmermann #define REGIDX_2F0 12 583c1ec4e8SThomas Zimmermann #define REGIDX_2F4 13 593c1ec4e8SThomas Zimmermann #define REGIDX_2F8 14 603c1ec4e8SThomas Zimmermann #define REGIDX_RFC 15 613c1ec4e8SThomas Zimmermann #define REGIDX_PLL 16 623c1ec4e8SThomas Zimmermann 633c1ec4e8SThomas Zimmermann static const u32 ast2500_ddr3_1600_timing_table[REGTBL_NUM] = { 643c1ec4e8SThomas Zimmermann 0x64604D38, /* 0x010 */ 653c1ec4e8SThomas Zimmermann 0x29690599, /* 0x014 */ 663c1ec4e8SThomas Zimmermann 0x00000300, /* 0x018 */ 673c1ec4e8SThomas Zimmermann 0x00000000, /* 0x020 */ 683c1ec4e8SThomas Zimmermann 0x00000000, /* 0x024 */ 693c1ec4e8SThomas Zimmermann 0x02181E70, /* 0x02C */ 703c1ec4e8SThomas Zimmermann 0x00000040, /* 0x030 */ 713c1ec4e8SThomas Zimmermann 0x00000024, /* 0x214 */ 723c1ec4e8SThomas Zimmermann 0x02001300, /* 0x2E0 */ 733c1ec4e8SThomas Zimmermann 0x0E0000A0, /* 0x2E4 */ 743c1ec4e8SThomas Zimmermann 0x000E001B, /* 0x2E8 */ 753c1ec4e8SThomas Zimmermann 0x35B8C105, /* 0x2EC */ 763c1ec4e8SThomas Zimmermann 0x08090408, /* 0x2F0 */ 773c1ec4e8SThomas Zimmermann 0x9B000800, /* 0x2F4 */ 783c1ec4e8SThomas Zimmermann 0x0E400A00, /* 0x2F8 */ 793c1ec4e8SThomas Zimmermann 0x9971452F, /* tRFC */ 803c1ec4e8SThomas Zimmermann 0x000071C1 /* PLL */ 813c1ec4e8SThomas Zimmermann }; 823c1ec4e8SThomas Zimmermann 833c1ec4e8SThomas Zimmermann static const u32 ast2500_ddr4_1600_timing_table[REGTBL_NUM] = { 843c1ec4e8SThomas Zimmermann 0x63604E37, /* 0x010 */ 853c1ec4e8SThomas Zimmermann 0xE97AFA99, /* 0x014 */ 863c1ec4e8SThomas Zimmermann 0x00019000, /* 0x018 */ 873c1ec4e8SThomas Zimmermann 0x08000000, /* 0x020 */ 883c1ec4e8SThomas Zimmermann 0x00000400, /* 0x024 */ 893c1ec4e8SThomas Zimmermann 0x00000410, /* 0x02C */ 903c1ec4e8SThomas Zimmermann 0x00000101, /* 0x030 */ 913c1ec4e8SThomas Zimmermann 0x00000024, /* 0x214 */ 923c1ec4e8SThomas Zimmermann 0x03002900, /* 0x2E0 */ 933c1ec4e8SThomas Zimmermann 0x0E0000A0, /* 0x2E4 */ 943c1ec4e8SThomas Zimmermann 0x000E001C, /* 0x2E8 */ 953c1ec4e8SThomas Zimmermann 0x35B8C106, /* 0x2EC */ 963c1ec4e8SThomas Zimmermann 0x08080607, /* 0x2F0 */ 973c1ec4e8SThomas Zimmermann 0x9B000900, /* 0x2F4 */ 983c1ec4e8SThomas Zimmermann 0x0E400A00, /* 0x2F8 */ 993c1ec4e8SThomas Zimmermann 0x99714545, /* tRFC */ 1003c1ec4e8SThomas Zimmermann 0x000071C1 /* PLL */ 1013c1ec4e8SThomas Zimmermann }; 1023c1ec4e8SThomas Zimmermann 1033c1ec4e8SThomas Zimmermann #define TIMEOUT 5000000 1043c1ec4e8SThomas Zimmermann 1053c1ec4e8SThomas Zimmermann void ast_2500_patch_ahb(void __iomem *regs) 1063c1ec4e8SThomas Zimmermann { 1073c1ec4e8SThomas Zimmermann u32 data; 1083c1ec4e8SThomas Zimmermann 1093c1ec4e8SThomas Zimmermann /* Clear bus lock condition */ 1103c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e600000, 0xAEED1A03); 1113c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e600084, 0x00010000); 1123c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e600088, 0x00000000); 1133c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8); 1143c1ec4e8SThomas Zimmermann 1153c1ec4e8SThomas Zimmermann data = __ast_mindwm(regs, 0x1e6e2070); 1163c1ec4e8SThomas Zimmermann if (data & 0x08000000) { /* check fast reset */ 1173c1ec4e8SThomas Zimmermann /* 1183c1ec4e8SThomas Zimmermann * If "Fast restet" is enabled for ARM-ICE debugger, 1193c1ec4e8SThomas Zimmermann * then WDT needs to enable, that 1203c1ec4e8SThomas Zimmermann * WDT04 is WDT#1 Reload reg. 1213c1ec4e8SThomas Zimmermann * WDT08 is WDT#1 counter restart reg to avoid system deadlock 1223c1ec4e8SThomas Zimmermann * WDT0C is WDT#1 control reg 1233c1ec4e8SThomas Zimmermann * [6:5]:= 01:Full chip 1243c1ec4e8SThomas Zimmermann * [4]:= 1:1MHz clock source 1253c1ec4e8SThomas Zimmermann * [1]:= 1:WDT will be cleeared and disabled after timeout occurs 1263c1ec4e8SThomas Zimmermann * [0]:= 1:WDT enable 1273c1ec4e8SThomas Zimmermann */ 1283c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1E785004, 0x00000010); 1293c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1E785008, 0x00004755); 1303c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1E78500c, 0x00000033); 1313c1ec4e8SThomas Zimmermann udelay(1000); 1323c1ec4e8SThomas Zimmermann } 1333c1ec4e8SThomas Zimmermann 1343c1ec4e8SThomas Zimmermann do { 1353c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e6e2000, 0x1688A8A8); 1363c1ec4e8SThomas Zimmermann data = __ast_mindwm(regs, 0x1e6e2000); 1373c1ec4e8SThomas Zimmermann } while (data != 1); 1383c1ec4e8SThomas Zimmermann 1393c1ec4e8SThomas Zimmermann __ast_moutdwm(regs, 0x1e6e207c, 0x08000000); /* clear fast reset */ 1403c1ec4e8SThomas Zimmermann } 1413c1ec4e8SThomas Zimmermann 1423c1ec4e8SThomas Zimmermann static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen) 1433c1ec4e8SThomas Zimmermann { 1443c1ec4e8SThomas Zimmermann return mmc_test(ast, datagen, 0x85); 1453c1ec4e8SThomas Zimmermann } 1463c1ec4e8SThomas Zimmermann 1473c1ec4e8SThomas Zimmermann static bool cbr_test_2500(struct ast_device *ast) 1483c1ec4e8SThomas Zimmermann { 1493c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF); 1503c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00); 1513c1ec4e8SThomas Zimmermann if (!mmc_test_burst(ast, 0)) 1523c1ec4e8SThomas Zimmermann return false; 1533c1ec4e8SThomas Zimmermann if (!mmc_test_single_2500(ast, 0)) 1543c1ec4e8SThomas Zimmermann return false; 1553c1ec4e8SThomas Zimmermann return true; 1563c1ec4e8SThomas Zimmermann } 1573c1ec4e8SThomas Zimmermann 1583c1ec4e8SThomas Zimmermann static bool ddr_test_2500(struct ast_device *ast) 1593c1ec4e8SThomas Zimmermann { 1603c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0074, 0x0000FFFF); 1613c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E007C, 0xFF00FF00); 1623c1ec4e8SThomas Zimmermann if (!mmc_test_burst(ast, 0)) 1633c1ec4e8SThomas Zimmermann return false; 1643c1ec4e8SThomas Zimmermann if (!mmc_test_burst(ast, 1)) 1653c1ec4e8SThomas Zimmermann return false; 1663c1ec4e8SThomas Zimmermann if (!mmc_test_burst(ast, 2)) 1673c1ec4e8SThomas Zimmermann return false; 1683c1ec4e8SThomas Zimmermann if (!mmc_test_burst(ast, 3)) 1693c1ec4e8SThomas Zimmermann return false; 1703c1ec4e8SThomas Zimmermann if (!mmc_test_single_2500(ast, 0)) 1713c1ec4e8SThomas Zimmermann return false; 1723c1ec4e8SThomas Zimmermann return true; 1733c1ec4e8SThomas Zimmermann } 1743c1ec4e8SThomas Zimmermann 1753c1ec4e8SThomas Zimmermann static void ddr_init_common_2500(struct ast_device *ast) 1763c1ec4e8SThomas Zimmermann { 1773c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00020080); 1783c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0008, 0x2003000F); 1793c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0038, 0x00000FFF); 1803c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0040, 0x88448844); 1813c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0044, 0x24422288); 1823c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0048, 0x22222222); 1833c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E004C, 0x22222222); 1843c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0050, 0x80000000); 1853c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0208, 0x00000000); 1863c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0218, 0x00000000); 1873c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0220, 0x00000000); 1883c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0228, 0x00000000); 1893c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0230, 0x00000000); 1903c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02A8, 0x00000000); 1913c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02B0, 0x00000000); 1923c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0240, 0x86000000); 1933c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0244, 0x00008600); 1943c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0248, 0x80000000); 1953c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E024C, 0x80808080); 1963c1ec4e8SThomas Zimmermann } 1973c1ec4e8SThomas Zimmermann 1983c1ec4e8SThomas Zimmermann static void ddr_phy_init_2500(struct ast_device *ast) 1993c1ec4e8SThomas Zimmermann { 2003c1ec4e8SThomas Zimmermann u32 data, pass, timecnt; 2013c1ec4e8SThomas Zimmermann 2023c1ec4e8SThomas Zimmermann pass = 0; 2033c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000005); 2043c1ec4e8SThomas Zimmermann while (!pass) { 2053c1ec4e8SThomas Zimmermann for (timecnt = 0; timecnt < TIMEOUT; timecnt++) { 2063c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0060) & 0x1; 2073c1ec4e8SThomas Zimmermann if (!data) 2083c1ec4e8SThomas Zimmermann break; 2093c1ec4e8SThomas Zimmermann } 2103c1ec4e8SThomas Zimmermann if (timecnt != TIMEOUT) { 2113c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0300) & 0x000A0000; 2123c1ec4e8SThomas Zimmermann if (!data) 2133c1ec4e8SThomas Zimmermann pass = 1; 2143c1ec4e8SThomas Zimmermann } 2153c1ec4e8SThomas Zimmermann if (!pass) { 2163c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000000); 2173c1ec4e8SThomas Zimmermann udelay(10); /* delay 10 us */ 2183c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000005); 2193c1ec4e8SThomas Zimmermann } 2203c1ec4e8SThomas Zimmermann } 2213c1ec4e8SThomas Zimmermann 2223c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000006); 2233c1ec4e8SThomas Zimmermann } 2243c1ec4e8SThomas Zimmermann 2253c1ec4e8SThomas Zimmermann /* 2263c1ec4e8SThomas Zimmermann * Check DRAM Size 2273c1ec4e8SThomas Zimmermann * 1Gb : 0x80000000 ~ 0x87FFFFFF 2283c1ec4e8SThomas Zimmermann * 2Gb : 0x80000000 ~ 0x8FFFFFFF 2293c1ec4e8SThomas Zimmermann * 4Gb : 0x80000000 ~ 0x9FFFFFFF 2303c1ec4e8SThomas Zimmermann * 8Gb : 0x80000000 ~ 0xBFFFFFFF 2313c1ec4e8SThomas Zimmermann */ 2323c1ec4e8SThomas Zimmermann static void check_dram_size_2500(struct ast_device *ast, u32 tRFC) 2333c1ec4e8SThomas Zimmermann { 2343c1ec4e8SThomas Zimmermann u32 reg_04, reg_14; 2353c1ec4e8SThomas Zimmermann 2363c1ec4e8SThomas Zimmermann reg_04 = ast_mindwm(ast, 0x1E6E0004) & 0xfffffffc; 2373c1ec4e8SThomas Zimmermann reg_14 = ast_mindwm(ast, 0x1E6E0014) & 0xffffff00; 2383c1ec4e8SThomas Zimmermann 2393c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0xA0100000, 0x41424344); 2403c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x90100000, 0x35363738); 2413c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x88100000, 0x292A2B2C); 2423c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x80100000, 0x1D1E1F10); 2433c1ec4e8SThomas Zimmermann 2443c1ec4e8SThomas Zimmermann /* Check 8Gbit */ 2453c1ec4e8SThomas Zimmermann if (ast_mindwm(ast, 0xA0100000) == 0x41424344) { 2463c1ec4e8SThomas Zimmermann reg_04 |= 0x03; 2473c1ec4e8SThomas Zimmermann reg_14 |= (tRFC >> 24) & 0xFF; 2483c1ec4e8SThomas Zimmermann /* Check 4Gbit */ 2493c1ec4e8SThomas Zimmermann } else if (ast_mindwm(ast, 0x90100000) == 0x35363738) { 2503c1ec4e8SThomas Zimmermann reg_04 |= 0x02; 2513c1ec4e8SThomas Zimmermann reg_14 |= (tRFC >> 16) & 0xFF; 2523c1ec4e8SThomas Zimmermann /* Check 2Gbit */ 2533c1ec4e8SThomas Zimmermann } else if (ast_mindwm(ast, 0x88100000) == 0x292A2B2C) { 2543c1ec4e8SThomas Zimmermann reg_04 |= 0x01; 2553c1ec4e8SThomas Zimmermann reg_14 |= (tRFC >> 8) & 0xFF; 2563c1ec4e8SThomas Zimmermann } else { 2573c1ec4e8SThomas Zimmermann reg_14 |= tRFC & 0xFF; 2583c1ec4e8SThomas Zimmermann } 2593c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, reg_04); 2603c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0014, reg_14); 2613c1ec4e8SThomas Zimmermann } 2623c1ec4e8SThomas Zimmermann 2633c1ec4e8SThomas Zimmermann static void enable_cache_2500(struct ast_device *ast) 2643c1ec4e8SThomas Zimmermann { 2653c1ec4e8SThomas Zimmermann u32 reg_04, data; 2663c1ec4e8SThomas Zimmermann 2673c1ec4e8SThomas Zimmermann reg_04 = ast_mindwm(ast, 0x1E6E0004); 2683c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x1000); 2693c1ec4e8SThomas Zimmermann 2703c1ec4e8SThomas Zimmermann do 2713c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E0004); 2723c1ec4e8SThomas Zimmermann while (!(data & 0x80000)); 2733c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, reg_04 | 0x400); 2743c1ec4e8SThomas Zimmermann } 2753c1ec4e8SThomas Zimmermann 2763c1ec4e8SThomas Zimmermann static void set_mpll_2500(struct ast_device *ast) 2773c1ec4e8SThomas Zimmermann { 2783c1ec4e8SThomas Zimmermann u32 addr, data, param; 2793c1ec4e8SThomas Zimmermann 2803c1ec4e8SThomas Zimmermann /* Reset MMC */ 2813c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 2823c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00020080); 2833c1ec4e8SThomas Zimmermann for (addr = 0x1e6e0004; addr < 0x1e6e0090;) { 2843c1ec4e8SThomas Zimmermann ast_moutdwm(ast, addr, 0x0); 2853c1ec4e8SThomas Zimmermann addr += 4; 2863c1ec4e8SThomas Zimmermann } 2873c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00020000); 2883c1ec4e8SThomas Zimmermann 2893c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2000, 0x1688A8A8); 2903c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E2070) & 0x00800000; 2913c1ec4e8SThomas Zimmermann if (data) { 2923c1ec4e8SThomas Zimmermann /* CLKIN = 25MHz */ 2933c1ec4e8SThomas Zimmermann param = 0x930023E0; 2943c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2160, 0x00011320); 2953c1ec4e8SThomas Zimmermann } else { 2963c1ec4e8SThomas Zimmermann /* CLKIN = 24MHz */ 2973c1ec4e8SThomas Zimmermann param = 0x93002400; 2983c1ec4e8SThomas Zimmermann } 2993c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2020, param); 3003c1ec4e8SThomas Zimmermann udelay(100); 3013c1ec4e8SThomas Zimmermann } 3023c1ec4e8SThomas Zimmermann 3033c1ec4e8SThomas Zimmermann static void reset_mmc_2500(struct ast_device *ast) 3043c1ec4e8SThomas Zimmermann { 3053c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E78505C, 0x00000004); 3063c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E785044, 0x00000001); 3073c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E785048, 0x00004755); 3083c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E78504C, 0x00000013); 3093c1ec4e8SThomas Zimmermann mdelay(100); 3103c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E785054, 0x00000077); 3113c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0000, 0xFC600309); 3123c1ec4e8SThomas Zimmermann } 3133c1ec4e8SThomas Zimmermann 3143c1ec4e8SThomas Zimmermann static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table) 3153c1ec4e8SThomas Zimmermann { 3163c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, 0x00000303); 3173c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]); 3183c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]); 3193c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]); 3203c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */ 3213c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */ 3223c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */ 3233c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */ 3243c1ec4e8SThomas Zimmermann 3253c1ec4e8SThomas Zimmermann /* DDR PHY Setting */ 3263c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0200, 0x02492AAE); 3273c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0204, 0x00001001); 3283c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B); 3293c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0210, 0x20000000); 3303c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]); 3313c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]); 3323c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]); 3333c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]); 3343c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]); 3353c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]); 3363c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]); 3373c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]); 3383c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0290, 0x00100008); 3393c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C0, 0x00000006); 3403c1ec4e8SThomas Zimmermann 3413c1ec4e8SThomas Zimmermann /* Controller Setting */ 3423c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x00020091); 3433c1ec4e8SThomas Zimmermann 3443c1ec4e8SThomas Zimmermann /* Wait DDR PHY init done */ 3453c1ec4e8SThomas Zimmermann ddr_phy_init_2500(ast); 3463c1ec4e8SThomas Zimmermann 3473c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]); 3483c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81); 3493c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93); 3503c1ec4e8SThomas Zimmermann 3513c1ec4e8SThomas Zimmermann check_dram_size_2500(ast, ddr_table[REGIDX_RFC]); 3523c1ec4e8SThomas Zimmermann enable_cache_2500(ast); 3533c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E001C, 0x00000008); 3543c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00); 3553c1ec4e8SThomas Zimmermann } 3563c1ec4e8SThomas Zimmermann 3573c1ec4e8SThomas Zimmermann static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table) 3583c1ec4e8SThomas Zimmermann { 3593c1ec4e8SThomas Zimmermann u32 data, data2, pass, retrycnt; 3603c1ec4e8SThomas Zimmermann u32 ddr_vref, phy_vref; 3613c1ec4e8SThomas Zimmermann u32 min_ddr_vref = 0, min_phy_vref = 0; 3623c1ec4e8SThomas Zimmermann u32 max_ddr_vref = 0, max_phy_vref = 0; 3633c1ec4e8SThomas Zimmermann 3643c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0004, 0x00000313); 3653c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0010, ddr_table[REGIDX_010]); 3663c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0014, ddr_table[REGIDX_014]); 3673c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0018, ddr_table[REGIDX_018]); 3683c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0020, ddr_table[REGIDX_020]); /* MODEREG4/6 */ 3693c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0024, ddr_table[REGIDX_024]); /* MODEREG5 */ 3703c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E002C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */ 3713c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0030, ddr_table[REGIDX_030]); /* MODEREG1/3 */ 3723c1ec4e8SThomas Zimmermann 3733c1ec4e8SThomas Zimmermann /* DDR PHY Setting */ 3743c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0200, 0x42492AAE); 3753c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0204, 0x09002000); 3763c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E020C, 0x55E00B0B); 3773c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0210, 0x20000000); 3783c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0214, ddr_table[REGIDX_214]); 3793c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E0, ddr_table[REGIDX_2E0]); 3803c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E4, ddr_table[REGIDX_2E4]); 3813c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02E8, ddr_table[REGIDX_2E8]); 3823c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02EC, ddr_table[REGIDX_2EC]); 3833c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F0, ddr_table[REGIDX_2F0]); 3843c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F4, ddr_table[REGIDX_2F4]); 3853c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02F8, ddr_table[REGIDX_2F8]); 3863c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0290, 0x00100008); 3873c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C4, 0x3C183C3C); 3883c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C8, 0x00631E0E); 3893c1ec4e8SThomas Zimmermann 3903c1ec4e8SThomas Zimmermann /* Controller Setting */ 3913c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x0001A991); 3923c1ec4e8SThomas Zimmermann 3933c1ec4e8SThomas Zimmermann /* Train PHY Vref first */ 3943c1ec4e8SThomas Zimmermann pass = 0; 3953c1ec4e8SThomas Zimmermann 3963c1ec4e8SThomas Zimmermann for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) { 3973c1ec4e8SThomas Zimmermann max_phy_vref = 0x0; 3983c1ec4e8SThomas Zimmermann pass = 0; 3993c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C0, 0x00001C06); 4003c1ec4e8SThomas Zimmermann for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) { 4013c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00000000); 4023c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000000); 4033c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02CC, phy_vref | (phy_vref << 8)); 4043c1ec4e8SThomas Zimmermann /* Fire DFI Init */ 4053c1ec4e8SThomas Zimmermann ddr_phy_init_2500(ast); 4063c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); 4073c1ec4e8SThomas Zimmermann if (cbr_test_2500(ast)) { 4083c1ec4e8SThomas Zimmermann pass++; 4093c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E03D0); 4103c1ec4e8SThomas Zimmermann data2 = data >> 8; 4113c1ec4e8SThomas Zimmermann data = data & 0xff; 4123c1ec4e8SThomas Zimmermann if (data > data2) 4133c1ec4e8SThomas Zimmermann data = data2; 4143c1ec4e8SThomas Zimmermann if (max_phy_vref < data) { 4153c1ec4e8SThomas Zimmermann max_phy_vref = data; 4163c1ec4e8SThomas Zimmermann min_phy_vref = phy_vref; 4173c1ec4e8SThomas Zimmermann } 4183c1ec4e8SThomas Zimmermann } else if (pass > 0) { 4193c1ec4e8SThomas Zimmermann break; 4203c1ec4e8SThomas Zimmermann } 4213c1ec4e8SThomas Zimmermann } 4223c1ec4e8SThomas Zimmermann } 4233c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02CC, min_phy_vref | (min_phy_vref << 8)); 4243c1ec4e8SThomas Zimmermann 4253c1ec4e8SThomas Zimmermann /* Train DDR Vref next */ 4263c1ec4e8SThomas Zimmermann pass = 0; 4273c1ec4e8SThomas Zimmermann 4283c1ec4e8SThomas Zimmermann for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) { 4293c1ec4e8SThomas Zimmermann min_ddr_vref = 0xFF; 4303c1ec4e8SThomas Zimmermann max_ddr_vref = 0x0; 4313c1ec4e8SThomas Zimmermann pass = 0; 4323c1ec4e8SThomas Zimmermann for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) { 4333c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00000000); 4343c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000000); 4353c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8)); 4363c1ec4e8SThomas Zimmermann /* Fire DFI Init */ 4373c1ec4e8SThomas Zimmermann ddr_phy_init_2500(ast); 4383c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00005C01); 4393c1ec4e8SThomas Zimmermann if (cbr_test_2500(ast)) { 4403c1ec4e8SThomas Zimmermann pass++; 4413c1ec4e8SThomas Zimmermann if (min_ddr_vref > ddr_vref) 4423c1ec4e8SThomas Zimmermann min_ddr_vref = ddr_vref; 4433c1ec4e8SThomas Zimmermann if (max_ddr_vref < ddr_vref) 4443c1ec4e8SThomas Zimmermann max_ddr_vref = ddr_vref; 4453c1ec4e8SThomas Zimmermann } else if (pass != 0) { 4463c1ec4e8SThomas Zimmermann break; 4473c1ec4e8SThomas Zimmermann } 4483c1ec4e8SThomas Zimmermann } 4493c1ec4e8SThomas Zimmermann } 4503c1ec4e8SThomas Zimmermann 4513c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x00000000); 4523c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0060, 0x00000000); 4533c1ec4e8SThomas Zimmermann ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1; 4543c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E02C0, 0x00000006 | (ddr_vref << 8)); 4553c1ec4e8SThomas Zimmermann 4563c1ec4e8SThomas Zimmermann /* Wait DDR PHY init done */ 4573c1ec4e8SThomas Zimmermann ddr_phy_init_2500(ast); 4583c1ec4e8SThomas Zimmermann 4593c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0120, ddr_table[REGIDX_PLL]); 4603c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E000C, 0x42AA5C81); 4613c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0034, 0x0001AF93); 4623c1ec4e8SThomas Zimmermann 4633c1ec4e8SThomas Zimmermann check_dram_size_2500(ast, ddr_table[REGIDX_RFC]); 4643c1ec4e8SThomas Zimmermann enable_cache_2500(ast); 4653c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E001C, 0x00000008); 4663c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E0038, 0xFFFFFF00); 4673c1ec4e8SThomas Zimmermann } 4683c1ec4e8SThomas Zimmermann 4693c1ec4e8SThomas Zimmermann static bool ast_dram_init_2500(struct ast_device *ast) 4703c1ec4e8SThomas Zimmermann { 4713c1ec4e8SThomas Zimmermann u32 data; 4723c1ec4e8SThomas Zimmermann u32 max_tries = 5; 4733c1ec4e8SThomas Zimmermann 4743c1ec4e8SThomas Zimmermann do { 4753c1ec4e8SThomas Zimmermann if (max_tries-- == 0) 4763c1ec4e8SThomas Zimmermann return false; 4773c1ec4e8SThomas Zimmermann set_mpll_2500(ast); 4783c1ec4e8SThomas Zimmermann reset_mmc_2500(ast); 4793c1ec4e8SThomas Zimmermann ddr_init_common_2500(ast); 4803c1ec4e8SThomas Zimmermann 4813c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E2070); 4823c1ec4e8SThomas Zimmermann if (data & 0x01000000) 4833c1ec4e8SThomas Zimmermann ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table); 4843c1ec4e8SThomas Zimmermann else 4853c1ec4e8SThomas Zimmermann ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table); 4863c1ec4e8SThomas Zimmermann } while (!ddr_test_2500(ast)); 4873c1ec4e8SThomas Zimmermann 4883c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2040, ast_mindwm(ast, 0x1E6E2040) | 0x41); 4893c1ec4e8SThomas Zimmermann 4903c1ec4e8SThomas Zimmermann /* Patch code */ 4913c1ec4e8SThomas Zimmermann data = ast_mindwm(ast, 0x1E6E200C) & 0xF9FFFFFF; 4923c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E200C, data | 0x10000000); 4933c1ec4e8SThomas Zimmermann 4943c1ec4e8SThomas Zimmermann return true; 4953c1ec4e8SThomas Zimmermann } 4963c1ec4e8SThomas Zimmermann 4973c1ec4e8SThomas Zimmermann static void ast_post_chip_2500(struct ast_device *ast) 4983c1ec4e8SThomas Zimmermann { 4993c1ec4e8SThomas Zimmermann struct drm_device *dev = &ast->base; 5003c1ec4e8SThomas Zimmermann u32 temp; 5013c1ec4e8SThomas Zimmermann u8 reg; 5023c1ec4e8SThomas Zimmermann 5033c1ec4e8SThomas Zimmermann reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 5043c1ec4e8SThomas Zimmermann if ((reg & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ 5053c1ec4e8SThomas Zimmermann /* Clear bus lock condition */ 5063c1ec4e8SThomas Zimmermann ast_2500_patch_ahb(ast->regs); 5073c1ec4e8SThomas Zimmermann 5083c1ec4e8SThomas Zimmermann /* Disable watchdog */ 5093c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E78502C, 0x00000000); 5103c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E78504C, 0x00000000); 5113c1ec4e8SThomas Zimmermann 5123c1ec4e8SThomas Zimmermann /* 5133c1ec4e8SThomas Zimmermann * Reset USB port to patch USB unknown device issue 5143c1ec4e8SThomas Zimmermann * SCU90 is Multi-function Pin Control #5 5153c1ec4e8SThomas Zimmermann * [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub 5163c1ec4e8SThomas Zimmermann * port). 5173c1ec4e8SThomas Zimmermann * SCU94 is Multi-function Pin Control #6 5183c1ec4e8SThomas Zimmermann * [14:13]:= 1x:USB2.0 Host2 controller 5193c1ec4e8SThomas Zimmermann * SCU70 is Hardware Strap reg 5203c1ec4e8SThomas Zimmermann * [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by 5213c1ec4e8SThomas Zimmermann * [18]: 0(24)/1(48) MHz) 5223c1ec4e8SThomas Zimmermann * SCU7C is Write clear reg to SCU70 5233c1ec4e8SThomas Zimmermann * [23]:= write 1 and then SCU70[23] will be clear as 0b. 5243c1ec4e8SThomas Zimmermann */ 5253c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2090, 0x20000000); 5263c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2094, 0x00004000); 5273c1ec4e8SThomas Zimmermann if (ast_mindwm(ast, 0x1E6E2070) & 0x00800000) { 5283c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E207C, 0x00800000); 5293c1ec4e8SThomas Zimmermann mdelay(100); 5303c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E2070, 0x00800000); 5313c1ec4e8SThomas Zimmermann } 5323c1ec4e8SThomas Zimmermann /* Modify eSPI reset pin */ 5333c1ec4e8SThomas Zimmermann temp = ast_mindwm(ast, 0x1E6E2070); 5343c1ec4e8SThomas Zimmermann if (temp & 0x02000000) 5353c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1E6E207C, 0x00004000); 5363c1ec4e8SThomas Zimmermann 5373c1ec4e8SThomas Zimmermann /* Slow down CPU/AHB CLK in VGA only mode */ 5383c1ec4e8SThomas Zimmermann temp = ast_read32(ast, 0x12008); 5393c1ec4e8SThomas Zimmermann temp |= 0x73; 5403c1ec4e8SThomas Zimmermann ast_write32(ast, 0x12008, temp); 5413c1ec4e8SThomas Zimmermann 5423c1ec4e8SThomas Zimmermann if (!ast_dram_init_2500(ast)) 5433c1ec4e8SThomas Zimmermann drm_err(dev, "DRAM init failed !\n"); 5443c1ec4e8SThomas Zimmermann 5453c1ec4e8SThomas Zimmermann temp = ast_mindwm(ast, 0x1e6e2040); 5463c1ec4e8SThomas Zimmermann ast_moutdwm(ast, 0x1e6e2040, temp | 0x40); 5473c1ec4e8SThomas Zimmermann } 5483c1ec4e8SThomas Zimmermann 5493c1ec4e8SThomas Zimmermann /* wait ready */ 5503c1ec4e8SThomas Zimmermann do { 5513c1ec4e8SThomas Zimmermann reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 5523c1ec4e8SThomas Zimmermann } while ((reg & 0x40) == 0); 5533c1ec4e8SThomas Zimmermann } 5543c1ec4e8SThomas Zimmermann 5553c1ec4e8SThomas Zimmermann int ast_2500_post(struct ast_device *ast) 5563c1ec4e8SThomas Zimmermann { 557*b1ce4ab0SThomas Zimmermann ast_2300_set_def_ext_reg(ast); 558*b1ce4ab0SThomas Zimmermann 5593c1ec4e8SThomas Zimmermann if (ast->config_mode == ast_use_p2a) { 5603c1ec4e8SThomas Zimmermann ast_post_chip_2500(ast); 5613c1ec4e8SThomas Zimmermann } else { 5623c1ec4e8SThomas Zimmermann if (ast->tx_chip == AST_TX_SIL164) { 5633c1ec4e8SThomas Zimmermann /* Enable DVO */ 5643c1ec4e8SThomas Zimmermann ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); 5653c1ec4e8SThomas Zimmermann } 5663c1ec4e8SThomas Zimmermann } 5673c1ec4e8SThomas Zimmermann 5683c1ec4e8SThomas Zimmermann return 0; 5693c1ec4e8SThomas Zimmermann } 570