aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r--drivers/video/via/hw.c630
1 files changed, 210 insertions, 420 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index dc4c778877ce..47b13535ed2b 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -20,274 +20,84 @@
20 */ 20 */
21 21
22#include <linux/via-core.h> 22#include <linux/via-core.h>
23#include <asm/olpc.h>
23#include "global.h" 24#include "global.h"
24 25#include "via_clock.h"
25static struct pll_config cle266_pll_config[] = { 26
26 {19, 4, 0}, 27static struct pll_limit cle266_pll_limits[] = {
27 {26, 5, 0}, 28 {19, 19, 4, 0},
28 {28, 5, 0}, 29 {26, 102, 5, 0},
29 {31, 5, 0}, 30 {53, 112, 6, 0},
30 {33, 5, 0}, 31 {41, 100, 7, 0},
31 {55, 5, 0}, 32 {83, 108, 8, 0},
32 {102, 5, 0}, 33 {87, 118, 9, 0},
33 {53, 6, 0}, 34 {95, 115, 12, 0},
34 {92, 6, 0}, 35 {108, 108, 13, 0},
35 {98, 6, 0}, 36 {83, 83, 17, 0},
36 {112, 6, 0}, 37 {67, 98, 20, 0},
37 {41, 7, 0}, 38 {121, 121, 24, 0},
38 {60, 7, 0}, 39 {99, 99, 29, 0},
39 {99, 7, 0}, 40 {33, 33, 3, 1},
40 {100, 7, 0}, 41 {15, 23, 4, 1},
41 {83, 8, 0}, 42 {37, 121, 5, 1},
42 {86, 8, 0}, 43 {82, 82, 6, 1},
43 {108, 8, 0}, 44 {31, 84, 7, 1},
44 {87, 9, 0}, 45 {83, 83, 8, 1},
45 {118, 9, 0}, 46 {76, 127, 9, 1},
46 {95, 12, 0}, 47 {33, 121, 4, 2},
47 {115, 12, 0}, 48 {91, 118, 5, 2},
48 {108, 13, 0}, 49 {83, 109, 6, 2},
49 {83, 17, 0}, 50 {90, 90, 7, 2},
50 {67, 20, 0}, 51 {93, 93, 2, 3},
51 {86, 20, 0}, 52 {53, 53, 3, 3},
52 {98, 20, 0}, 53 {73, 117, 4, 3},
53 {121, 24, 0}, 54 {101, 127, 5, 3},
54 {99, 29, 0}, 55 {99, 99, 7, 3}
55 {33, 3, 1},
56 {15, 4, 1},
57 {23, 4, 1},
58 {37, 5, 1},
59 {83, 5, 1},
60 {85, 5, 1},
61 {94, 5, 1},
62 {103, 5, 1},
63 {109, 5, 1},
64 {113, 5, 1},
65 {121, 5, 1},
66 {82, 6, 1},
67 {31, 7, 1},
68 {55, 7, 1},
69 {84, 7, 1},
70 {83, 8, 1},
71 {76, 9, 1},
72 {127, 9, 1},
73 {33, 4, 2},
74 {75, 4, 2},
75 {119, 4, 2},
76 {121, 4, 2},
77 {91, 5, 2},
78 {118, 5, 2},
79 {83, 6, 2},
80 {109, 6, 2},
81 {90, 7, 2},
82 {93, 2, 3},
83 {53, 3, 3},
84 {73, 4, 3},
85 {89, 4, 3},
86 {105, 4, 3},
87 {117, 4, 3},
88 {101, 5, 3},
89 {121, 5, 3},
90 {127, 5, 3},
91 {99, 7, 3}
92}; 56};
93 57
94static struct pll_config k800_pll_config[] = { 58static struct pll_limit k800_pll_limits[] = {
95 {22, 2, 0}, 59 {22, 22, 2, 0},
96 {28, 3, 0}, 60 {28, 28, 3, 0},
97 {81, 3, 1}, 61 {81, 112, 3, 1},
98 {85, 3, 1}, 62 {86, 166, 4, 1},
99 {98, 3, 1}, 63 {109, 153, 5, 1},
100 {112, 3, 1}, 64 {66, 116, 3, 2},
101 {86, 4, 1}, 65 {93, 137, 4, 2},
102 {166, 4, 1}, 66 {117, 208, 5, 2},
103 {109, 5, 1}, 67 {30, 30, 2, 3},
104 {113, 5, 1}, 68 {69, 125, 3, 3},
105 {121, 5, 1}, 69 {89, 161, 4, 3},
106 {131, 5, 1}, 70 {121, 208, 5, 3},
107 {143, 5, 1}, 71 {66, 66, 2, 4},
108 {153, 5, 1}, 72 {85, 85, 3, 4},
109 {66, 3, 2}, 73 {141, 161, 4, 4},
110 {68, 3, 2}, 74 {177, 177, 5, 4}
111 {95, 3, 2},
112 {106, 3, 2},
113 {116, 3, 2},
114 {93, 4, 2},
115 {119, 4, 2},
116 {121, 4, 2},
117 {133, 4, 2},
118 {137, 4, 2},
119 {117, 5, 2},
120 {118, 5, 2},
121 {120, 5, 2},
122 {124, 5, 2},
123 {132, 5, 2},
124 {137, 5, 2},
125 {141, 5, 2},
126 {166, 5, 2},
127 {170, 5, 2},
128 {191, 5, 2},
129 {206, 5, 2},
130 {208, 5, 2},
131 {30, 2, 3},
132 {69, 3, 3},
133 {82, 3, 3},
134 {83, 3, 3},
135 {109, 3, 3},
136 {114, 3, 3},
137 {125, 3, 3},
138 {89, 4, 3},
139 {103, 4, 3},
140 {117, 4, 3},
141 {126, 4, 3},
142 {150, 4, 3},
143 {161, 4, 3},
144 {121, 5, 3},
145 {127, 5, 3},
146 {131, 5, 3},
147 {134, 5, 3},
148 {148, 5, 3},
149 {169, 5, 3},
150 {172, 5, 3},
151 {182, 5, 3},
152 {195, 5, 3},
153 {196, 5, 3},
154 {208, 5, 3},
155 {66, 2, 4},
156 {85, 3, 4},
157 {141, 4, 4},
158 {146, 4, 4},
159 {161, 4, 4},
160 {177, 5, 4}
161}; 75};
162 76
163static struct pll_config cx700_pll_config[] = { 77static struct pll_limit cx700_pll_limits[] = {
164 {98, 3, 1}, 78 {98, 98, 3, 1},
165 {86, 4, 1}, 79 {86, 86, 4, 1},
166 {109, 5, 1}, 80 {109, 208, 5, 1},
167 {110, 5, 1}, 81 {68, 68, 2, 2},
168 {113, 5, 1}, 82 {95, 116, 3, 2},
169 {121, 5, 1}, 83 {93, 166, 4, 2},
170 {131, 5, 1}, 84 {110, 206, 5, 2},
171 {135, 5, 1}, 85 {174, 174, 7, 2},
172 {142, 5, 1}, 86 {82, 109, 3, 3},
173 {143, 5, 1}, 87 {117, 161, 4, 3},
174 {153, 5, 1}, 88 {112, 208, 5, 3},
175 {187, 5, 1}, 89 {141, 202, 5, 4}
176 {208, 5, 1},
177 {68, 2, 2},
178 {95, 3, 2},
179 {116, 3, 2},
180 {93, 4, 2},
181 {119, 4, 2},
182 {133, 4, 2},
183 {137, 4, 2},
184 {151, 4, 2},
185 {166, 4, 2},
186 {110, 5, 2},
187 {112, 5, 2},
188 {117, 5, 2},
189 {118, 5, 2},
190 {120, 5, 2},
191 {132, 5, 2},
192 {137, 5, 2},
193 {141, 5, 2},
194 {151, 5, 2},
195 {166, 5, 2},
196 {175, 5, 2},
197 {191, 5, 2},
198 {206, 5, 2},
199 {174, 7, 2},
200 {82, 3, 3},
201 {109, 3, 3},
202 {117, 4, 3},
203 {150, 4, 3},
204 {161, 4, 3},
205 {112, 5, 3},
206 {115, 5, 3},
207 {121, 5, 3},
208 {127, 5, 3},
209 {129, 5, 3},
210 {131, 5, 3},
211 {134, 5, 3},
212 {138, 5, 3},
213 {148, 5, 3},
214 {157, 5, 3},
215 {169, 5, 3},
216 {172, 5, 3},
217 {190, 5, 3},
218 {195, 5, 3},
219 {196, 5, 3},
220 {208, 5, 3},
221 {141, 5, 4},
222 {150, 5, 4},
223 {166, 5, 4},
224 {176, 5, 4},
225 {177, 5, 4},
226 {183, 5, 4},
227 {202, 5, 4}
228}; 90};
229 91
230static struct pll_config vx855_pll_config[] = { 92static struct pll_limit vx855_pll_limits[] = {
231 {86, 4, 1}, 93 {86, 86, 4, 1},
232 {108, 5, 1}, 94 {108, 208, 5, 1},
233 {110, 5, 1}, 95 {110, 208, 5, 2},
234 {113, 5, 1}, 96 {83, 112, 3, 3},
235 {121, 5, 1}, 97 {103, 161, 4, 3},
236 {131, 5, 1}, 98 {112, 209, 5, 3},
237 {135, 5, 1}, 99 {142, 161, 4, 4},
238 {142, 5, 1}, 100 {141, 176, 5, 4}
239 {143, 5, 1},
240 {153, 5, 1},
241 {164, 5, 1},
242 {187, 5, 1},
243 {208, 5, 1},
244 {110, 5, 2},
245 {112, 5, 2},
246 {117, 5, 2},
247 {118, 5, 2},
248 {124, 5, 2},
249 {132, 5, 2},
250 {137, 5, 2},
251 {141, 5, 2},
252 {149, 5, 2},
253 {151, 5, 2},
254 {159, 5, 2},
255 {166, 5, 2},
256 {167, 5, 2},
257 {172, 5, 2},
258 {189, 5, 2},
259 {191, 5, 2},
260 {194, 5, 2},
261 {206, 5, 2},
262 {208, 5, 2},
263 {83, 3, 3},
264 {88, 3, 3},
265 {109, 3, 3},
266 {112, 3, 3},
267 {103, 4, 3},
268 {105, 4, 3},
269 {161, 4, 3},
270 {112, 5, 3},
271 {115, 5, 3},
272 {121, 5, 3},
273 {127, 5, 3},
274 {134, 5, 3},
275 {137, 5, 3},
276 {148, 5, 3},
277 {157, 5, 3},
278 {169, 5, 3},
279 {172, 5, 3},
280 {182, 5, 3},
281 {191, 5, 3},
282 {195, 5, 3},
283 {209, 5, 3},
284 {142, 4, 4},
285 {146, 4, 4},
286 {161, 4, 4},
287 {141, 5, 4},
288 {150, 5, 4},
289 {165, 5, 4},
290 {176, 5, 4}
291}; 101};
292 102
293/* according to VIA Technologies these values are based on experiment */ 103/* according to VIA Technologies these values are based on experiment */
@@ -308,6 +118,42 @@ static struct io_reg scaling_parameters[] = {
308 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */ 118 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
309}; 119};
310 120
121static struct io_reg common_vga[] = {
122 {VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
123 [1] vertical display end (bit 8)
124 [2] vertical retrace start (bit 8)
125 [3] start vertical blanking (bit 8)
126 [4] line compare (bit 8)
127 [5] vertical total (bit 9)
128 [6] vertical display end (bit 9)
129 [7] vertical retrace start (bit 9) */
130 {VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
131 [5-6] byte panning */
132 {VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
133 [5] start vertical blanking (bit 9)
134 [6] line compare (bit 9)
135 [7] scan doubling */
136 {VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
137 [5] cursor disable */
138 {VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
139 [5-6] cursor skew */
140 {VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
141 {VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
142 {VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
143 [6] memory refresh bandwidth
144 [7] CRTC register protect enable */
145 {VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
146 [5] divide memory address clock by 4
147 [6] double word addressing */
148 {VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
149 [2] divide scan line clock by 2
150 [3] divide memory address clock by 2
151 [5] address wrap
152 [6] byte mode select
153 [7] sync enable */
154 {VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
155};
156
311static struct fifo_depth_select display_fifo_depth_reg = { 157static struct fifo_depth_select display_fifo_depth_reg = {
312 /* IGA1 FIFO Depth_Select */ 158 /* IGA1 FIFO Depth_Select */
313 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, 159 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
@@ -676,6 +522,9 @@ static struct via_device_mapping device_mapping[] = {
676 {VIA_LVDS2, "LVDS2"} 522 {VIA_LVDS2, "LVDS2"}
677}; 523};
678 524
525/* structure with function pointers to support clock control */
526static struct via_clock clock;
527
679static void load_fix_bit_crtc_reg(void); 528static void load_fix_bit_crtc_reg(void);
680static void __devinit init_gfx_chip_info(int chip_type); 529static void __devinit init_gfx_chip_info(int chip_type);
681static void __devinit init_tmds_chip_info(void); 530static void __devinit init_tmds_chip_info(void);
@@ -770,13 +619,14 @@ static u32 get_lcd_devices(int output_interface)
770/*Set IGA path for each device*/ 619/*Set IGA path for each device*/
771void viafb_set_iga_path(void) 620void viafb_set_iga_path(void)
772{ 621{
622 int crt_iga_path = 0;
773 623
774 if (viafb_SAMM_ON == 1) { 624 if (viafb_SAMM_ON == 1) {
775 if (viafb_CRT_ON) { 625 if (viafb_CRT_ON) {
776 if (viafb_primary_dev == CRT_Device) 626 if (viafb_primary_dev == CRT_Device)
777 viaparinfo->crt_setting_info->iga_path = IGA1; 627 crt_iga_path = IGA1;
778 else 628 else
779 viaparinfo->crt_setting_info->iga_path = IGA2; 629 crt_iga_path = IGA2;
780 } 630 }
781 631
782 if (viafb_DVI_ON) { 632 if (viafb_DVI_ON) {
@@ -793,8 +643,7 @@ void viafb_set_iga_path(void)
793 UNICHROME_CLE266)) { 643 UNICHROME_CLE266)) {
794 viaparinfo-> 644 viaparinfo->
795 lvds_setting_info->iga_path = IGA2; 645 lvds_setting_info->iga_path = IGA2;
796 viaparinfo-> 646 crt_iga_path = IGA1;
797 crt_setting_info->iga_path = IGA1;
798 viaparinfo-> 647 viaparinfo->
799 tmds_setting_info->iga_path = IGA1; 648 tmds_setting_info->iga_path = IGA1;
800 } else 649 } else
@@ -814,10 +663,10 @@ void viafb_set_iga_path(void)
814 viafb_SAMM_ON = 0; 663 viafb_SAMM_ON = 0;
815 664
816 if (viafb_CRT_ON && viafb_LCD_ON) { 665 if (viafb_CRT_ON && viafb_LCD_ON) {
817 viaparinfo->crt_setting_info->iga_path = IGA1; 666 crt_iga_path = IGA1;
818 viaparinfo->lvds_setting_info->iga_path = IGA2; 667 viaparinfo->lvds_setting_info->iga_path = IGA2;
819 } else if (viafb_CRT_ON && viafb_DVI_ON) { 668 } else if (viafb_CRT_ON && viafb_DVI_ON) {
820 viaparinfo->crt_setting_info->iga_path = IGA1; 669 crt_iga_path = IGA1;
821 viaparinfo->tmds_setting_info->iga_path = IGA2; 670 viaparinfo->tmds_setting_info->iga_path = IGA2;
822 } else if (viafb_LCD_ON && viafb_DVI_ON) { 671 } else if (viafb_LCD_ON && viafb_DVI_ON) {
823 viaparinfo->tmds_setting_info->iga_path = IGA1; 672 viaparinfo->tmds_setting_info->iga_path = IGA1;
@@ -826,7 +675,7 @@ void viafb_set_iga_path(void)
826 viaparinfo->lvds_setting_info->iga_path = IGA2; 675 viaparinfo->lvds_setting_info->iga_path = IGA2;
827 viaparinfo->lvds_setting_info2->iga_path = IGA2; 676 viaparinfo->lvds_setting_info2->iga_path = IGA2;
828 } else if (viafb_CRT_ON) { 677 } else if (viafb_CRT_ON) {
829 viaparinfo->crt_setting_info->iga_path = IGA1; 678 crt_iga_path = IGA1;
830 } else if (viafb_LCD_ON) { 679 } else if (viafb_LCD_ON) {
831 viaparinfo->lvds_setting_info->iga_path = IGA2; 680 viaparinfo->lvds_setting_info->iga_path = IGA2;
832 } else if (viafb_DVI_ON) { 681 } else if (viafb_DVI_ON) {
@@ -837,7 +686,7 @@ void viafb_set_iga_path(void)
837 viaparinfo->shared->iga1_devices = 0; 686 viaparinfo->shared->iga1_devices = 0;
838 viaparinfo->shared->iga2_devices = 0; 687 viaparinfo->shared->iga2_devices = 0;
839 if (viafb_CRT_ON) { 688 if (viafb_CRT_ON) {
840 if (viaparinfo->crt_setting_info->iga_path == IGA1) 689 if (crt_iga_path == IGA1)
841 viaparinfo->shared->iga1_devices |= VIA_CRT; 690 viaparinfo->shared->iga1_devices |= VIA_CRT;
842 else 691 else
843 viaparinfo->shared->iga2_devices |= VIA_CRT; 692 viaparinfo->shared->iga2_devices |= VIA_CRT;
@@ -875,6 +724,10 @@ void viafb_set_iga_path(void)
875 viaparinfo->chip_info-> 724 viaparinfo->chip_info->
876 lvds_chip_info2.output_interface); 725 lvds_chip_info2.output_interface);
877 } 726 }
727
728 /* looks like the OLPC has its display wired to DVP1 and LVDS2 */
729 if (machine_is_olpc())
730 viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
878} 731}
879 732
880static void set_color_register(u8 index, u8 red, u8 green, u8 blue) 733static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
@@ -1162,25 +1015,17 @@ void via_odev_to_seq(struct seq_file *m, u32 odev)
1162 1015
1163static void load_fix_bit_crtc_reg(void) 1016static void load_fix_bit_crtc_reg(void)
1164{ 1017{
1018 viafb_unlock_crt();
1019
1165 /* always set to 1 */ 1020 /* always set to 1 */
1166 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7); 1021 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1167 /* line compare should set all bits = 1 (extend modes) */ 1022 /* line compare should set all bits = 1 (extend modes) */
1168 viafb_write_reg(CR18, VIACR, 0xff);
1169 /* line compare should set all bits = 1 (extend modes) */
1170 viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1171 /* line compare should set all bits = 1 (extend modes) */
1172 viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1173 /* line compare should set all bits = 1 (extend modes) */
1174 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4); 1023 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1175 /* line compare should set all bits = 1 (extend modes) */ 1024 /* line compare should set all bits = 1 (extend modes) */
1176 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2); 1025 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1177 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ 1026 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1178 /* extend mode always set to e3h */ 1027
1179 viafb_write_reg(CR17, VIACR, 0xe3); 1028 viafb_lock_crt();
1180 /* extend mode always set to 0h */
1181 viafb_write_reg(CR08, VIACR, 0x00);
1182 /* extend mode always set to 0h */
1183 viafb_write_reg(CR14, VIACR, 0x00);
1184 1029
1185 /* If K8M800, enable Prefetch Mode. */ 1030 /* If K8M800, enable Prefetch Mode. */
1186 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) 1031 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
@@ -1601,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1601 1446
1602} 1447}
1603 1448
1604static u32 cle266_encode_pll(struct pll_config pll) 1449static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
1605{
1606 return (pll.multiplier << 8)
1607 | (pll.rshift << 6)
1608 | pll.divisor;
1609}
1610
1611static u32 k800_encode_pll(struct pll_config pll)
1612{
1613 return ((pll.divisor - 2) << 16)
1614 | (pll.rshift << 10)
1615 | (pll.multiplier - 2);
1616}
1617
1618static u32 vx855_encode_pll(struct pll_config pll)
1619{
1620 return (pll.divisor << 16)
1621 | (pll.rshift << 10)
1622 | pll.multiplier;
1623}
1624
1625static inline u32 get_pll_internal_frequency(u32 ref_freq,
1626 struct pll_config pll)
1627{
1628 return ref_freq / pll.divisor * pll.multiplier;
1629}
1630
1631static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1632{
1633 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1634}
1635
1636static struct pll_config get_pll_config(struct pll_config *config, int size,
1637 int clk) 1450 int clk)
1638{ 1451{
1639 struct pll_config best = config[0]; 1452 struct via_pll_config cur, up, down, best = {0, 1, 0};
1640 const u32 f0 = 14318180; /* X1 frequency */ 1453 const u32 f0 = 14318180; /* X1 frequency */
1641 int i; 1454 int i, f;
1642 1455
1643 for (i = 1; i < size; i++) { 1456 for (i = 0; i < size; i++) {
1644 if (abs(get_pll_output_frequency(f0, config[i]) - clk) 1457 cur.rshift = limits[i].rshift;
1645 < abs(get_pll_output_frequency(f0, best) - clk)) 1458 cur.divisor = limits[i].divisor;
1646 best = config[i]; 1459 cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
1460 f = abs(get_pll_output_frequency(f0, cur) - clk);
1461 up = down = cur;
1462 up.multiplier++;
1463 down.multiplier--;
1464 if (abs(get_pll_output_frequency(f0, up) - clk) < f)
1465 cur = up;
1466 else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
1467 cur = down;
1468
1469 if (cur.multiplier < limits[i].multiplier_min)
1470 cur.multiplier = limits[i].multiplier_min;
1471 else if (cur.multiplier > limits[i].multiplier_max)
1472 cur.multiplier = limits[i].multiplier_max;
1473
1474 f = abs(get_pll_output_frequency(f0, cur) - clk);
1475 if (f < abs(get_pll_output_frequency(f0, best) - clk))
1476 best = cur;
1647 } 1477 }
1648 1478
1649 return best; 1479 return best;
1650} 1480}
1651 1481
1652u32 viafb_get_clk_value(int clk) 1482static struct via_pll_config get_best_pll_config(int clk)
1653{ 1483{
1654 u32 value = 0; 1484 struct via_pll_config config;
1655 1485
1656 switch (viaparinfo->chip_info->gfx_chip_name) { 1486 switch (viaparinfo->chip_info->gfx_chip_name) {
1657 case UNICHROME_CLE266: 1487 case UNICHROME_CLE266:
1658 case UNICHROME_K400: 1488 case UNICHROME_K400:
1659 value = cle266_encode_pll(get_pll_config(cle266_pll_config, 1489 config = get_pll_config(cle266_pll_limits,
1660 ARRAY_SIZE(cle266_pll_config), clk)); 1490 ARRAY_SIZE(cle266_pll_limits), clk);
1661 break; 1491 break;
1662 case UNICHROME_K800: 1492 case UNICHROME_K800:
1663 case UNICHROME_PM800: 1493 case UNICHROME_PM800:
1664 case UNICHROME_CN700: 1494 case UNICHROME_CN700:
1665 value = k800_encode_pll(get_pll_config(k800_pll_config, 1495 config = get_pll_config(k800_pll_limits,
1666 ARRAY_SIZE(k800_pll_config), clk)); 1496 ARRAY_SIZE(k800_pll_limits), clk);
1667 break; 1497 break;
1668 case UNICHROME_CX700: 1498 case UNICHROME_CX700:
1669 case UNICHROME_CN750: 1499 case UNICHROME_CN750:
@@ -1671,92 +1501,28 @@ u32 viafb_get_clk_value(int clk)
1671 case UNICHROME_P4M890: 1501 case UNICHROME_P4M890:
1672 case UNICHROME_P4M900: 1502 case UNICHROME_P4M900:
1673 case UNICHROME_VX800: 1503 case UNICHROME_VX800:
1674 value = k800_encode_pll(get_pll_config(cx700_pll_config, 1504 config = get_pll_config(cx700_pll_limits,
1675 ARRAY_SIZE(cx700_pll_config), clk)); 1505 ARRAY_SIZE(cx700_pll_limits), clk);
1676 break; 1506 break;
1677 case UNICHROME_VX855: 1507 case UNICHROME_VX855:
1678 case UNICHROME_VX900: 1508 case UNICHROME_VX900:
1679 value = vx855_encode_pll(get_pll_config(vx855_pll_config, 1509 config = get_pll_config(vx855_pll_limits,
1680 ARRAY_SIZE(vx855_pll_config), clk)); 1510 ARRAY_SIZE(vx855_pll_limits), clk);
1681 break; 1511 break;
1682 } 1512 }
1683 1513
1684 return value; 1514 return config;
1685} 1515}
1686 1516
1687/* Set VCLK*/ 1517/* Set VCLK*/
1688void viafb_set_vclock(u32 clk, int set_iga) 1518void viafb_set_vclock(u32 clk, int set_iga)
1689{ 1519{
1690 /* H.W. Reset : ON */ 1520 struct via_pll_config config = get_best_pll_config(clk);
1691 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1692 1521
1693 if (set_iga == IGA1) { 1522 if (set_iga == IGA1)
1694 /* Change D,N FOR VCLK */ 1523 clock.set_primary_pll(config);
1695 switch (viaparinfo->chip_info->gfx_chip_name) { 1524 if (set_iga == IGA2)
1696 case UNICHROME_CLE266: 1525 clock.set_secondary_pll(config);
1697 case UNICHROME_K400:
1698 via_write_reg(VIASR, SR46, (clk & 0x00FF));
1699 via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1700 break;
1701
1702 case UNICHROME_K800:
1703 case UNICHROME_PM800:
1704 case UNICHROME_CN700:
1705 case UNICHROME_CX700:
1706 case UNICHROME_CN750:
1707 case UNICHROME_K8M890:
1708 case UNICHROME_P4M890:
1709 case UNICHROME_P4M900:
1710 case UNICHROME_VX800:
1711 case UNICHROME_VX855:
1712 case UNICHROME_VX900:
1713 via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1714 via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1715 via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1716 break;
1717 }
1718 }
1719
1720 if (set_iga == IGA2) {
1721 /* Change D,N FOR LCK */
1722 switch (viaparinfo->chip_info->gfx_chip_name) {
1723 case UNICHROME_CLE266:
1724 case UNICHROME_K400:
1725 via_write_reg(VIASR, SR44, (clk & 0x00FF));
1726 via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1727 break;
1728
1729 case UNICHROME_K800:
1730 case UNICHROME_PM800:
1731 case UNICHROME_CN700:
1732 case UNICHROME_CX700:
1733 case UNICHROME_CN750:
1734 case UNICHROME_K8M890:
1735 case UNICHROME_P4M890:
1736 case UNICHROME_P4M900:
1737 case UNICHROME_VX800:
1738 case UNICHROME_VX855:
1739 case UNICHROME_VX900:
1740 via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1741 via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1742 via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1743 break;
1744 }
1745 }
1746
1747 /* H.W. Reset : OFF */
1748 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1749
1750 /* Reset PLL */
1751 if (set_iga == IGA1) {
1752 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1753 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1754 }
1755
1756 if (set_iga == IGA2) {
1757 viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
1758 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
1759 }
1760 1526
1761 /* Fire! */ 1527 /* Fire! */
1762 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ 1528 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
@@ -2002,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2002 int i; 1768 int i;
2003 int index = 0; 1769 int index = 0;
2004 int h_addr, v_addr; 1770 int h_addr, v_addr;
2005 u32 pll_D_N, clock, refresh = viafb_refresh; 1771 u32 clock, refresh = viafb_refresh;
2006 1772
2007 if (viafb_SAMM_ON && set_iga == IGA2) 1773 if (viafb_SAMM_ON && set_iga == IGA2)
2008 refresh = viafb_refresh1; 1774 refresh = viafb_refresh1;
@@ -2033,8 +1799,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2033 v_addr = crt_reg.ver_addr; 1799 v_addr = crt_reg.ver_addr;
2034 if (set_iga == IGA1) { 1800 if (set_iga == IGA1) {
2035 viafb_unlock_crt(); 1801 viafb_unlock_crt();
2036 viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
2037 viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
2038 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1802 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
2039 } 1803 }
2040 1804
@@ -2047,7 +1811,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2047 break; 1811 break;
2048 } 1812 }
2049 1813
2050 load_fix_bit_crtc_reg();
2051 viafb_lock_crt(); 1814 viafb_lock_crt();
2052 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 1815 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
2053 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); 1816 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
@@ -2059,20 +1822,17 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2059 1822
2060 clock = crt_reg.hor_total * crt_reg.ver_total 1823 clock = crt_reg.hor_total * crt_reg.ver_total
2061 * crt_table[index].refresh_rate; 1824 * crt_table[index].refresh_rate;
2062 pll_D_N = viafb_get_clk_value(clock); 1825 viafb_set_vclock(clock, set_iga);
2063 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
2064 viafb_set_vclock(pll_D_N, set_iga);
2065 1826
2066} 1827}
2067 1828
2068void __devinit viafb_init_chip_info(int chip_type) 1829void __devinit viafb_init_chip_info(int chip_type)
2069{ 1830{
1831 via_clock_init(&clock, chip_type);
2070 init_gfx_chip_info(chip_type); 1832 init_gfx_chip_info(chip_type);
2071 init_tmds_chip_info(); 1833 init_tmds_chip_info();
2072 init_lvds_chip_info(); 1834 init_lvds_chip_info();
2073 1835
2074 viaparinfo->crt_setting_info->iga_path = IGA1;
2075
2076 /*Set IGA path for each device */ 1836 /*Set IGA path for each device */
2077 viafb_set_iga_path(); 1837 viafb_set_iga_path();
2078 1838
@@ -2354,6 +2114,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2354 outb(0x00, VIAAR); 2114 outb(0x00, VIAAR);
2355 2115
2356 /* Write Common Setting for Video Mode */ 2116 /* Write Common Setting for Video Mode */
2117 viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));
2357 switch (viaparinfo->chip_info->gfx_chip_name) { 2118 switch (viaparinfo->chip_info->gfx_chip_name) {
2358 case UNICHROME_CLE266: 2119 case UNICHROME_CLE266:
2359 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); 2120 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
@@ -2400,9 +2161,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2400 2161
2401 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); 2162 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
2402 2163
2403 /* Write CRTC */
2404 viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
2405
2406 /* Write Graphic Controller */ 2164 /* Write Graphic Controller */
2407 for (i = 0; i < StdGR; i++) 2165 for (i = 0; i < StdGR; i++)
2408 via_write_reg(VIAGR, i, VPIT.GR[i]); 2166 via_write_reg(VIAGR, i, VPIT.GR[i]);
@@ -2432,6 +2190,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2432 } 2190 }
2433 } 2191 }
2434 2192
2193 load_fix_bit_crtc_reg();
2435 via_set_primary_pitch(viafbinfo->fix.line_length); 2194 via_set_primary_pitch(viafbinfo->fix.line_length);
2436 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length 2195 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2437 : viafbinfo->fix.line_length); 2196 : viafbinfo->fix.line_length);
@@ -2451,15 +2210,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2451 2210
2452 /* CRT set mode */ 2211 /* CRT set mode */
2453 if (viafb_CRT_ON) { 2212 if (viafb_CRT_ON) {
2454 if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == 2213 if (viafb_SAMM_ON &&
2455 IGA2)) { 2214 viaparinfo->shared->iga2_devices & VIA_CRT) {
2456 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, 2215 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
2457 video_bpp1 / 8, 2216 video_bpp1 / 8, IGA2);
2458 viaparinfo->crt_setting_info->iga_path);
2459 } else { 2217 } else {
2460 viafb_fill_crtc_timing(crt_timing, vmode_tbl, 2218 viafb_fill_crtc_timing(crt_timing, vmode_tbl,
2461 video_bpp / 8, 2219 video_bpp / 8,
2462 viaparinfo->crt_setting_info->iga_path); 2220 (viaparinfo->shared->iga1_devices & VIA_CRT)
2221 ? IGA1 : IGA2);
2463 } 2222 }
2464 2223
2465 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode 2224 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
@@ -2557,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2557 get_sync(viafbinfo1)); 2316 get_sync(viafbinfo1));
2558 } 2317 }
2559 2318
2319 clock.set_engine_pll_state(VIA_STATE_ON);
2320 clock.set_primary_clock_source(VIA_CLKSRC_X1, true);
2321 clock.set_secondary_clock_source(VIA_CLKSRC_X1, true);
2322
2323#ifdef CONFIG_FB_VIA_X_COMPATIBILITY
2324 clock.set_primary_pll_state(VIA_STATE_ON);
2325 clock.set_primary_clock_state(VIA_STATE_ON);
2326 clock.set_secondary_pll_state(VIA_STATE_ON);
2327 clock.set_secondary_clock_state(VIA_STATE_ON);
2328#else
2329 if (viaparinfo->shared->iga1_devices) {
2330 clock.set_primary_pll_state(VIA_STATE_ON);
2331 clock.set_primary_clock_state(VIA_STATE_ON);
2332 } else {
2333 clock.set_primary_pll_state(VIA_STATE_OFF);
2334 clock.set_primary_clock_state(VIA_STATE_OFF);
2335 }
2336
2337 if (viaparinfo->shared->iga2_devices) {
2338 clock.set_secondary_pll_state(VIA_STATE_ON);
2339 clock.set_secondary_clock_state(VIA_STATE_ON);
2340 } else {
2341 clock.set_secondary_pll_state(VIA_STATE_OFF);
2342 clock.set_secondary_clock_state(VIA_STATE_OFF);
2343 }
2344#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/
2345
2560 via_set_state(devices, VIA_STATE_ON); 2346 via_set_state(devices, VIA_STATE_ON);
2561 device_screen_on(); 2347 device_screen_on();
2562 return 1; 2348 return 1;
@@ -2598,8 +2384,12 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2598 best = &vmode->crtc[i]; 2384 best = &vmode->crtc[i];
2599 } 2385 }
2600 2386
2601 if (abs(best->refresh_rate - long_refresh) > 3) 2387 if (abs(best->refresh_rate - long_refresh) > 3) {
2602 return 60; 2388 if (hres == 1200 && vres == 900)
2389 return 49; /* OLPC DCON only supports 50 Hz */
2390 else
2391 return 60;
2392 }
2603 2393
2604 return best->refresh_rate; 2394 return best->refresh_rate;
2605} 2395}