Commit | Line | Data |
---|---|---|
81dee67e SM |
1 | |
2 | #include "ddk750_help.h" | |
3 | #include "ddk750_reg.h" | |
4 | #include "ddk750_mode.h" | |
5 | #include "ddk750_chip.h" | |
6 | ||
7 | /* | |
8 | SM750LE only: | |
9 | This function takes care extra registers and bit fields required to set | |
10 | up a mode in SM750LE | |
11 | ||
12 | Explanation about Display Control register: | |
13 | HW only supports 7 predefined pixel clocks, and clock select is | |
14 | in bit 29:27 of Display Control register. | |
15 | */ | |
16 | static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl) | |
17 | { | |
18 | unsigned long x, y; | |
19 | ||
20 | x = pModeParam->horizontal_display_end; | |
21 | y = pModeParam->vertical_display_end; | |
22 | ||
23 | /* SM750LE has to set up the top-left and bottom-right | |
24 | registers as well. | |
25 | Note that normal SM750/SM718 only use those two register for | |
26 | auto-centering mode. | |
27 | */ | |
28 | POKE32(CRT_AUTO_CENTERING_TL, | |
29 | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0) | |
30 | | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0)); | |
31 | ||
32 | POKE32(CRT_AUTO_CENTERING_BR, | |
33 | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1) | |
34 | | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1)); | |
35 | ||
36 | /* Assume common fields in dispControl have been properly set before | |
37 | calling this function. | |
38 | This function only sets the extra fields in dispControl. | |
39 | */ | |
40 | ||
41 | /* Clear bit 29:27 of display control register */ | |
42 | dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK); | |
43 | ||
44 | /* Set bit 29:27 of display control register for the right clock */ | |
45 | /* Note that SM750LE only need to supported 7 resoluitons. */ | |
46 | if ( x == 800 && y == 600 ) | |
47 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41); | |
48 | else if (x == 1024 && y == 768) | |
49 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65); | |
50 | else if (x == 1152 && y == 864) | |
51 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); | |
52 | else if (x == 1280 && y == 768) | |
53 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); | |
54 | else if (x == 1280 && y == 720) | |
55 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74); | |
56 | else if (x == 1280 && y == 960) | |
57 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); | |
58 | else if (x == 1280 && y == 1024) | |
59 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); | |
60 | else /* default to VGA clock */ | |
61 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25); | |
62 | ||
63 | /* Set bit 25:24 of display controller */ | |
64 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT); | |
65 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT); | |
66 | ||
67 | /* Set bit 14 of display controller */ | |
68 | dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW); | |
69 | ||
70 | POKE32(CRT_DISPLAY_CTRL, dispControl); | |
71 | ||
72 | return dispControl; | |
73 | } | |
74 | ||
75 | ||
76 | ||
77 | /* only timing related registers will be programed */ | |
78 | static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) | |
79 | { | |
80 | int ret = 0; | |
81 | int cnt = 0; | |
82 | unsigned int ulTmpValue,ulReg; | |
83 | if(pll->clockType == SECONDARY_PLL) | |
84 | { | |
85 | /* programe secondary pixel clock */ | |
86 | POKE32(CRT_PLL_CTRL,formatPllReg(pll)); | |
87 | POKE32(CRT_HORIZONTAL_TOTAL, | |
88 | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | |
89 | | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); | |
90 | ||
91 | POKE32(CRT_HORIZONTAL_SYNC, | |
92 | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) | |
93 | | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); | |
94 | ||
95 | POKE32(CRT_VERTICAL_TOTAL, | |
96 | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) | |
97 | | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); | |
98 | ||
99 | POKE32(CRT_VERTICAL_SYNC, | |
100 | FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | |
101 | | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); | |
102 | ||
103 | ||
104 | ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| | |
105 | FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| | |
106 | FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| | |
107 | FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); | |
108 | ||
109 | ||
110 | if(getChipType() == SM750LE){ | |
111 | displayControlAdjust_SM750LE(pModeParam,ulTmpValue); | |
112 | }else{ | |
113 | ulReg = PEEK32(CRT_DISPLAY_CTRL) | |
114 | & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) | |
115 | & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) | |
116 | & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) | |
117 | & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); | |
118 | ||
119 | POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); | |
120 | } | |
121 | ||
122 | } | |
123 | else if(pll->clockType == PRIMARY_PLL) | |
124 | { | |
125 | unsigned int ulReservedBits; | |
126 | POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); | |
127 | ||
128 | POKE32(PANEL_HORIZONTAL_TOTAL, | |
129 | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) | |
130 | | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); | |
131 | ||
132 | POKE32(PANEL_HORIZONTAL_SYNC, | |
133 | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) | |
134 | | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); | |
135 | ||
136 | POKE32(PANEL_VERTICAL_TOTAL, | |
137 | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) | |
138 | | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); | |
139 | ||
140 | POKE32(PANEL_VERTICAL_SYNC, | |
141 | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) | |
142 | | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); | |
143 | ||
144 | ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| | |
145 | FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| | |
146 | FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| | |
147 | FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| | |
148 | FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); | |
149 | ||
150 | ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | | |
151 | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | | |
152 | FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| | |
153 | FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); | |
154 | ||
155 | ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) | |
156 | & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) | |
157 | & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) | |
158 | & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) | |
159 | & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) | |
160 | & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); | |
161 | ||
162 | ||
163 | /* May a hardware bug or just my test chip (not confirmed). | |
164 | * PANEL_DISPLAY_CTRL register seems requiring few writes | |
165 | * before a value can be succesfully written in. | |
166 | * Added some masks to mask out the reserved bits. | |
167 | * Note: This problem happens by design. The hardware will wait for the | |
168 | * next vertical sync to turn on/off the plane. | |
169 | */ | |
170 | ||
171 | POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); | |
172 | #if 1 | |
173 | while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) | |
174 | { | |
175 | cnt++; | |
176 | if(cnt > 1000) | |
177 | break; | |
178 | POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); | |
179 | } | |
180 | #endif | |
181 | } | |
182 | else{ | |
183 | ret = -1; | |
184 | } | |
185 | return ret; | |
186 | } | |
187 | ||
188 | int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) | |
189 | { | |
190 | pll_value_t pll; | |
191 | unsigned int uiActualPixelClk; | |
192 | pll.inputFreq = DEFAULT_INPUT_CLOCK; | |
193 | pll.clockType = clock; | |
194 | ||
195 | uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); | |
196 | if(getChipType() == SM750LE){ | |
197 | /* set graphic mode via IO method */ | |
198 | outb_p(0x88,0x3d4); | |
199 | outb_p(0x06,0x3d5); | |
200 | } | |
201 | programModeRegisters(parm,&pll); | |
202 | return 0; | |
203 | } | |
204 | ||
205 |