source: src/linux/universal/linux-4.9/drivers/gpu/drm/ast/ast_post.c @ 31662

Last change on this file since 31662 was 31662, checked in by brainslayer, 4 months ago

use new squashfs in all kernels

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