2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <linux/via-core.h>
26 static struct pll_config cle266_pll_config[] = {
95 static struct pll_config k800_pll_config[] = {
164 static struct pll_config cx700_pll_config[] = {
231 static struct pll_config vx855_pll_config[] = {
294 /* according to VIA Technologies these values are based on experiment */
295 static struct io_reg scaling_parameters[] = {
296 {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
297 {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
298 {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
299 {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
300 {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
301 {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
302 {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
303 {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
304 {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
305 {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
306 {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
307 {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
308 {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
309 {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
312 static struct fifo_depth_select display_fifo_depth_reg = {
313 /* IGA1 FIFO Depth_Select */
314 {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
315 /* IGA2 FIFO Depth_Select */
316 {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
317 {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
320 static struct fifo_threshold_select fifo_threshold_select_reg = {
321 /* IGA1 FIFO Threshold Select */
322 {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
323 /* IGA2 FIFO Threshold Select */
324 {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
327 static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
328 /* IGA1 FIFO High Threshold Select */
329 {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
330 /* IGA2 FIFO High Threshold Select */
331 {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
334 static struct display_queue_expire_num display_queue_expire_num_reg = {
335 /* IGA1 Display Queue Expire Num */
336 {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
337 /* IGA2 Display Queue Expire Num */
338 {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
341 /* Definition Fetch Count Registers*/
342 static struct fetch_count fetch_count_reg = {
343 /* IGA1 Fetch Count Register */
344 {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
345 /* IGA2 Fetch Count Register */
346 {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
349 static struct iga1_crtc_timing iga1_crtc_reg = {
350 /* IGA1 Horizontal Total */
351 {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
352 /* IGA1 Horizontal Addressable Video */
353 {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
354 /* IGA1 Horizontal Blank Start */
355 {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
356 /* IGA1 Horizontal Blank End */
357 {IGA1_HOR_BLANK_END_REG_NUM,
358 {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
359 /* IGA1 Horizontal Sync Start */
360 {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
361 /* IGA1 Horizontal Sync End */
362 {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
363 /* IGA1 Vertical Total */
364 {IGA1_VER_TOTAL_REG_NUM,
365 {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
366 /* IGA1 Vertical Addressable Video */
367 {IGA1_VER_ADDR_REG_NUM,
368 {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
369 /* IGA1 Vertical Blank Start */
370 {IGA1_VER_BLANK_START_REG_NUM,
371 {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
372 /* IGA1 Vertical Blank End */
373 {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
374 /* IGA1 Vertical Sync Start */
375 {IGA1_VER_SYNC_START_REG_NUM,
376 {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
377 /* IGA1 Vertical Sync End */
378 {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
381 static struct iga2_crtc_timing iga2_crtc_reg = {
382 /* IGA2 Horizontal Total */
383 {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
384 /* IGA2 Horizontal Addressable Video */
385 {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
386 /* IGA2 Horizontal Blank Start */
387 {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
388 /* IGA2 Horizontal Blank End */
389 {IGA2_HOR_BLANK_END_REG_NUM,
390 {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
391 /* IGA2 Horizontal Sync Start */
392 {IGA2_HOR_SYNC_START_REG_NUM,
393 {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
394 /* IGA2 Horizontal Sync End */
395 {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
396 /* IGA2 Vertical Total */
397 {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
398 /* IGA2 Vertical Addressable Video */
399 {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
400 /* IGA2 Vertical Blank Start */
401 {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
402 /* IGA2 Vertical Blank End */
403 {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
404 /* IGA2 Vertical Sync Start */
405 {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
406 /* IGA2 Vertical Sync End */
407 {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
410 static struct rgbLUT palLUT_table[] = {
412 /* Index 0x00~0x03 */
413 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
416 /* Index 0x04~0x07 */
417 {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
420 /* Index 0x08~0x0B */
421 {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
424 /* Index 0x0C~0x0F */
425 {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
428 /* Index 0x10~0x13 */
429 {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
432 /* Index 0x14~0x17 */
433 {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
436 /* Index 0x18~0x1B */
437 {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
440 /* Index 0x1C~0x1F */
441 {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
444 /* Index 0x20~0x23 */
445 {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
448 /* Index 0x24~0x27 */
449 {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
452 /* Index 0x28~0x2B */
453 {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
456 /* Index 0x2C~0x2F */
457 {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
460 /* Index 0x30~0x33 */
461 {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
464 /* Index 0x34~0x37 */
465 {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
468 /* Index 0x38~0x3B */
469 {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
472 /* Index 0x3C~0x3F */
473 {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
476 /* Index 0x40~0x43 */
477 {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
480 /* Index 0x44~0x47 */
481 {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
484 /* Index 0x48~0x4B */
485 {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
488 /* Index 0x4C~0x4F */
489 {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
492 /* Index 0x50~0x53 */
493 {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
496 /* Index 0x54~0x57 */
497 {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
500 /* Index 0x58~0x5B */
501 {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
504 /* Index 0x5C~0x5F */
505 {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
508 /* Index 0x60~0x63 */
509 {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
512 /* Index 0x64~0x67 */
513 {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
516 /* Index 0x68~0x6B */
517 {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
520 /* Index 0x6C~0x6F */
521 {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
524 /* Index 0x70~0x73 */
525 {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
528 /* Index 0x74~0x77 */
529 {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
532 /* Index 0x78~0x7B */
533 {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
536 /* Index 0x7C~0x7F */
537 {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
540 /* Index 0x80~0x83 */
541 {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
544 /* Index 0x84~0x87 */
545 {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
548 /* Index 0x88~0x8B */
549 {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
552 /* Index 0x8C~0x8F */
553 {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
556 /* Index 0x90~0x93 */
557 {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
560 /* Index 0x94~0x97 */
561 {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
564 /* Index 0x98~0x9B */
565 {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
568 /* Index 0x9C~0x9F */
569 {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
572 /* Index 0xA0~0xA3 */
573 {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
576 /* Index 0xA4~0xA7 */
577 {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
580 /* Index 0xA8~0xAB */
581 {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
584 /* Index 0xAC~0xAF */
585 {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
588 /* Index 0xB0~0xB3 */
589 {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
592 /* Index 0xB4~0xB7 */
593 {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
596 /* Index 0xB8~0xBB */
597 {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
600 /* Index 0xBC~0xBF */
601 {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
604 /* Index 0xC0~0xC3 */
605 {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
608 /* Index 0xC4~0xC7 */
609 {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
612 /* Index 0xC8~0xCB */
613 {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
616 /* Index 0xCC~0xCF */
617 {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
620 /* Index 0xD0~0xD3 */
621 {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
624 /* Index 0xD4~0xD7 */
625 {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
628 /* Index 0xD8~0xDB */
629 {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
632 /* Index 0xDC~0xDF */
633 {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
636 /* Index 0xE0~0xE3 */
637 {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
640 /* Index 0xE4~0xE7 */
641 {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
644 /* Index 0xE8~0xEB */
645 {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
648 /* Index 0xEC~0xEF */
649 {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
652 /* Index 0xF0~0xF3 */
653 {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
656 /* Index 0xF4~0xF7 */
657 {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
660 /* Index 0xF8~0xFB */
661 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
664 /* Index 0xFC~0xFF */
665 {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
670 static struct via_device_mapping device_mapping[] = {
671 {VIA_LDVP0, "LDVP0"},
672 {VIA_LDVP1, "LDVP1"},
676 {VIA_LVDS1, "LVDS1"},
680 static void load_fix_bit_crtc_reg(void);
681 static void __devinit init_gfx_chip_info(int chip_type);
682 static void __devinit init_tmds_chip_info(void);
683 static void __devinit init_lvds_chip_info(void);
684 static void device_screen_off(void);
685 static void device_screen_on(void);
686 static void set_display_channel(void);
687 static void device_off(void);
688 static void device_on(void);
689 static void enable_second_display_channel(void);
690 static void disable_second_display_channel(void);
692 void viafb_lock_crt(void)
694 viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
697 void viafb_unlock_crt(void)
699 viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
700 viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
703 static void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
705 outb(index, LUT_INDEX_WRITE);
711 static u32 get_dvi_devices(int output_interface)
713 switch (output_interface) {
715 return VIA_DVP0 | VIA_LDVP0;
718 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
723 case INTERFACE_DFP_HIGH:
724 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
727 return VIA_LVDS2 | VIA_DVP0;
729 case INTERFACE_DFP_LOW:
730 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
733 return VIA_DVP1 | VIA_LVDS1;
742 static u32 get_lcd_devices(int output_interface)
744 switch (output_interface) {
751 case INTERFACE_DFP_HIGH:
752 return VIA_LVDS2 | VIA_DVP0;
754 case INTERFACE_DFP_LOW:
755 return VIA_LVDS1 | VIA_DVP1;
758 return VIA_LVDS1 | VIA_LVDS2;
760 case INTERFACE_LVDS0:
761 case INTERFACE_LVDS0LVDS1:
764 case INTERFACE_LVDS1:
771 /*Set IGA path for each device*/
772 void viafb_set_iga_path(void)
775 if (viafb_SAMM_ON == 1) {
777 if (viafb_primary_dev == CRT_Device)
778 viaparinfo->crt_setting_info->iga_path = IGA1;
780 viaparinfo->crt_setting_info->iga_path = IGA2;
784 if (viafb_primary_dev == DVI_Device)
785 viaparinfo->tmds_setting_info->iga_path = IGA1;
787 viaparinfo->tmds_setting_info->iga_path = IGA2;
791 if (viafb_primary_dev == LCD_Device) {
793 (viaparinfo->chip_info->gfx_chip_name ==
796 lvds_setting_info->iga_path = IGA2;
798 crt_setting_info->iga_path = IGA1;
800 tmds_setting_info->iga_path = IGA1;
803 lvds_setting_info->iga_path = IGA1;
805 viaparinfo->lvds_setting_info->iga_path = IGA2;
809 if (LCD2_Device == viafb_primary_dev)
810 viaparinfo->lvds_setting_info2->iga_path = IGA1;
812 viaparinfo->lvds_setting_info2->iga_path = IGA2;
817 if (viafb_CRT_ON && viafb_LCD_ON) {
818 viaparinfo->crt_setting_info->iga_path = IGA1;
819 viaparinfo->lvds_setting_info->iga_path = IGA2;
820 } else if (viafb_CRT_ON && viafb_DVI_ON) {
821 viaparinfo->crt_setting_info->iga_path = IGA1;
822 viaparinfo->tmds_setting_info->iga_path = IGA2;
823 } else if (viafb_LCD_ON && viafb_DVI_ON) {
824 viaparinfo->tmds_setting_info->iga_path = IGA1;
825 viaparinfo->lvds_setting_info->iga_path = IGA2;
826 } else if (viafb_LCD_ON && viafb_LCD2_ON) {
827 viaparinfo->lvds_setting_info->iga_path = IGA2;
828 viaparinfo->lvds_setting_info2->iga_path = IGA2;
829 } else if (viafb_CRT_ON) {
830 viaparinfo->crt_setting_info->iga_path = IGA1;
831 } else if (viafb_LCD_ON) {
832 viaparinfo->lvds_setting_info->iga_path = IGA2;
833 } else if (viafb_DVI_ON) {
834 viaparinfo->tmds_setting_info->iga_path = IGA1;
838 viaparinfo->shared->iga1_devices = 0;
839 viaparinfo->shared->iga2_devices = 0;
841 if (viaparinfo->crt_setting_info->iga_path == IGA1)
842 viaparinfo->shared->iga1_devices |= VIA_CRT;
844 viaparinfo->shared->iga2_devices |= VIA_CRT;
848 if (viaparinfo->tmds_setting_info->iga_path == IGA1)
849 viaparinfo->shared->iga1_devices |= get_dvi_devices(
850 viaparinfo->chip_info->
851 tmds_chip_info.output_interface);
853 viaparinfo->shared->iga2_devices |= get_dvi_devices(
854 viaparinfo->chip_info->
855 tmds_chip_info.output_interface);
859 if (viaparinfo->lvds_setting_info->iga_path == IGA1)
860 viaparinfo->shared->iga1_devices |= get_lcd_devices(
861 viaparinfo->chip_info->
862 lvds_chip_info.output_interface);
864 viaparinfo->shared->iga2_devices |= get_lcd_devices(
865 viaparinfo->chip_info->
866 lvds_chip_info.output_interface);
870 if (viaparinfo->lvds_setting_info2->iga_path == IGA1)
871 viaparinfo->shared->iga1_devices |= get_lcd_devices(
872 viaparinfo->chip_info->
873 lvds_chip_info2.output_interface);
875 viaparinfo->shared->iga2_devices |= get_lcd_devices(
876 viaparinfo->chip_info->
877 lvds_chip_info2.output_interface);
880 /* looks like the OLPC has its display wired to DVP1 and LVDS2 */
881 if (machine_is_olpc())
882 viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;
885 static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
887 outb(0xFF, 0x3C6); /* bit mask of palette */
894 void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue)
896 viafb_write_reg_mask(0x1A, VIASR, 0x00, 0x01);
897 set_color_register(index, red, green, blue);
900 void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue)
902 viafb_write_reg_mask(0x1A, VIASR, 0x01, 0x01);
903 set_color_register(index, red, green, blue);
906 static void set_source_common(u8 index, u8 offset, u8 iga)
908 u8 value, mask = 1 << offset;
918 printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
922 via_write_reg_mask(VIACR, index, value, mask);
925 static void set_crt_source(u8 iga)
937 printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga);
941 via_write_reg_mask(VIASR, 0x16, value, 0x40);
944 static inline void set_ldvp0_source(u8 iga)
946 set_source_common(0x6C, 7, iga);
949 static inline void set_ldvp1_source(u8 iga)
951 set_source_common(0x93, 7, iga);
954 static inline void set_dvp0_source(u8 iga)
956 set_source_common(0x96, 4, iga);
959 static inline void set_dvp1_source(u8 iga)
961 set_source_common(0x9B, 4, iga);
964 static inline void set_lvds1_source(u8 iga)
966 set_source_common(0x99, 4, iga);
969 static inline void set_lvds2_source(u8 iga)
971 set_source_common(0x97, 4, iga);
974 void via_set_source(u32 devices, u8 iga)
976 if (devices & VIA_LDVP0)
977 set_ldvp0_source(iga);
978 if (devices & VIA_LDVP1)
979 set_ldvp1_source(iga);
980 if (devices & VIA_DVP0)
981 set_dvp0_source(iga);
982 if (devices & VIA_CRT)
984 if (devices & VIA_DVP1)
985 set_dvp1_source(iga);
986 if (devices & VIA_LVDS1)
987 set_lvds1_source(iga);
988 if (devices & VIA_LVDS2)
989 set_lvds2_source(iga);
992 static void set_crt_state(u8 state)
1000 case VIA_STATE_STANDBY:
1003 case VIA_STATE_SUSPEND:
1013 via_write_reg_mask(VIACR, 0x36, value, 0x30);
1016 static void set_dvp0_state(u8 state)
1031 via_write_reg_mask(VIASR, 0x1E, value, 0xC0);
1034 static void set_dvp1_state(u8 state)
1049 via_write_reg_mask(VIASR, 0x1E, value, 0x30);
1052 static void set_lvds1_state(u8 state)
1067 via_write_reg_mask(VIASR, 0x2A, value, 0x03);
1070 static void set_lvds2_state(u8 state)
1085 via_write_reg_mask(VIASR, 0x2A, value, 0x0C);
1088 void via_set_state(u32 devices, u8 state)
1091 TODO: Can we enable/disable these devices? How?
1092 if (devices & VIA_LDVP0)
1093 if (devices & VIA_LDVP1)
1095 if (devices & VIA_DVP0)
1096 set_dvp0_state(state);
1097 if (devices & VIA_CRT)
1098 set_crt_state(state);
1099 if (devices & VIA_DVP1)
1100 set_dvp1_state(state);
1101 if (devices & VIA_LVDS1)
1102 set_lvds1_state(state);
1103 if (devices & VIA_LVDS2)
1104 set_lvds2_state(state);
1107 void via_set_sync_polarity(u32 devices, u8 polarity)
1109 if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) {
1110 printk(KERN_WARNING "viafb: Unsupported polarity: %d\n",
1115 if (devices & VIA_CRT)
1116 via_write_misc_reg_mask(polarity << 6, 0xC0);
1117 if (devices & VIA_DVP1)
1118 via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60);
1119 if (devices & VIA_LVDS1)
1120 via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60);
1121 if (devices & VIA_LVDS2)
1122 via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60);
1125 u32 via_parse_odev(char *input, char **end)
1134 for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
1135 len = strlen(device_mapping[i].name);
1136 if (!strncmp(ptr, device_mapping[i].name, len)) {
1137 odev |= device_mapping[i].device;
1151 void via_odev_to_seq(struct seq_file *m, u32 odev)
1155 for (i = 0; i < ARRAY_SIZE(device_mapping); i++) {
1156 if (odev & device_mapping[i].device) {
1160 seq_puts(m, device_mapping[i].name);
1168 static void load_fix_bit_crtc_reg(void)
1170 /* always set to 1 */
1171 viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
1172 /* line compare should set all bits = 1 (extend modes) */
1173 viafb_write_reg(CR18, VIACR, 0xff);
1174 /* line compare should set all bits = 1 (extend modes) */
1175 viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
1176 /* line compare should set all bits = 1 (extend modes) */
1177 viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
1178 /* line compare should set all bits = 1 (extend modes) */
1179 viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
1180 /* line compare should set all bits = 1 (extend modes) */
1181 viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
1182 /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
1183 /* extend mode always set to e3h */
1184 viafb_write_reg(CR17, VIACR, 0xe3);
1185 /* extend mode always set to 0h */
1186 viafb_write_reg(CR08, VIACR, 0x00);
1187 /* extend mode always set to 0h */
1188 viafb_write_reg(CR14, VIACR, 0x00);
1190 /* If K8M800, enable Prefetch Mode. */
1191 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
1192 || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
1193 viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
1194 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
1195 && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
1196 viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
1200 void viafb_load_reg(int timing_value, int viafb_load_reg_num,
1201 struct io_register *reg,
1209 int start_index, end_index, cr_index;
1212 for (i = 0; i < viafb_load_reg_num; i++) {
1215 start_index = reg[i].start_bit;
1216 end_index = reg[i].end_bit;
1217 cr_index = reg[i].io_addr;
1219 shift_next_reg = bit_num;
1220 for (j = start_index; j <= end_index; j++) {
1221 /*if (bit_num==8) timing_value = timing_value >>8; */
1222 reg_mask = reg_mask | (BIT0 << j);
1223 get_bit = (timing_value & (BIT0 << bit_num));
1225 data | ((get_bit >> shift_next_reg) << start_index);
1228 if (io_type == VIACR)
1229 viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
1231 viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
1236 /* Write Registers */
1237 void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1241 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1243 for (i = 0; i < ItemNum; i++)
1244 via_write_reg_mask(RegTable[i].port, RegTable[i].index,
1245 RegTable[i].value, RegTable[i].mask);
1248 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
1251 int viafb_load_reg_num;
1252 struct io_register *reg = NULL;
1256 reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1257 viafb_load_reg_num = fetch_count_reg.
1258 iga1_fetch_count_reg.reg_num;
1259 reg = fetch_count_reg.iga1_fetch_count_reg.reg;
1260 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1263 reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
1264 viafb_load_reg_num = fetch_count_reg.
1265 iga2_fetch_count_reg.reg_num;
1266 reg = fetch_count_reg.iga2_fetch_count_reg.reg;
1267 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1273 void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
1276 int viafb_load_reg_num;
1277 struct io_register *reg = NULL;
1278 int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
1279 0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
1280 int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
1281 0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
1283 if (set_iga == IGA1) {
1284 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1285 iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
1286 iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
1287 iga1_fifo_high_threshold =
1288 K800_IGA1_FIFO_HIGH_THRESHOLD;
1289 /* If resolution > 1280x1024, expire length = 64, else
1290 expire length = 128 */
1291 if ((hor_active > 1280) && (ver_active > 1024))
1292 iga1_display_queue_expire_num = 16;
1294 iga1_display_queue_expire_num =
1295 K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1299 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1300 iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
1301 iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
1302 iga1_fifo_high_threshold =
1303 P880_IGA1_FIFO_HIGH_THRESHOLD;
1304 iga1_display_queue_expire_num =
1305 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1307 /* If resolution > 1280x1024, expire length = 64, else
1308 expire length = 128 */
1309 if ((hor_active > 1280) && (ver_active > 1024))
1310 iga1_display_queue_expire_num = 16;
1312 iga1_display_queue_expire_num =
1313 P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1316 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1317 iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
1318 iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
1319 iga1_fifo_high_threshold =
1320 CN700_IGA1_FIFO_HIGH_THRESHOLD;
1322 /* If resolution > 1280x1024, expire length = 64,
1323 else expire length = 128 */
1324 if ((hor_active > 1280) && (ver_active > 1024))
1325 iga1_display_queue_expire_num = 16;
1327 iga1_display_queue_expire_num =
1328 CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1331 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1332 iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
1333 iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
1334 iga1_fifo_high_threshold =
1335 CX700_IGA1_FIFO_HIGH_THRESHOLD;
1336 iga1_display_queue_expire_num =
1337 CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1340 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1341 iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
1342 iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
1343 iga1_fifo_high_threshold =
1344 K8M890_IGA1_FIFO_HIGH_THRESHOLD;
1345 iga1_display_queue_expire_num =
1346 K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1349 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1350 iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
1351 iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
1352 iga1_fifo_high_threshold =
1353 P4M890_IGA1_FIFO_HIGH_THRESHOLD;
1354 iga1_display_queue_expire_num =
1355 P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1358 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1359 iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
1360 iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
1361 iga1_fifo_high_threshold =
1362 P4M900_IGA1_FIFO_HIGH_THRESHOLD;
1363 iga1_display_queue_expire_num =
1364 P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1367 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1368 iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
1369 iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
1370 iga1_fifo_high_threshold =
1371 VX800_IGA1_FIFO_HIGH_THRESHOLD;
1372 iga1_display_queue_expire_num =
1373 VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1376 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1377 iga1_fifo_max_depth = VX855_IGA1_FIFO_MAX_DEPTH;
1378 iga1_fifo_threshold = VX855_IGA1_FIFO_THRESHOLD;
1379 iga1_fifo_high_threshold =
1380 VX855_IGA1_FIFO_HIGH_THRESHOLD;
1381 iga1_display_queue_expire_num =
1382 VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1385 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1386 iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH;
1387 iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD;
1388 iga1_fifo_high_threshold =
1389 VX900_IGA1_FIFO_HIGH_THRESHOLD;
1390 iga1_display_queue_expire_num =
1391 VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
1394 /* Set Display FIFO Depath Select */
1395 reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
1396 viafb_load_reg_num =
1397 display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
1398 reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
1399 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1401 /* Set Display FIFO Threshold Select */
1402 reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
1403 viafb_load_reg_num =
1404 fifo_threshold_select_reg.
1405 iga1_fifo_threshold_select_reg.reg_num;
1407 fifo_threshold_select_reg.
1408 iga1_fifo_threshold_select_reg.reg;
1409 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1411 /* Set FIFO High Threshold Select */
1413 IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
1414 viafb_load_reg_num =
1415 fifo_high_threshold_select_reg.
1416 iga1_fifo_high_threshold_select_reg.reg_num;
1418 fifo_high_threshold_select_reg.
1419 iga1_fifo_high_threshold_select_reg.reg;
1420 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1422 /* Set Display Queue Expire Num */
1424 IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1425 (iga1_display_queue_expire_num);
1426 viafb_load_reg_num =
1427 display_queue_expire_num_reg.
1428 iga1_display_queue_expire_num_reg.reg_num;
1430 display_queue_expire_num_reg.
1431 iga1_display_queue_expire_num_reg.reg;
1432 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
1435 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1436 iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
1437 iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
1438 iga2_fifo_high_threshold =
1439 K800_IGA2_FIFO_HIGH_THRESHOLD;
1441 /* If resolution > 1280x1024, expire length = 64,
1442 else expire length = 128 */
1443 if ((hor_active > 1280) && (ver_active > 1024))
1444 iga2_display_queue_expire_num = 16;
1446 iga2_display_queue_expire_num =
1447 K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1450 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
1451 iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
1452 iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
1453 iga2_fifo_high_threshold =
1454 P880_IGA2_FIFO_HIGH_THRESHOLD;
1456 /* If resolution > 1280x1024, expire length = 64,
1457 else expire length = 128 */
1458 if ((hor_active > 1280) && (ver_active > 1024))
1459 iga2_display_queue_expire_num = 16;
1461 iga2_display_queue_expire_num =
1462 P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1465 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
1466 iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
1467 iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
1468 iga2_fifo_high_threshold =
1469 CN700_IGA2_FIFO_HIGH_THRESHOLD;
1471 /* If resolution > 1280x1024, expire length = 64,
1472 else expire length = 128 */
1473 if ((hor_active > 1280) && (ver_active > 1024))
1474 iga2_display_queue_expire_num = 16;
1476 iga2_display_queue_expire_num =
1477 CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1480 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
1481 iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
1482 iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
1483 iga2_fifo_high_threshold =
1484 CX700_IGA2_FIFO_HIGH_THRESHOLD;
1485 iga2_display_queue_expire_num =
1486 CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1489 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
1490 iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
1491 iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
1492 iga2_fifo_high_threshold =
1493 K8M890_IGA2_FIFO_HIGH_THRESHOLD;
1494 iga2_display_queue_expire_num =
1495 K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1498 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
1499 iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
1500 iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
1501 iga2_fifo_high_threshold =
1502 P4M890_IGA2_FIFO_HIGH_THRESHOLD;
1503 iga2_display_queue_expire_num =
1504 P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1507 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
1508 iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
1509 iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
1510 iga2_fifo_high_threshold =
1511 P4M900_IGA2_FIFO_HIGH_THRESHOLD;
1512 iga2_display_queue_expire_num =
1513 P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1516 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
1517 iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
1518 iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
1519 iga2_fifo_high_threshold =
1520 VX800_IGA2_FIFO_HIGH_THRESHOLD;
1521 iga2_display_queue_expire_num =
1522 VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1525 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX855) {
1526 iga2_fifo_max_depth = VX855_IGA2_FIFO_MAX_DEPTH;
1527 iga2_fifo_threshold = VX855_IGA2_FIFO_THRESHOLD;
1528 iga2_fifo_high_threshold =
1529 VX855_IGA2_FIFO_HIGH_THRESHOLD;
1530 iga2_display_queue_expire_num =
1531 VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1534 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) {
1535 iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH;
1536 iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD;
1537 iga2_fifo_high_threshold =
1538 VX900_IGA2_FIFO_HIGH_THRESHOLD;
1539 iga2_display_queue_expire_num =
1540 VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
1543 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
1544 /* Set Display FIFO Depath Select */
1546 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
1548 /* Patch LCD in IGA2 case */
1549 viafb_load_reg_num =
1550 display_fifo_depth_reg.
1551 iga2_fifo_depth_select_reg.reg_num;
1553 display_fifo_depth_reg.
1554 iga2_fifo_depth_select_reg.reg;
1555 viafb_load_reg(reg_value,
1556 viafb_load_reg_num, reg, VIACR);
1559 /* Set Display FIFO Depath Select */
1561 IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
1562 viafb_load_reg_num =
1563 display_fifo_depth_reg.
1564 iga2_fifo_depth_select_reg.reg_num;
1566 display_fifo_depth_reg.
1567 iga2_fifo_depth_select_reg.reg;
1568 viafb_load_reg(reg_value,
1569 viafb_load_reg_num, reg, VIACR);
1572 /* Set Display FIFO Threshold Select */
1573 reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
1574 viafb_load_reg_num =
1575 fifo_threshold_select_reg.
1576 iga2_fifo_threshold_select_reg.reg_num;
1578 fifo_threshold_select_reg.
1579 iga2_fifo_threshold_select_reg.reg;
1580 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1582 /* Set FIFO High Threshold Select */
1584 IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
1585 viafb_load_reg_num =
1586 fifo_high_threshold_select_reg.
1587 iga2_fifo_high_threshold_select_reg.reg_num;
1589 fifo_high_threshold_select_reg.
1590 iga2_fifo_high_threshold_select_reg.reg;
1591 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1593 /* Set Display Queue Expire Num */
1595 IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
1596 (iga2_display_queue_expire_num);
1597 viafb_load_reg_num =
1598 display_queue_expire_num_reg.
1599 iga2_display_queue_expire_num_reg.reg_num;
1601 display_queue_expire_num_reg.
1602 iga2_display_queue_expire_num_reg.reg;
1603 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1609 static u32 cle266_encode_pll(struct pll_config pll)
1611 return (pll.multiplier << 8)
1616 static u32 k800_encode_pll(struct pll_config pll)
1618 return ((pll.divisor - 2) << 16)
1619 | (pll.rshift << 10)
1620 | (pll.multiplier - 2);
1623 static u32 vx855_encode_pll(struct pll_config pll)
1625 return (pll.divisor << 16)
1626 | (pll.rshift << 10)
1630 static inline u32 get_pll_internal_frequency(u32 ref_freq,
1631 struct pll_config pll)
1633 return ref_freq / pll.divisor * pll.multiplier;
1636 static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll)
1638 return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift;
1641 static struct pll_config get_pll_config(struct pll_config *config, int size,
1644 struct pll_config best = config[0];
1645 const u32 f0 = 14318180; /* X1 frequency */
1648 for (i = 1; i < size; i++) {
1649 if (abs(get_pll_output_frequency(f0, config[i]) - clk)
1650 < abs(get_pll_output_frequency(f0, best) - clk))
1657 u32 viafb_get_clk_value(int clk)
1661 switch (viaparinfo->chip_info->gfx_chip_name) {
1662 case UNICHROME_CLE266:
1663 case UNICHROME_K400:
1664 value = cle266_encode_pll(get_pll_config(cle266_pll_config,
1665 ARRAY_SIZE(cle266_pll_config), clk));
1667 case UNICHROME_K800:
1668 case UNICHROME_PM800:
1669 case UNICHROME_CN700:
1670 value = k800_encode_pll(get_pll_config(k800_pll_config,
1671 ARRAY_SIZE(k800_pll_config), clk));
1673 case UNICHROME_CX700:
1674 case UNICHROME_CN750:
1675 case UNICHROME_K8M890:
1676 case UNICHROME_P4M890:
1677 case UNICHROME_P4M900:
1678 case UNICHROME_VX800:
1679 value = k800_encode_pll(get_pll_config(cx700_pll_config,
1680 ARRAY_SIZE(cx700_pll_config), clk));
1682 case UNICHROME_VX855:
1683 case UNICHROME_VX900:
1684 value = vx855_encode_pll(get_pll_config(vx855_pll_config,
1685 ARRAY_SIZE(vx855_pll_config), clk));
1693 void viafb_set_vclock(u32 clk, int set_iga)
1695 /* H.W. Reset : ON */
1696 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1698 if (set_iga == IGA1) {
1699 /* Change D,N FOR VCLK */
1700 switch (viaparinfo->chip_info->gfx_chip_name) {
1701 case UNICHROME_CLE266:
1702 case UNICHROME_K400:
1703 via_write_reg(VIASR, SR46, (clk & 0x00FF));
1704 via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1707 case UNICHROME_K800:
1708 case UNICHROME_PM800:
1709 case UNICHROME_CN700:
1710 case UNICHROME_CX700:
1711 case UNICHROME_CN750:
1712 case UNICHROME_K8M890:
1713 case UNICHROME_P4M890:
1714 case UNICHROME_P4M900:
1715 case UNICHROME_VX800:
1716 case UNICHROME_VX855:
1717 case UNICHROME_VX900:
1718 via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1719 via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1720 via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1725 if (set_iga == IGA2) {
1726 /* Change D,N FOR LCK */
1727 switch (viaparinfo->chip_info->gfx_chip_name) {
1728 case UNICHROME_CLE266:
1729 case UNICHROME_K400:
1730 via_write_reg(VIASR, SR44, (clk & 0x00FF));
1731 via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1734 case UNICHROME_K800:
1735 case UNICHROME_PM800:
1736 case UNICHROME_CN700:
1737 case UNICHROME_CX700:
1738 case UNICHROME_CN750:
1739 case UNICHROME_K8M890:
1740 case UNICHROME_P4M890:
1741 case UNICHROME_P4M900:
1742 case UNICHROME_VX800:
1743 case UNICHROME_VX855:
1744 case UNICHROME_VX900:
1745 via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1746 via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1747 via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1752 /* H.W. Reset : OFF */
1753 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1756 if (set_iga == IGA1) {
1757 viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1758 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1761 if (set_iga == IGA2) {
1762 viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
1763 viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
1767 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
1770 void viafb_load_crtc_timing(struct display_timing device_timing,
1774 int viafb_load_reg_num = 0;
1776 struct io_register *reg = NULL;
1780 for (i = 0; i < 12; i++) {
1781 if (set_iga == IGA1) {
1785 IGA1_HOR_TOTAL_FORMULA(device_timing.
1787 viafb_load_reg_num =
1788 iga1_crtc_reg.hor_total.reg_num;
1789 reg = iga1_crtc_reg.hor_total.reg;
1793 IGA1_HOR_ADDR_FORMULA(device_timing.
1795 viafb_load_reg_num =
1796 iga1_crtc_reg.hor_addr.reg_num;
1797 reg = iga1_crtc_reg.hor_addr.reg;
1799 case H_BLANK_START_INDEX:
1801 IGA1_HOR_BLANK_START_FORMULA
1802 (device_timing.hor_blank_start);
1803 viafb_load_reg_num =
1804 iga1_crtc_reg.hor_blank_start.reg_num;
1805 reg = iga1_crtc_reg.hor_blank_start.reg;
1807 case H_BLANK_END_INDEX:
1809 IGA1_HOR_BLANK_END_FORMULA
1810 (device_timing.hor_blank_start,
1811 device_timing.hor_blank_end);
1812 viafb_load_reg_num =
1813 iga1_crtc_reg.hor_blank_end.reg_num;
1814 reg = iga1_crtc_reg.hor_blank_end.reg;
1816 case H_SYNC_START_INDEX:
1818 IGA1_HOR_SYNC_START_FORMULA
1819 (device_timing.hor_sync_start);
1820 viafb_load_reg_num =
1821 iga1_crtc_reg.hor_sync_start.reg_num;
1822 reg = iga1_crtc_reg.hor_sync_start.reg;
1824 case H_SYNC_END_INDEX:
1826 IGA1_HOR_SYNC_END_FORMULA
1827 (device_timing.hor_sync_start,
1828 device_timing.hor_sync_end);
1829 viafb_load_reg_num =
1830 iga1_crtc_reg.hor_sync_end.reg_num;
1831 reg = iga1_crtc_reg.hor_sync_end.reg;
1835 IGA1_VER_TOTAL_FORMULA(device_timing.
1837 viafb_load_reg_num =
1838 iga1_crtc_reg.ver_total.reg_num;
1839 reg = iga1_crtc_reg.ver_total.reg;
1843 IGA1_VER_ADDR_FORMULA(device_timing.
1845 viafb_load_reg_num =
1846 iga1_crtc_reg.ver_addr.reg_num;
1847 reg = iga1_crtc_reg.ver_addr.reg;
1849 case V_BLANK_START_INDEX:
1851 IGA1_VER_BLANK_START_FORMULA
1852 (device_timing.ver_blank_start);
1853 viafb_load_reg_num =
1854 iga1_crtc_reg.ver_blank_start.reg_num;
1855 reg = iga1_crtc_reg.ver_blank_start.reg;
1857 case V_BLANK_END_INDEX:
1859 IGA1_VER_BLANK_END_FORMULA
1860 (device_timing.ver_blank_start,
1861 device_timing.ver_blank_end);
1862 viafb_load_reg_num =
1863 iga1_crtc_reg.ver_blank_end.reg_num;
1864 reg = iga1_crtc_reg.ver_blank_end.reg;
1866 case V_SYNC_START_INDEX:
1868 IGA1_VER_SYNC_START_FORMULA
1869 (device_timing.ver_sync_start);
1870 viafb_load_reg_num =
1871 iga1_crtc_reg.ver_sync_start.reg_num;
1872 reg = iga1_crtc_reg.ver_sync_start.reg;
1874 case V_SYNC_END_INDEX:
1876 IGA1_VER_SYNC_END_FORMULA
1877 (device_timing.ver_sync_start,
1878 device_timing.ver_sync_end);
1879 viafb_load_reg_num =
1880 iga1_crtc_reg.ver_sync_end.reg_num;
1881 reg = iga1_crtc_reg.ver_sync_end.reg;
1887 if (set_iga == IGA2) {
1891 IGA2_HOR_TOTAL_FORMULA(device_timing.
1893 viafb_load_reg_num =
1894 iga2_crtc_reg.hor_total.reg_num;
1895 reg = iga2_crtc_reg.hor_total.reg;
1899 IGA2_HOR_ADDR_FORMULA(device_timing.
1901 viafb_load_reg_num =
1902 iga2_crtc_reg.hor_addr.reg_num;
1903 reg = iga2_crtc_reg.hor_addr.reg;
1905 case H_BLANK_START_INDEX:
1907 IGA2_HOR_BLANK_START_FORMULA
1908 (device_timing.hor_blank_start);
1909 viafb_load_reg_num =
1910 iga2_crtc_reg.hor_blank_start.reg_num;
1911 reg = iga2_crtc_reg.hor_blank_start.reg;
1913 case H_BLANK_END_INDEX:
1915 IGA2_HOR_BLANK_END_FORMULA
1916 (device_timing.hor_blank_start,
1917 device_timing.hor_blank_end);
1918 viafb_load_reg_num =
1919 iga2_crtc_reg.hor_blank_end.reg_num;
1920 reg = iga2_crtc_reg.hor_blank_end.reg;
1922 case H_SYNC_START_INDEX:
1924 IGA2_HOR_SYNC_START_FORMULA
1925 (device_timing.hor_sync_start);
1926 if (UNICHROME_CN700 <=
1927 viaparinfo->chip_info->gfx_chip_name)
1928 viafb_load_reg_num =
1929 iga2_crtc_reg.hor_sync_start.
1932 viafb_load_reg_num = 3;
1933 reg = iga2_crtc_reg.hor_sync_start.reg;
1935 case H_SYNC_END_INDEX:
1937 IGA2_HOR_SYNC_END_FORMULA
1938 (device_timing.hor_sync_start,
1939 device_timing.hor_sync_end);
1940 viafb_load_reg_num =
1941 iga2_crtc_reg.hor_sync_end.reg_num;
1942 reg = iga2_crtc_reg.hor_sync_end.reg;
1946 IGA2_VER_TOTAL_FORMULA(device_timing.
1948 viafb_load_reg_num =
1949 iga2_crtc_reg.ver_total.reg_num;
1950 reg = iga2_crtc_reg.ver_total.reg;
1954 IGA2_VER_ADDR_FORMULA(device_timing.
1956 viafb_load_reg_num =
1957 iga2_crtc_reg.ver_addr.reg_num;
1958 reg = iga2_crtc_reg.ver_addr.reg;
1960 case V_BLANK_START_INDEX:
1962 IGA2_VER_BLANK_START_FORMULA
1963 (device_timing.ver_blank_start);
1964 viafb_load_reg_num =
1965 iga2_crtc_reg.ver_blank_start.reg_num;
1966 reg = iga2_crtc_reg.ver_blank_start.reg;
1968 case V_BLANK_END_INDEX:
1970 IGA2_VER_BLANK_END_FORMULA
1971 (device_timing.ver_blank_start,
1972 device_timing.ver_blank_end);
1973 viafb_load_reg_num =
1974 iga2_crtc_reg.ver_blank_end.reg_num;
1975 reg = iga2_crtc_reg.ver_blank_end.reg;
1977 case V_SYNC_START_INDEX:
1979 IGA2_VER_SYNC_START_FORMULA
1980 (device_timing.ver_sync_start);
1981 viafb_load_reg_num =
1982 iga2_crtc_reg.ver_sync_start.reg_num;
1983 reg = iga2_crtc_reg.ver_sync_start.reg;
1985 case V_SYNC_END_INDEX:
1987 IGA2_VER_SYNC_END_FORMULA
1988 (device_timing.ver_sync_start,
1989 device_timing.ver_sync_end);
1990 viafb_load_reg_num =
1991 iga2_crtc_reg.ver_sync_end.reg_num;
1992 reg = iga2_crtc_reg.ver_sync_end.reg;
1997 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
2003 void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
2004 struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
2006 struct display_timing crt_reg;
2010 u32 pll_D_N, clock, refresh = viafb_refresh;
2012 if (viafb_SAMM_ON && set_iga == IGA2)
2013 refresh = viafb_refresh1;
2015 for (i = 0; i < video_mode->mode_array; i++) {
2018 if (crt_table[i].refresh_rate == refresh)
2022 crt_reg = crt_table[index].crtc;
2024 /* Mode 640x480 has border, but LCD/DFP didn't have border. */
2025 /* So we would delete border. */
2026 if ((viafb_LCD_ON | viafb_DVI_ON)
2027 && video_mode->crtc[0].crtc.hor_addr == 640
2028 && video_mode->crtc[0].crtc.ver_addr == 480
2030 /* The border is 8 pixels. */
2031 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
2033 /* Blanking time should add left and right borders. */
2034 crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
2037 h_addr = crt_reg.hor_addr;
2038 v_addr = crt_reg.ver_addr;
2039 if (set_iga == IGA1) {
2041 viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
2042 viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
2043 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
2048 viafb_load_crtc_timing(crt_reg, IGA1);
2051 viafb_load_crtc_timing(crt_reg, IGA2);
2055 load_fix_bit_crtc_reg();
2057 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
2058 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
2061 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
2062 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
2063 viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
2065 clock = crt_reg.hor_total * crt_reg.ver_total
2066 * crt_table[index].refresh_rate;
2067 pll_D_N = viafb_get_clk_value(clock);
2068 DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
2069 viafb_set_vclock(pll_D_N, set_iga);
2073 void __devinit viafb_init_chip_info(int chip_type)
2075 init_gfx_chip_info(chip_type);
2076 init_tmds_chip_info();
2077 init_lvds_chip_info();
2079 viaparinfo->crt_setting_info->iga_path = IGA1;
2081 /*Set IGA path for each device */
2082 viafb_set_iga_path();
2084 viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
2085 viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
2086 viaparinfo->lvds_setting_info2->display_method =
2087 viaparinfo->lvds_setting_info->display_method;
2088 viaparinfo->lvds_setting_info2->lcd_mode =
2089 viaparinfo->lvds_setting_info->lcd_mode;
2092 void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
2095 viaparinfo->tmds_setting_info->h_active = hres;
2096 viaparinfo->tmds_setting_info->v_active = vres;
2098 viaparinfo->lvds_setting_info->h_active = hres;
2099 viaparinfo->lvds_setting_info->v_active = vres;
2100 viaparinfo->lvds_setting_info->bpp = bpp;
2101 viaparinfo->lvds_setting_info2->h_active = hres;
2102 viaparinfo->lvds_setting_info2->v_active = vres;
2103 viaparinfo->lvds_setting_info2->bpp = bpp;
2106 if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
2107 viaparinfo->tmds_setting_info->h_active = hres;
2108 viaparinfo->tmds_setting_info->v_active = vres;
2111 if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
2112 viaparinfo->lvds_setting_info->h_active = hres;
2113 viaparinfo->lvds_setting_info->v_active = vres;
2114 viaparinfo->lvds_setting_info->bpp = bpp;
2116 if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
2117 viaparinfo->lvds_setting_info2->h_active = hres;
2118 viaparinfo->lvds_setting_info2->v_active = vres;
2119 viaparinfo->lvds_setting_info2->bpp = bpp;
2124 static void __devinit init_gfx_chip_info(int chip_type)
2128 viaparinfo->chip_info->gfx_chip_name = chip_type;
2130 /* Check revision of CLE266 Chip */
2131 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
2132 /* CR4F only define in CLE266.CX chip */
2133 tmp = viafb_read_reg(VIACR, CR4F);
2134 viafb_write_reg(CR4F, VIACR, 0x55);
2135 if (viafb_read_reg(VIACR, CR4F) != 0x55)
2136 viaparinfo->chip_info->gfx_chip_revision =
2139 viaparinfo->chip_info->gfx_chip_revision =
2141 /* restore orignal CR4F value */
2142 viafb_write_reg(CR4F, VIACR, tmp);
2145 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
2146 tmp = viafb_read_reg(VIASR, SR43);
2147 DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
2149 viaparinfo->chip_info->gfx_chip_revision =
2150 CX700_REVISION_700M2;
2151 } else if (tmp & 0x40) {
2152 viaparinfo->chip_info->gfx_chip_revision =
2153 CX700_REVISION_700M;
2155 viaparinfo->chip_info->gfx_chip_revision =
2160 /* Determine which 2D engine we have */
2161 switch (viaparinfo->chip_info->gfx_chip_name) {
2162 case UNICHROME_VX800:
2163 case UNICHROME_VX855:
2164 case UNICHROME_VX900:
2165 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
2167 case UNICHROME_K8M890:
2168 case UNICHROME_P4M900:
2169 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
2172 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
2177 static void __devinit init_tmds_chip_info(void)
2179 viafb_tmds_trasmitter_identify();
2181 if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
2183 switch (viaparinfo->chip_info->gfx_chip_name) {
2184 case UNICHROME_CX700:
2186 /* we should check support by hardware layout.*/
2187 if ((viafb_display_hardware_layout ==
2189 || (viafb_display_hardware_layout ==
2190 HW_LAYOUT_LCD_DVI)) {
2191 viaparinfo->chip_info->tmds_chip_info.
2192 output_interface = INTERFACE_TMDS;
2194 viaparinfo->chip_info->tmds_chip_info.
2200 case UNICHROME_K8M890:
2201 case UNICHROME_P4M900:
2202 case UNICHROME_P4M890:
2203 /* TMDS on PCIE, we set DFPLOW as default. */
2204 viaparinfo->chip_info->tmds_chip_info.output_interface =
2209 /* set DVP1 default for DVI */
2210 viaparinfo->chip_info->tmds_chip_info
2211 .output_interface = INTERFACE_DVP1;
2216 DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
2217 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
2218 viafb_init_dvi_size(&viaparinfo->shared->chip_info.tmds_chip_info,
2219 &viaparinfo->shared->tmds_setting_info);
2222 static void __devinit init_lvds_chip_info(void)
2224 viafb_lvds_trasmitter_identify();
2225 viafb_init_lcd_size();
2226 viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
2227 viaparinfo->lvds_setting_info);
2228 if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
2229 viafb_init_lvds_output_interface(&viaparinfo->chip_info->
2230 lvds_chip_info2, viaparinfo->lvds_setting_info2);
2232 /*If CX700,two singel LCD, we need to reassign
2233 LCD interface to different LVDS port */
2234 if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
2235 && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
2236 if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
2237 lvds_chip_name) && (INTEGRATED_LVDS ==
2238 viaparinfo->chip_info->
2239 lvds_chip_info2.lvds_chip_name)) {
2240 viaparinfo->chip_info->lvds_chip_info.output_interface =
2242 viaparinfo->chip_info->lvds_chip_info2.
2248 DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
2249 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
2250 DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
2251 viaparinfo->chip_info->lvds_chip_info.output_interface);
2252 DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
2253 viaparinfo->chip_info->lvds_chip_info.output_interface);
2256 void __devinit viafb_init_dac(int set_iga)
2261 if (set_iga == IGA1) {
2262 /* access Primary Display's LUT */
2263 viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2265 viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
2266 for (i = 0; i < 256; i++) {
2267 write_dac_reg(i, palLUT_table[i].red,
2268 palLUT_table[i].green,
2269 palLUT_table[i].blue);
2272 viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
2274 tmp = viafb_read_reg(VIACR, CR6A);
2275 /* access Secondary Display's LUT */
2276 viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
2277 viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
2278 for (i = 0; i < 256; i++) {
2279 write_dac_reg(i, palLUT_table[i].red,
2280 palLUT_table[i].green,
2281 palLUT_table[i].blue);
2283 /* set IGA1 DAC for default */
2284 viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
2285 viafb_write_reg(CR6A, VIACR, tmp);
2289 static void device_screen_off(void)
2291 /* turn off CRT screen (IGA1) */
2292 viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
2295 static void device_screen_on(void)
2297 /* turn on CRT screen (IGA1) */
2298 viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
2301 static void set_display_channel(void)
2303 /*If viafb_LCD2_ON, on cx700, internal lvds's information
2304 is keeped on lvds_setting_info2 */
2305 if (viafb_LCD2_ON &&
2306 viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
2307 /* For dual channel LCD: */
2308 /* Set to Dual LVDS channel. */
2309 viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2310 } else if (viafb_LCD_ON && viafb_DVI_ON) {
2312 /* Set to LVDS1 + TMDS channel. */
2313 viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
2314 } else if (viafb_DVI_ON) {
2315 /* Set to single TMDS channel. */
2316 viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
2317 } else if (viafb_LCD_ON) {
2318 if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
2319 /* For dual channel LCD: */
2320 /* Set to Dual LVDS channel. */
2321 viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
2323 /* Set to LVDS0 + LVDS1 channel. */
2324 viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
2329 static u8 get_sync(struct fb_info *info)
2333 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
2334 polarity |= VIA_HSYNC_NEGATIVE;
2335 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
2336 polarity |= VIA_VSYNC_NEGATIVE;
2340 int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2341 struct VideoModeTable *vmode_tbl1, int video_bpp1)
2345 u32 devices = viaparinfo->shared->iga1_devices
2346 | viaparinfo->shared->iga2_devices;
2347 u8 value, index, mask;
2348 struct crt_mode_table *crt_timing;
2349 struct crt_mode_table *crt_timing1 = NULL;
2351 device_screen_off();
2352 crt_timing = vmode_tbl->crtc;
2354 if (viafb_SAMM_ON == 1) {
2355 crt_timing1 = vmode_tbl1->crtc;
2361 /* Write Common Setting for Video Mode */
2362 switch (viaparinfo->chip_info->gfx_chip_name) {
2363 case UNICHROME_CLE266:
2364 viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
2367 case UNICHROME_K400:
2368 viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
2371 case UNICHROME_K800:
2372 case UNICHROME_PM800:
2373 viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
2376 case UNICHROME_CN700:
2377 case UNICHROME_K8M890:
2378 case UNICHROME_P4M890:
2379 case UNICHROME_P4M900:
2380 viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
2383 case UNICHROME_CX700:
2384 case UNICHROME_VX800:
2385 viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
2388 case UNICHROME_VX855:
2389 case UNICHROME_VX900:
2390 viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs);
2394 viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
2396 via_set_state(devices, VIA_STATE_OFF);
2398 /* Fill VPIT Parameters */
2399 /* Write Misc Register */
2400 outb(VPIT.Misc, VIA_MISC_REG_WRITE);
2402 /* Write Sequencer */
2403 for (i = 1; i <= StdSR; i++)
2404 via_write_reg(VIASR, i, VPIT.SR[i - 1]);
2406 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
2409 viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
2411 /* Write Graphic Controller */
2412 for (i = 0; i < StdGR; i++)
2413 via_write_reg(VIAGR, i, VPIT.GR[i]);
2415 /* Write Attribute Controller */
2416 for (i = 0; i < StdAR; i++) {
2419 outb(VPIT.AR[i], VIAAR);
2425 /* Update Patch Register */
2427 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
2428 || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
2429 && vmode_tbl->crtc[0].crtc.hor_addr == 1024
2430 && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
2431 for (j = 0; j < res_patch_table[0].table_length; j++) {
2432 index = res_patch_table[0].io_reg_table[j].index;
2433 port = res_patch_table[0].io_reg_table[j].port;
2434 value = res_patch_table[0].io_reg_table[j].value;
2435 mask = res_patch_table[0].io_reg_table[j].mask;
2436 viafb_write_reg_mask(index, port, value, mask);
2440 via_set_primary_pitch(viafbinfo->fix.line_length);
2441 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2442 : viafbinfo->fix.line_length);
2443 via_set_primary_color_depth(viaparinfo->depth);
2444 via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
2445 : viaparinfo->depth);
2446 via_set_source(viaparinfo->shared->iga1_devices, IGA1);
2447 via_set_source(viaparinfo->shared->iga2_devices, IGA2);
2448 if (viaparinfo->shared->iga2_devices)
2449 enable_second_display_channel();
2451 disable_second_display_channel();
2453 /* Update Refresh Rate Setting */
2455 /* Clear On Screen */
2459 if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
2461 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1,
2463 viaparinfo->crt_setting_info->iga_path);
2465 viafb_fill_crtc_timing(crt_timing, vmode_tbl,
2467 viaparinfo->crt_setting_info->iga_path);
2470 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2471 to 8 alignment (1368),there is several pixels (2 pixels)
2472 on right side of screen. */
2473 if (vmode_tbl->crtc[0].crtc.hor_addr % 8) {
2475 viafb_write_reg(CR02, VIACR,
2476 viafb_read_reg(VIACR, CR02) - 1);
2482 if (viafb_SAMM_ON &&
2483 (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
2484 viafb_dvi_set_mode(viafb_get_mode
2485 (viaparinfo->tmds_setting_info->h_active,
2486 viaparinfo->tmds_setting_info->
2488 video_bpp1, viaparinfo->
2489 tmds_setting_info->iga_path);
2491 viafb_dvi_set_mode(viafb_get_mode
2492 (viaparinfo->tmds_setting_info->h_active,
2494 tmds_setting_info->v_active),
2495 video_bpp, viaparinfo->
2496 tmds_setting_info->iga_path);
2501 if (viafb_SAMM_ON &&
2502 (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
2503 viaparinfo->lvds_setting_info->bpp = video_bpp1;
2504 viafb_lcd_set_mode(crt_timing1, viaparinfo->
2506 &viaparinfo->chip_info->lvds_chip_info);
2508 /* IGA1 doesn't have LCD scaling, so set it center. */
2509 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
2510 viaparinfo->lvds_setting_info->display_method =
2513 viaparinfo->lvds_setting_info->bpp = video_bpp;
2514 viafb_lcd_set_mode(crt_timing, viaparinfo->
2516 &viaparinfo->chip_info->lvds_chip_info);
2519 if (viafb_LCD2_ON) {
2520 if (viafb_SAMM_ON &&
2521 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
2522 viaparinfo->lvds_setting_info2->bpp = video_bpp1;
2523 viafb_lcd_set_mode(crt_timing1, viaparinfo->
2525 &viaparinfo->chip_info->lvds_chip_info2);
2527 /* IGA1 doesn't have LCD scaling, so set it center. */
2528 if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
2529 viaparinfo->lvds_setting_info2->display_method =
2532 viaparinfo->lvds_setting_info2->bpp = video_bpp;
2533 viafb_lcd_set_mode(crt_timing, viaparinfo->
2535 &viaparinfo->chip_info->lvds_chip_info2);
2539 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
2540 && (viafb_LCD_ON || viafb_DVI_ON))
2541 set_display_channel();
2543 /* If set mode normally, save resolution information for hot-plug . */
2544 if (!viafb_hotplug) {
2545 viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr;
2546 viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr;
2547 viafb_hotplug_bpp = video_bpp;
2548 viafb_hotplug_refresh = viafb_refresh;
2551 viafb_DeviceStatus = DVI_Device;
2553 viafb_DeviceStatus = CRT_Device;
2557 via_set_sync_polarity(devices, get_sync(viafbinfo));
2559 via_set_sync_polarity(viaparinfo->shared->iga1_devices,
2560 get_sync(viafbinfo));
2561 via_set_sync_polarity(viaparinfo->shared->iga2_devices,
2562 get_sync(viafbinfo1));
2565 via_set_state(devices, VIA_STATE_ON);
2570 int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2573 struct crt_mode_table *best;
2574 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2577 return RES_640X480_60HZ_PIXCLOCK;
2579 best = &vmode->crtc[0];
2580 for (i = 1; i < vmode->mode_array; i++) {
2581 if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
2582 < abs(best->refresh_rate - vmode_refresh))
2583 best = &vmode->crtc[i];
2586 return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
2587 * 1000 / best->refresh_rate;
2590 int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2593 struct crt_mode_table *best;
2594 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2599 best = &vmode->crtc[0];
2600 for (i = 1; i < vmode->mode_array; i++) {
2601 if (abs(vmode->crtc[i].refresh_rate - long_refresh)
2602 < abs(best->refresh_rate - long_refresh))
2603 best = &vmode->crtc[i];
2606 if (abs(best->refresh_rate - long_refresh) > 3) {
2607 if (hres == 1200 && vres == 900)
2608 return 50; /* OLPC DCON only supports 50 Hz */
2613 return best->refresh_rate;
2616 static void device_off(void)
2618 viafb_dvi_disable();
2619 viafb_lcd_disable();
2622 static void device_on(void)
2624 if (viafb_DVI_ON == 1)
2626 if (viafb_LCD_ON == 1)
2630 static void enable_second_display_channel(void)
2632 /* to enable second display channel. */
2633 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2634 viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
2635 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2638 static void disable_second_display_channel(void)
2640 /* to disable second display channel. */
2641 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
2642 viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
2643 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2646 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2649 switch (output_interface) {
2650 case INTERFACE_DVP0:
2652 /* DVP0 Clock Polarity and Adjust: */
2653 viafb_write_reg_mask(CR96, VIACR,
2654 p_gfx_dpa_setting->DVP0, 0x0F);
2656 /* DVP0 Clock and Data Pads Driving: */
2657 viafb_write_reg_mask(SR1E, VIASR,
2658 p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
2659 viafb_write_reg_mask(SR2A, VIASR,
2660 p_gfx_dpa_setting->DVP0ClockDri_S1,
2662 viafb_write_reg_mask(SR1B, VIASR,
2663 p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
2664 viafb_write_reg_mask(SR2A, VIASR,
2665 p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
2669 case INTERFACE_DVP1:
2671 /* DVP1 Clock Polarity and Adjust: */
2672 viafb_write_reg_mask(CR9B, VIACR,
2673 p_gfx_dpa_setting->DVP1, 0x0F);
2675 /* DVP1 Clock and Data Pads Driving: */
2676 viafb_write_reg_mask(SR65, VIASR,
2677 p_gfx_dpa_setting->DVP1Driving, 0x0F);
2681 case INTERFACE_DFP_HIGH:
2683 viafb_write_reg_mask(CR97, VIACR,
2684 p_gfx_dpa_setting->DFPHigh, 0x0F);
2688 case INTERFACE_DFP_LOW:
2690 viafb_write_reg_mask(CR99, VIACR,
2691 p_gfx_dpa_setting->DFPLow, 0x0F);
2697 viafb_write_reg_mask(CR97, VIACR,
2698 p_gfx_dpa_setting->DFPHigh, 0x0F);
2699 viafb_write_reg_mask(CR99, VIACR,
2700 p_gfx_dpa_setting->DFPLow, 0x0F);
2706 /*According var's xres, yres fill var's other timing information*/
2707 void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2708 struct VideoModeTable *vmode_tbl)
2710 struct crt_mode_table *crt_timing = NULL;
2711 struct display_timing crt_reg;
2712 int i = 0, index = 0;
2713 crt_timing = vmode_tbl->crtc;
2714 for (i = 0; i < vmode_tbl->mode_array; i++) {
2716 if (crt_timing[i].refresh_rate == refresh)
2720 crt_reg = crt_timing[index].crtc;
2721 var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
2723 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2724 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
2725 var->hsync_len = crt_reg.hor_sync_end;
2727 crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
2728 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2729 var->vsync_len = crt_reg.ver_sync_end;
2731 if (crt_timing[index].h_sync_polarity == POSITIVE)
2732 var->sync |= FB_SYNC_HOR_HIGH_ACT;
2733 if (crt_timing[index].v_sync_polarity == POSITIVE)
2734 var->sync |= FB_SYNC_VERT_HIGH_ACT;