1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2012 Red Hat Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 19 * USE OR OTHER DEALINGS IN THE SOFTWARE. 20 * 21 * The above copyright notice and this permission notice (including the 22 * next paragraph) shall be included in all copies or substantial portions 23 * of the Software. 24 */ 25 /* 26 * Authors: Dave Airlie <airlied@redhat.com> 27 */ 28 29 #include <linux/delay.h> 30 #include <linux/pci.h> 31 32 #include <drm/drm_drv.h> 33 #include <drm/drm_print.h> 34 35 #include "ast_drv.h" 36 #include "ast_post.h" 37 38 /* 39 * POST 40 */ 41 42 /* 43 * AST2500 DRAM settings modules 44 */ 45 46 #define REGTBL_NUM 17 47 #define REGIDX_010 0 48 #define REGIDX_014 1 49 #define REGIDX_018 2 50 #define REGIDX_020 3 51 #define REGIDX_024 4 52 #define REGIDX_02C 5 53 #define REGIDX_030 6 54 #define REGIDX_214 7 55 #define REGIDX_2E0 8 56 #define REGIDX_2E4 9 57 #define REGIDX_2E8 10 58 #define REGIDX_2EC 11 59 #define REGIDX_2F0 12 60 #define REGIDX_2F4 13 61 #define REGIDX_2F8 14 62 #define REGIDX_RFC 15 63 #define REGIDX_PLL 16 64 65 static const u32 ast2500_ddr3_1600_timing_table[REGTBL_NUM] = { 66 0x64604D38, /* 0x010 */ 67 0x29690599, /* 0x014 */ 68 0x00000300, /* 0x018 */ 69 0x00000000, /* 0x020 */ 70 0x00000000, /* 0x024 */ 71 0x02181E70, /* 0x02C */ 72 0x00000040, /* 0x030 */ 73 0x00000024, /* 0x214 */ 74 0x02001300, /* 0x2E0 */ 75 0x0E0000A0, /* 0x2E4 */ 76 0x000E001B, /* 0x2E8 */ 77 0x35B8C105, /* 0x2EC */ 78 0x08090408, /* 0x2F0 */ 79 0x9B000800, /* 0x2F4 */ 80 0x0E400A00, /* 0x2F8 */ 81 0x9971452F, /* tRFC */ 82 0x000071C1 /* PLL */ 83 }; 84 85 static const u32 ast2500_ddr4_1600_timing_table[REGTBL_NUM] = { 86 0x63604E37, /* 0x010 */ 87 0xE97AFA99, /* 0x014 */ 88 0x00019000, /* 0x018 */ 89 0x08000000, /* 0x020 */ 90 0x00000400, /* 0x024 */ 91 0x00000410, /* 0x02C */ 92 0x00000101, /* 0x030 */ 93 0x00000024, /* 0x214 */ 94 0x03002900, /* 0x2E0 */ 95 0x0E0000A0, /* 0x2E4 */ 96 0x000E001C, /* 0x2E8 */ 97 0x35B8C106, /* 0x2EC */ 98 0x08080607, /* 0x2F0 */ 99 0x9B000900, /* 0x2F4 */ 100 0x0E400A00, /* 0x2F8 */ 101 0x99714545, /* tRFC */ 102 0x000071C1 /* PLL */ 103 }; 104 105 #define TIMEOUT 5000000 106 107 void ast_2500_patch_ahb(void __iomem *regs) 108 { 109 u32 data; 110 111 /* Clear bus lock condition */ 112 __ast_moutdwm(regs, AST_REG_AHBC00, AST_REG_AHBC00_PROTECT_KEY); 113 __ast_moutdwm(regs, AST_REG_AHBC84, 0x00010000); 114 __ast_moutdwm(regs, AST_REG_AHBC88, 0x00000000); 115 __ast_moutdwm(regs, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY); 116 117 data = __ast_mindwm(regs, AST_REG_SCU070); 118 if (data & 0x08000000) { /* check fast reset */ 119 /* 120 * If "Fast restet" is enabled for ARM-ICE debugger, 121 * then WDT needs to enable, that 122 * WDT04 is WDT#1 Reload reg. 123 * WDT08 is WDT#1 counter restart reg to avoid system deadlock 124 * WDT0C is WDT#1 control reg 125 * [6:5]:= 01:Full chip 126 * [4]:= 1:1MHz clock source 127 * [1]:= 1:WDT will be cleeared and disabled after timeout occurs 128 * [0]:= 1:WDT enable 129 */ 130 __ast_moutdwm(regs, AST_REG_WDT04(0), 0x00000010); 131 __ast_moutdwm(regs, AST_REG_WDT08(0), 0x00004755); 132 __ast_moutdwm(regs, AST_REG_WDT0C(0), 0x00000033); 133 udelay(1000); 134 } 135 136 do { 137 __ast_moutdwm(regs, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY); 138 data = __ast_mindwm(regs, AST_REG_SCU000); 139 } while (data != 1); 140 141 __ast_moutdwm(regs, AST_REG_SCU07C, 0x08000000); /* clear fast reset */ 142 } 143 144 static bool mmc_test_single_2500(struct ast_device *ast, u32 datagen) 145 { 146 return mmc_test(ast, datagen, 0x85); 147 } 148 149 static bool cbr_test_2500(struct ast_device *ast) 150 { 151 ast_moutdwm(ast, AST_REG_MCR74, 0x0000FFFF); 152 ast_moutdwm(ast, AST_REG_MCR7C, 0xFF00FF00); 153 if (!mmc_test_burst(ast, 0)) 154 return false; 155 if (!mmc_test_single_2500(ast, 0)) 156 return false; 157 return true; 158 } 159 160 static bool ddr_test_2500(struct ast_device *ast) 161 { 162 ast_moutdwm(ast, AST_REG_MCR74, 0x0000FFFF); 163 ast_moutdwm(ast, AST_REG_MCR7C, 0xFF00FF00); 164 if (!mmc_test_burst(ast, 0)) 165 return false; 166 if (!mmc_test_burst(ast, 1)) 167 return false; 168 if (!mmc_test_burst(ast, 2)) 169 return false; 170 if (!mmc_test_burst(ast, 3)) 171 return false; 172 if (!mmc_test_single_2500(ast, 0)) 173 return false; 174 return true; 175 } 176 177 static void ddr_init_common_2500(struct ast_device *ast) 178 { 179 ast_moutdwm(ast, AST_REG_MCR34, 0x00020080); 180 ast_moutdwm(ast, AST_REG_MCR08, 0x2003000F); 181 ast_moutdwm(ast, AST_REG_MCR38, 0x00000FFF); 182 ast_moutdwm(ast, AST_REG_MCR40, 0x88448844); 183 ast_moutdwm(ast, AST_REG_MCR44, 0x24422288); 184 ast_moutdwm(ast, AST_REG_MCR48, 0x22222222); 185 ast_moutdwm(ast, AST_REG_MCR4C, 0x22222222); 186 ast_moutdwm(ast, AST_REG_MCR50, 0x80000000); 187 ast_moutdwm(ast, AST_REG_MCR208, 0x00000000); 188 ast_moutdwm(ast, AST_REG_MCR218, 0x00000000); 189 ast_moutdwm(ast, AST_REG_MCR220, 0x00000000); 190 ast_moutdwm(ast, AST_REG_MCR228, 0x00000000); 191 ast_moutdwm(ast, AST_REG_MCR230, 0x00000000); 192 ast_moutdwm(ast, AST_REG_MCR2A8, 0x00000000); 193 ast_moutdwm(ast, AST_REG_MCR2B0, 0x00000000); 194 ast_moutdwm(ast, AST_REG_MCR240, 0x86000000); 195 ast_moutdwm(ast, AST_REG_MCR244, 0x00008600); 196 ast_moutdwm(ast, AST_REG_MCR248, 0x80000000); 197 ast_moutdwm(ast, AST_REG_MCR24C, 0x80808080); 198 } 199 200 static void ddr_phy_init_2500(struct ast_device *ast) 201 { 202 u32 data, pass, timecnt; 203 204 pass = 0; 205 ast_moutdwm(ast, AST_REG_MCR60, 0x00000005); 206 while (!pass) { 207 for (timecnt = 0; timecnt < TIMEOUT; timecnt++) { 208 data = ast_mindwm(ast, AST_REG_MCR60) & 0x1; 209 if (!data) 210 break; 211 } 212 if (timecnt != TIMEOUT) { 213 data = ast_mindwm(ast, AST_REG_MCR300) & 0x000A0000; 214 if (!data) 215 pass = 1; 216 } 217 if (!pass) { 218 ast_moutdwm(ast, AST_REG_MCR60, 0x00000000); 219 udelay(10); /* delay 10 us */ 220 ast_moutdwm(ast, AST_REG_MCR60, 0x00000005); 221 } 222 } 223 224 ast_moutdwm(ast, AST_REG_MCR60, 0x00000006); 225 } 226 227 /* 228 * TODO: Review and fix the comments. The function below only detects 229 * up to 1 GiB of SDRAM. 230 * 231 * Check DRAM Size 232 * 1Gb : 0x80000000 ~ 0x87FFFFFF 233 * 2Gb : 0x80000000 ~ 0x8FFFFFFF 234 * 4Gb : 0x80000000 ~ 0x9FFFFFFF 235 * 8Gb : 0x80000000 ~ 0xBFFFFFFF 236 */ 237 static void check_dram_size_2500(struct ast_device *ast, u32 tRFC) 238 { 239 u32 reg_04, reg_14; 240 241 reg_04 = ast_mindwm(ast, AST_REG_MCR04) & 0xfffffffc; 242 reg_14 = ast_mindwm(ast, AST_REG_MCR14) & 0xffffff00; 243 244 ast_moutdwm(ast, AST_SDRAM(0x20100000), 0x41424344); 245 ast_moutdwm(ast, AST_SDRAM(0x10100000), 0x35363738); 246 ast_moutdwm(ast, AST_SDRAM(0x08100000), 0x292A2B2C); 247 ast_moutdwm(ast, AST_SDRAM(0x00100000), 0x1D1E1F10); 248 249 /* Check 8Gbit */ 250 if (ast_mindwm(ast, AST_SDRAM(0x20100000)) == 0x41424344) { 251 reg_04 |= 0x03; 252 reg_14 |= (tRFC >> 24) & 0xFF; 253 /* Check 4Gbit */ 254 } else if (ast_mindwm(ast, AST_SDRAM(0x10100000)) == 0x35363738) { 255 reg_04 |= 0x02; 256 reg_14 |= (tRFC >> 16) & 0xFF; 257 /* Check 2Gbit */ 258 } else if (ast_mindwm(ast, AST_SDRAM(0x08100000)) == 0x292A2B2C) { 259 reg_04 |= 0x01; 260 reg_14 |= (tRFC >> 8) & 0xFF; 261 } else { 262 reg_14 |= tRFC & 0xFF; 263 } 264 ast_moutdwm(ast, AST_REG_MCR04, reg_04); 265 ast_moutdwm(ast, AST_REG_MCR14, reg_14); 266 } 267 268 static void enable_cache_2500(struct ast_device *ast) 269 { 270 u32 reg_04, data; 271 272 reg_04 = ast_mindwm(ast, AST_REG_MCR04); 273 ast_moutdwm(ast, AST_REG_MCR04, reg_04 | 0x1000); 274 275 do 276 data = ast_mindwm(ast, AST_REG_MCR04); 277 while (!(data & 0x80000)); 278 ast_moutdwm(ast, AST_REG_MCR04, reg_04 | 0x400); 279 } 280 281 static void set_mpll_2500(struct ast_device *ast) 282 { 283 u32 mcr, data, param; 284 285 /* Reset MMC */ 286 ast_moutdwm(ast, AST_REG_MCR00, AST_REG_MCR00_PROTECTION_KEY); 287 ast_moutdwm(ast, AST_REG_MCR34, 0x00020080); 288 for (mcr = AST_REG_MCR04; mcr <= AST_REG_MCR8C; mcr += 4) 289 ast_moutdwm(ast, mcr, 0x00000000); 290 ast_moutdwm(ast, AST_REG_MCR34, 0x00020000); 291 292 ast_moutdwm(ast, AST_REG_SCU000, AST_REG_SCU000_PROTECTION_KEY); 293 data = ast_mindwm(ast, AST_REG_SCU070) & 0x00800000; 294 if (data) { 295 /* CLKIN = 25MHz */ 296 param = 0x930023E0; 297 ast_moutdwm(ast, AST_REG_SCU160, 0x00011320); 298 } else { 299 /* CLKIN = 24MHz */ 300 param = 0x93002400; 301 } 302 ast_moutdwm(ast, AST_REG_SCU020, param); 303 udelay(100); 304 } 305 306 static void reset_mmc_2500(struct ast_device *ast) 307 { 308 ast_moutdwm(ast, AST_REG_WDT1C(1), 0x00000004); 309 ast_moutdwm(ast, AST_REG_WDT04(1), 0x00000001); 310 ast_moutdwm(ast, AST_REG_WDT08(1), 0x00004755); 311 ast_moutdwm(ast, AST_REG_WDT0C(1), 0x00000013); 312 mdelay(100); 313 ast_moutdwm(ast, AST_REG_WDT14(1), 0x00000077); 314 ast_moutdwm(ast, AST_REG_MCR00, AST_REG_MCR00_PROTECTION_KEY); 315 } 316 317 static void ddr3_init_2500(struct ast_device *ast, const u32 *ddr_table) 318 { 319 ast_moutdwm(ast, AST_REG_MCR04, 0x00000303); 320 ast_moutdwm(ast, AST_REG_MCR10, ddr_table[REGIDX_010]); 321 ast_moutdwm(ast, AST_REG_MCR14, ddr_table[REGIDX_014]); 322 ast_moutdwm(ast, AST_REG_MCR18, ddr_table[REGIDX_018]); 323 ast_moutdwm(ast, AST_REG_MCR20, ddr_table[REGIDX_020]); /* MODEREG4/6 */ 324 ast_moutdwm(ast, AST_REG_MCR24, ddr_table[REGIDX_024]); /* MODEREG5 */ 325 ast_moutdwm(ast, AST_REG_MCR2C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */ 326 ast_moutdwm(ast, AST_REG_MCR30, ddr_table[REGIDX_030]); /* MODEREG1/3 */ 327 328 /* DDR PHY Setting */ 329 ast_moutdwm(ast, AST_REG_MCR200, 0x02492AAE); 330 ast_moutdwm(ast, AST_REG_MCR204, 0x00001001); 331 ast_moutdwm(ast, AST_REG_MCR20C, 0x55E00B0B); 332 ast_moutdwm(ast, AST_REG_MCR210, 0x20000000); 333 ast_moutdwm(ast, AST_REG_MCR214, ddr_table[REGIDX_214]); 334 ast_moutdwm(ast, AST_REG_MCR2E0, ddr_table[REGIDX_2E0]); 335 ast_moutdwm(ast, AST_REG_MCR2E4, ddr_table[REGIDX_2E4]); 336 ast_moutdwm(ast, AST_REG_MCR2E8, ddr_table[REGIDX_2E8]); 337 ast_moutdwm(ast, AST_REG_MCR2EC, ddr_table[REGIDX_2EC]); 338 ast_moutdwm(ast, AST_REG_MCR2F0, ddr_table[REGIDX_2F0]); 339 ast_moutdwm(ast, AST_REG_MCR2F4, ddr_table[REGIDX_2F4]); 340 ast_moutdwm(ast, AST_REG_MCR2F8, ddr_table[REGIDX_2F8]); 341 ast_moutdwm(ast, AST_REG_MCR290, 0x00100008); 342 ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006); 343 344 /* Controller Setting */ 345 ast_moutdwm(ast, AST_REG_MCR34, 0x00020091); 346 347 /* Wait DDR PHY init done */ 348 ddr_phy_init_2500(ast); 349 350 ast_moutdwm(ast, AST_REG_MCR120, ddr_table[REGIDX_PLL]); 351 ast_moutdwm(ast, AST_REG_MCR0C, 0x42AA5C81); 352 ast_moutdwm(ast, AST_REG_MCR34, 0x0001AF93); 353 354 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]); 355 enable_cache_2500(ast); 356 ast_moutdwm(ast, AST_REG_MCR1C, 0x00000008); 357 ast_moutdwm(ast, AST_REG_MCR38, 0xFFFFFF00); 358 } 359 360 static void ddr4_init_2500(struct ast_device *ast, const u32 *ddr_table) 361 { 362 u32 data, data2, pass, retrycnt; 363 u32 ddr_vref, phy_vref; 364 u32 min_ddr_vref = 0, min_phy_vref = 0; 365 u32 max_ddr_vref = 0, max_phy_vref = 0; 366 367 ast_moutdwm(ast, AST_REG_MCR04, 0x00000313); 368 ast_moutdwm(ast, AST_REG_MCR10, ddr_table[REGIDX_010]); 369 ast_moutdwm(ast, AST_REG_MCR14, ddr_table[REGIDX_014]); 370 ast_moutdwm(ast, AST_REG_MCR18, ddr_table[REGIDX_018]); 371 ast_moutdwm(ast, AST_REG_MCR20, ddr_table[REGIDX_020]); /* MODEREG4/6 */ 372 ast_moutdwm(ast, AST_REG_MCR24, ddr_table[REGIDX_024]); /* MODEREG5 */ 373 ast_moutdwm(ast, AST_REG_MCR2C, ddr_table[REGIDX_02C] | 0x100); /* MODEREG0/2 */ 374 ast_moutdwm(ast, AST_REG_MCR30, ddr_table[REGIDX_030]); /* MODEREG1/3 */ 375 376 /* DDR PHY Setting */ 377 ast_moutdwm(ast, AST_REG_MCR200, 0x42492AAE); 378 ast_moutdwm(ast, AST_REG_MCR204, 0x09002000); 379 ast_moutdwm(ast, AST_REG_MCR20C, 0x55E00B0B); 380 ast_moutdwm(ast, AST_REG_MCR210, 0x20000000); 381 ast_moutdwm(ast, AST_REG_MCR214, ddr_table[REGIDX_214]); 382 ast_moutdwm(ast, AST_REG_MCR2E0, ddr_table[REGIDX_2E0]); 383 ast_moutdwm(ast, AST_REG_MCR2E4, ddr_table[REGIDX_2E4]); 384 ast_moutdwm(ast, AST_REG_MCR2E8, ddr_table[REGIDX_2E8]); 385 ast_moutdwm(ast, AST_REG_MCR2EC, ddr_table[REGIDX_2EC]); 386 ast_moutdwm(ast, AST_REG_MCR2F0, ddr_table[REGIDX_2F0]); 387 ast_moutdwm(ast, AST_REG_MCR2F4, ddr_table[REGIDX_2F4]); 388 ast_moutdwm(ast, AST_REG_MCR2F8, ddr_table[REGIDX_2F8]); 389 ast_moutdwm(ast, AST_REG_MCR290, 0x00100008); 390 ast_moutdwm(ast, AST_REG_MCR2C4, 0x3C183C3C); 391 ast_moutdwm(ast, AST_REG_MCR2C8, 0x00631E0E); 392 393 /* Controller Setting */ 394 ast_moutdwm(ast, AST_REG_MCR34, 0x0001A991); 395 396 /* Train PHY Vref first */ 397 pass = 0; 398 399 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) { 400 max_phy_vref = 0x0; 401 pass = 0; 402 ast_moutdwm(ast, AST_REG_MCR2C0, 0x00001C06); 403 for (phy_vref = 0x40; phy_vref < 0x80; phy_vref++) { 404 ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000); 405 ast_moutdwm(ast, AST_REG_MCR60, 0x00000000); 406 ast_moutdwm(ast, AST_REG_MCR2CC, phy_vref | (phy_vref << 8)); 407 /* Fire DFI Init */ 408 ddr_phy_init_2500(ast); 409 ast_moutdwm(ast, AST_REG_MCR0C, 0x00005C01); 410 if (cbr_test_2500(ast)) { 411 pass++; 412 data = ast_mindwm(ast, AST_REG_MCR3D0); 413 data2 = data >> 8; 414 data = data & 0xff; 415 if (data > data2) 416 data = data2; 417 if (max_phy_vref < data) { 418 max_phy_vref = data; 419 min_phy_vref = phy_vref; 420 } 421 } else if (pass > 0) { 422 break; 423 } 424 } 425 } 426 ast_moutdwm(ast, AST_REG_MCR2CC, min_phy_vref | (min_phy_vref << 8)); 427 428 /* Train DDR Vref next */ 429 pass = 0; 430 431 for (retrycnt = 0; retrycnt < 4 && pass == 0; retrycnt++) { 432 min_ddr_vref = 0xFF; 433 max_ddr_vref = 0x0; 434 pass = 0; 435 for (ddr_vref = 0x00; ddr_vref < 0x40; ddr_vref++) { 436 ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000); 437 ast_moutdwm(ast, AST_REG_MCR60, 0x00000000); 438 ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006 | (ddr_vref << 8)); 439 /* Fire DFI Init */ 440 ddr_phy_init_2500(ast); 441 ast_moutdwm(ast, AST_REG_MCR0C, 0x00005C01); 442 if (cbr_test_2500(ast)) { 443 pass++; 444 if (min_ddr_vref > ddr_vref) 445 min_ddr_vref = ddr_vref; 446 if (max_ddr_vref < ddr_vref) 447 max_ddr_vref = ddr_vref; 448 } else if (pass != 0) { 449 break; 450 } 451 } 452 } 453 454 ast_moutdwm(ast, AST_REG_MCR0C, 0x00000000); 455 ast_moutdwm(ast, AST_REG_MCR60, 0x00000000); 456 ddr_vref = (min_ddr_vref + max_ddr_vref + 1) >> 1; 457 ast_moutdwm(ast, AST_REG_MCR2C0, 0x00000006 | (ddr_vref << 8)); 458 459 /* Wait DDR PHY init done */ 460 ddr_phy_init_2500(ast); 461 462 ast_moutdwm(ast, AST_REG_MCR120, ddr_table[REGIDX_PLL]); 463 ast_moutdwm(ast, AST_REG_MCR0C, 0x42AA5C81); 464 ast_moutdwm(ast, AST_REG_MCR34, 0x0001AF93); 465 466 check_dram_size_2500(ast, ddr_table[REGIDX_RFC]); 467 enable_cache_2500(ast); 468 ast_moutdwm(ast, AST_REG_MCR1C, 0x00000008); 469 ast_moutdwm(ast, AST_REG_MCR38, 0xFFFFFF00); 470 } 471 472 static bool ast_dram_init_2500(struct ast_device *ast) 473 { 474 u32 data; 475 u32 max_tries = 5; 476 477 do { 478 if (max_tries-- == 0) 479 return false; 480 set_mpll_2500(ast); 481 reset_mmc_2500(ast); 482 ddr_init_common_2500(ast); 483 484 data = ast_mindwm(ast, AST_REG_SCU070); 485 if (data & 0x01000000) 486 ddr4_init_2500(ast, ast2500_ddr4_1600_timing_table); 487 else 488 ddr3_init_2500(ast, ast2500_ddr3_1600_timing_table); 489 } while (!ddr_test_2500(ast)); 490 491 ast_moutdwm(ast, AST_REG_SCU040, ast_mindwm(ast, AST_REG_SCU040) | 0x41); 492 493 /* Patch code */ 494 data = ast_mindwm(ast, AST_REG_SCU00C) & 0xF9FFFFFF; 495 ast_moutdwm(ast, AST_REG_SCU00C, data | 0x10000000); 496 497 return true; 498 } 499 500 static void ast_post_chip_2500(struct ast_device *ast) 501 { 502 struct drm_device *dev = &ast->base; 503 u32 temp; 504 u8 reg; 505 506 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 507 if ((reg & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ 508 u32 scu008; 509 510 /* Clear bus lock condition */ 511 ast_2500_patch_ahb(ast->regs); 512 513 /* Disable watchdog */ 514 ast_moutdwm(ast, AST_REG_WDT2C(0), 0x00000000); 515 ast_moutdwm(ast, AST_REG_WDT0C(1), 0x00000000); 516 517 /* 518 * Reset USB port to patch USB unknown device issue 519 * SCU90 is Multi-function Pin Control #5 520 * [29]:= 1:Enable USB2.0 Host port#1 (that the mutually shared USB2.0 Hub 521 * port). 522 * SCU94 is Multi-function Pin Control #6 523 * [14:13]:= 1x:USB2.0 Host2 controller 524 * SCU70 is Hardware Strap reg 525 * [23]:= 1:CLKIN is 25MHz and USBCK1 = 24/48 MHz (determined by 526 * [18]: 0(24)/1(48) MHz) 527 * SCU7C is Write clear reg to SCU70 528 * [23]:= write 1 and then SCU70[23] will be clear as 0b. 529 */ 530 ast_moutdwm(ast, AST_REG_SCU090, 0x20000000); 531 ast_moutdwm(ast, AST_REG_SCU094, 0x00004000); 532 if (ast_mindwm(ast, AST_REG_SCU070) & 0x00800000) { 533 ast_moutdwm(ast, AST_REG_SCU07C, 0x00800000); 534 mdelay(100); 535 ast_moutdwm(ast, AST_REG_SCU070, 0x00800000); 536 } 537 /* Modify eSPI reset pin */ 538 temp = ast_mindwm(ast, AST_REG_SCU070); 539 if (temp & 0x02000000) 540 ast_moutdwm(ast, AST_REG_SCU07C, 0x00004000); 541 542 /* Slow down CPU/AHB CLK in VGA only mode */ 543 scu008 = ast_mindwm(ast, AST_REG_SCU008); 544 scu008 |= 0x00000073; 545 ast_moutdwm(ast, AST_REG_SCU008, scu008); 546 547 if (!ast_dram_init_2500(ast)) 548 drm_err(dev, "DRAM init failed !\n"); 549 550 temp = ast_mindwm(ast, AST_REG_SCU040); 551 ast_moutdwm(ast, AST_REG_SCU040, temp | 0x40); 552 } 553 554 /* wait ready */ 555 do { 556 reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); 557 } while ((reg & 0x40) == 0); 558 } 559 560 int ast_2500_post(struct ast_device *ast) 561 { 562 ast_2300_set_def_ext_reg(ast); 563 564 if (ast->config_mode == ast_use_p2a) { 565 ast_post_chip_2500(ast); 566 } else { 567 if (ast->tx_chip == AST_TX_SIL164) { 568 /* Enable DVO */ 569 ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); 570 } 571 } 572 573 return 0; 574 } 575 576 /* 577 * Mode setting 578 */ 579 580 const struct ast_vbios_dclk_info ast_2500_dclk_table[] = { 581 {0x2c, 0xe7, 0x03}, /* 00: VCLK25_175 */ 582 {0x95, 0x62, 0x03}, /* 01: VCLK28_322 */ 583 {0x67, 0x63, 0x01}, /* 02: VCLK31_5 */ 584 {0x76, 0x63, 0x01}, /* 03: VCLK36 */ 585 {0xee, 0x67, 0x01}, /* 04: VCLK40 */ 586 {0x82, 0x62, 0x01}, /* 05: VCLK49_5 */ 587 {0xc6, 0x64, 0x01}, /* 06: VCLK50 */ 588 {0x94, 0x62, 0x01}, /* 07: VCLK56_25 */ 589 {0x80, 0x64, 0x00}, /* 08: VCLK65 */ 590 {0x7b, 0x63, 0x00}, /* 09: VCLK75 */ 591 {0x67, 0x62, 0x00}, /* 0a: VCLK78_75 */ 592 {0x7c, 0x62, 0x00}, /* 0b: VCLK94_5 */ 593 {0x8e, 0x62, 0x00}, /* 0c: VCLK108 */ 594 {0x85, 0x24, 0x00}, /* 0d: VCLK135 */ 595 {0x67, 0x22, 0x00}, /* 0e: VCLK157_5 */ 596 {0x6a, 0x22, 0x00}, /* 0f: VCLK162 */ 597 {0x4d, 0x4c, 0x80}, /* 10: VCLK154 */ 598 {0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */ 599 {0x28, 0x49, 0x80}, /* 12: VCLK106.5 */ 600 {0x37, 0x49, 0x80}, /* 13: VCLK146.25 */ 601 {0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */ 602 {0x47, 0x6c, 0x80}, /* 15: VCLK71 */ 603 {0x25, 0x65, 0x80}, /* 16: VCLK88.75 */ 604 {0x58, 0x01, 0x42}, /* 17: VCLK119 */ 605 {0x32, 0x67, 0x80}, /* 18: VCLK85_5 */ 606 {0x6a, 0x6d, 0x80}, /* 19: VCLK97_75 */ 607 {0x44, 0x20, 0x43}, /* 1a: VCLK118_25 */ 608 }; 609 610 /* 611 * Device initialization 612 */ 613 614 static void ast_2500_detect_widescreen(struct ast_device *ast) 615 { 616 if (__ast_2100_detect_wsxga_p(ast) || ast->chip == AST2510) { 617 ast->support_wsxga_p = true; 618 ast->support_fullhd = true; 619 } 620 if (__ast_2100_detect_wuxga(ast)) 621 ast->support_wuxga = true; 622 } 623 624 static const struct ast_device_quirks ast_2500_device_quirks = { 625 .crtc_mem_req_threshold_low = 96, 626 .crtc_mem_req_threshold_high = 120, 627 .crtc_hsync_precatch_needed = true, 628 }; 629 630 struct drm_device *ast_2500_device_create(struct pci_dev *pdev, 631 const struct drm_driver *drv, 632 enum ast_chip chip, 633 enum ast_config_mode config_mode, 634 void __iomem *regs, 635 void __iomem *ioregs, 636 bool need_post) 637 { 638 struct drm_device *dev; 639 struct ast_device *ast; 640 int ret; 641 642 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base); 643 if (IS_ERR(ast)) 644 return ERR_CAST(ast); 645 dev = &ast->base; 646 647 ast_device_init(ast, chip, config_mode, regs, ioregs, &ast_2500_device_quirks); 648 649 ast->dclk_table = ast_2500_dclk_table; 650 651 ast_2300_detect_tx_chip(ast); 652 653 if (need_post) { 654 ret = ast_post_gpu(ast); 655 if (ret) 656 return ERR_PTR(ret); 657 } 658 659 ret = ast_mm_init(ast); 660 if (ret) 661 return ERR_PTR(ret); 662 663 /* map reserved buffer */ 664 ast->dp501_fw_buf = NULL; 665 if (ast->vram_size < pci_resource_len(pdev, 0)) { 666 ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0); 667 if (!ast->dp501_fw_buf) 668 drm_info(dev, "failed to map reserved buffer!\n"); 669 } 670 671 ast_2500_detect_widescreen(ast); 672 673 ret = ast_mode_config_init(ast); 674 if (ret) 675 return ERR_PTR(ret); 676 677 return dev; 678 } 679