aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-10-04 05:55:04 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-10-04 05:55:04 -0400
commit6488867c0525c9189f2f0d18e9009529b4732782 (patch)
tree995dd1bd84452de928357ba837e893e9c2a67e40 /drivers
parent4d7408014e4f085c43b511b436ac60d1d61e6e17 (diff)
parent4ce36bbb0497bdd3d6b8682175e5c58745b7acdd (diff)
Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6 into fbdev-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/via/dvi.c34
-rw-r--r--drivers/video/via/dvi.h3
-rw-r--r--drivers/video/via/global.c2
-rw-r--r--drivers/video/via/global.h2
-rw-r--r--drivers/video/via/hw.c544
-rw-r--r--drivers/video/via/hw.h285
-rw-r--r--drivers/video/via/lcd.c53
-rw-r--r--drivers/video/via/lcd.h7
-rw-r--r--drivers/video/via/share.h23
-rw-r--r--drivers/video/via/via-core.c2
-rw-r--r--drivers/video/via/via_modesetting.c104
-rw-r--r--drivers/video/via/via_modesetting.h18
-rw-r--r--drivers/video/via/viafbdev.c166
-rw-r--r--drivers/video/via/viamode.c60
-rw-r--r--drivers/video/via/viamode.h4
15 files changed, 391 insertions, 916 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index b1f364745ca0..9138e517267c 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -172,30 +172,20 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
172} 172}
173 173
174/* DVI Set Mode */ 174/* DVI Set Mode */
175void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, 175void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
176 int set_iga)
177{ 176{
178 struct VideoModeTable *rb_mode; 177 struct fb_var_screeninfo dvi_var = *var;
179 struct crt_mode_table *pDviTiming; 178 struct crt_mode_table *rb_mode;
180 unsigned long desirePixelClock, maxPixelClock; 179 int maxPixelClock;
181 pDviTiming = mode->crtc; 180
182 desirePixelClock = pDviTiming->refresh_rate 181 maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock;
183 * pDviTiming->crtc.hor_total * pDviTiming->crtc.ver_total 182 if (maxPixelClock && PICOS2KHZ(var->pixclock) / 1000 > maxPixelClock) {
184 / 1000000; 183 rb_mode = viafb_get_best_rb_mode(var->xres, var->yres, 60);
185 maxPixelClock = (unsigned long)viaparinfo-> 184 if (rb_mode)
186 tmds_setting_info->max_pixel_clock; 185 viafb_fill_var_timing_info(&dvi_var, rb_mode);
187
188 DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
189
190 if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
191 rb_mode = viafb_get_rb_mode(mode->crtc[0].crtc.hor_addr,
192 mode->crtc[0].crtc.ver_addr);
193 if (rb_mode) {
194 mode = rb_mode;
195 pDviTiming = rb_mode->crtc;
196 }
197 } 186 }
198 viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); 187
188 viafb_fill_crtc_timing(&dvi_var, iga);
199} 189}
200 190
201/* Sense DVI Connector */ 191/* Sense DVI Connector */
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
index f473dd010977..e2116aaf797a 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/via/dvi.h
@@ -59,7 +59,6 @@ void viafb_dvi_enable(void);
59bool __devinit viafb_tmds_trasmitter_identify(void); 59bool __devinit viafb_tmds_trasmitter_identify(void);
60void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, 60void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
61 struct tmds_setting_information *tmds_setting); 61 struct tmds_setting_information *tmds_setting);
62void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, 62void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga);
63 int set_iga);
64 63
65#endif /* __DVI_H__ */ 64#endif /* __DVI_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
index e10d8249534c..3102171c1674 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/via/global.c
@@ -35,6 +35,8 @@ int viafb_LCD_ON ;
35int viafb_LCD2_ON; 35int viafb_LCD2_ON;
36int viafb_SAMM_ON; 36int viafb_SAMM_ON;
37int viafb_dual_fb; 37int viafb_dual_fb;
38unsigned int viafb_second_xres = 640;
39unsigned int viafb_second_yres = 480;
38int viafb_hotplug_Xres = 640; 40int viafb_hotplug_Xres = 640;
39int viafb_hotplug_Yres = 480; 41int viafb_hotplug_Yres = 480;
40int viafb_hotplug_bpp = 32; 42int viafb_hotplug_bpp = 32;
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index ff969dc34593..275dbbbd6b81 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -67,6 +67,8 @@ extern int viafb_lcd_dsp_method;
67extern int viafb_lcd_mode; 67extern int viafb_lcd_mode;
68 68
69extern int viafb_CRT_ON; 69extern int viafb_CRT_ON;
70extern unsigned int viafb_second_xres;
71extern unsigned int viafb_second_yres;
70extern int viafb_hotplug_Xres; 72extern int viafb_hotplug_Xres;
71extern int viafb_hotplug_Yres; 73extern int viafb_hotplug_Yres;
72extern int viafb_hotplug_bpp; 74extern int viafb_hotplug_bpp;
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index 47b13535ed2b..d5aaca9cfa7e 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -191,67 +191,6 @@ static struct fetch_count fetch_count_reg = {
191 {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } } 191 {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
192}; 192};
193 193
194static struct iga1_crtc_timing iga1_crtc_reg = {
195 /* IGA1 Horizontal Total */
196 {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
197 /* IGA1 Horizontal Addressable Video */
198 {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
199 /* IGA1 Horizontal Blank Start */
200 {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
201 /* IGA1 Horizontal Blank End */
202 {IGA1_HOR_BLANK_END_REG_NUM,
203 {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
204 /* IGA1 Horizontal Sync Start */
205 {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
206 /* IGA1 Horizontal Sync End */
207 {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
208 /* IGA1 Vertical Total */
209 {IGA1_VER_TOTAL_REG_NUM,
210 {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
211 /* IGA1 Vertical Addressable Video */
212 {IGA1_VER_ADDR_REG_NUM,
213 {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
214 /* IGA1 Vertical Blank Start */
215 {IGA1_VER_BLANK_START_REG_NUM,
216 {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
217 /* IGA1 Vertical Blank End */
218 {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
219 /* IGA1 Vertical Sync Start */
220 {IGA1_VER_SYNC_START_REG_NUM,
221 {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
222 /* IGA1 Vertical Sync End */
223 {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
224};
225
226static struct iga2_crtc_timing iga2_crtc_reg = {
227 /* IGA2 Horizontal Total */
228 {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
229 /* IGA2 Horizontal Addressable Video */
230 {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
231 /* IGA2 Horizontal Blank Start */
232 {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
233 /* IGA2 Horizontal Blank End */
234 {IGA2_HOR_BLANK_END_REG_NUM,
235 {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
236 /* IGA2 Horizontal Sync Start */
237 {IGA2_HOR_SYNC_START_REG_NUM,
238 {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
239 /* IGA2 Horizontal Sync End */
240 {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
241 /* IGA2 Vertical Total */
242 {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
243 /* IGA2 Vertical Addressable Video */
244 {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
245 /* IGA2 Vertical Blank Start */
246 {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
247 /* IGA2 Vertical Blank End */
248 {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
249 /* IGA2 Vertical Sync Start */
250 {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
251 /* IGA2 Vertical Sync End */
252 {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
253};
254
255static struct rgbLUT palLUT_table[] = { 194static struct rgbLUT palLUT_table[] = {
256 /* {R,G,B} */ 195 /* {R,G,B} */
257 /* Index 0x00~0x03 */ 196 /* Index 0x00~0x03 */
@@ -1528,302 +1467,40 @@ void viafb_set_vclock(u32 clk, int set_iga)
1528 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ 1467 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
1529} 1468}
1530 1469
1531void viafb_load_crtc_timing(struct display_timing device_timing, 1470static struct display_timing var_to_timing(const struct fb_var_screeninfo *var)
1532 int set_iga)
1533{ 1471{
1534 int i; 1472 struct display_timing timing;
1535 int viafb_load_reg_num = 0; 1473
1536 int reg_value = 0; 1474 timing.hor_addr = var->xres;
1537 struct io_register *reg = NULL; 1475 timing.hor_sync_start = timing.hor_addr + var->right_margin;
1538 1476 timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
1539 viafb_unlock_crt(); 1477 timing.hor_total = timing.hor_sync_end + var->left_margin;
1540 1478 timing.hor_blank_start = timing.hor_addr;
1541 for (i = 0; i < 12; i++) { 1479 timing.hor_blank_end = timing.hor_total;
1542 if (set_iga == IGA1) { 1480 timing.ver_addr = var->yres;
1543 switch (i) { 1481 timing.ver_sync_start = timing.ver_addr + var->lower_margin;
1544 case H_TOTAL_INDEX: 1482 timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
1545 reg_value = 1483 timing.ver_total = timing.ver_sync_end + var->upper_margin;
1546 IGA1_HOR_TOTAL_FORMULA(device_timing. 1484 timing.ver_blank_start = timing.ver_addr;
1547 hor_total); 1485 timing.ver_blank_end = timing.ver_total;
1548 viafb_load_reg_num = 1486 return timing;
1549 iga1_crtc_reg.hor_total.reg_num;
1550 reg = iga1_crtc_reg.hor_total.reg;
1551 break;
1552 case H_ADDR_INDEX:
1553 reg_value =
1554 IGA1_HOR_ADDR_FORMULA(device_timing.
1555 hor_addr);
1556 viafb_load_reg_num =
1557 iga1_crtc_reg.hor_addr.reg_num;
1558 reg = iga1_crtc_reg.hor_addr.reg;
1559 break;
1560 case H_BLANK_START_INDEX:
1561 reg_value =
1562 IGA1_HOR_BLANK_START_FORMULA
1563 (device_timing.hor_blank_start);
1564 viafb_load_reg_num =
1565 iga1_crtc_reg.hor_blank_start.reg_num;
1566 reg = iga1_crtc_reg.hor_blank_start.reg;
1567 break;
1568 case H_BLANK_END_INDEX:
1569 reg_value =
1570 IGA1_HOR_BLANK_END_FORMULA
1571 (device_timing.hor_blank_start,
1572 device_timing.hor_blank_end);
1573 viafb_load_reg_num =
1574 iga1_crtc_reg.hor_blank_end.reg_num;
1575 reg = iga1_crtc_reg.hor_blank_end.reg;
1576 break;
1577 case H_SYNC_START_INDEX:
1578 reg_value =
1579 IGA1_HOR_SYNC_START_FORMULA
1580 (device_timing.hor_sync_start);
1581 viafb_load_reg_num =
1582 iga1_crtc_reg.hor_sync_start.reg_num;
1583 reg = iga1_crtc_reg.hor_sync_start.reg;
1584 break;
1585 case H_SYNC_END_INDEX:
1586 reg_value =
1587 IGA1_HOR_SYNC_END_FORMULA
1588 (device_timing.hor_sync_start,
1589 device_timing.hor_sync_end);
1590 viafb_load_reg_num =
1591 iga1_crtc_reg.hor_sync_end.reg_num;
1592 reg = iga1_crtc_reg.hor_sync_end.reg;
1593 break;
1594 case V_TOTAL_INDEX:
1595 reg_value =
1596 IGA1_VER_TOTAL_FORMULA(device_timing.
1597 ver_total);
1598 viafb_load_reg_num =
1599 iga1_crtc_reg.ver_total.reg_num;
1600 reg = iga1_crtc_reg.ver_total.reg;
1601 break;
1602 case V_ADDR_INDEX:
1603 reg_value =
1604 IGA1_VER_ADDR_FORMULA(device_timing.
1605 ver_addr);
1606 viafb_load_reg_num =
1607 iga1_crtc_reg.ver_addr.reg_num;
1608 reg = iga1_crtc_reg.ver_addr.reg;
1609 break;
1610 case V_BLANK_START_INDEX:
1611 reg_value =
1612 IGA1_VER_BLANK_START_FORMULA
1613 (device_timing.ver_blank_start);
1614 viafb_load_reg_num =
1615 iga1_crtc_reg.ver_blank_start.reg_num;
1616 reg = iga1_crtc_reg.ver_blank_start.reg;
1617 break;
1618 case V_BLANK_END_INDEX:
1619 reg_value =
1620 IGA1_VER_BLANK_END_FORMULA
1621 (device_timing.ver_blank_start,
1622 device_timing.ver_blank_end);
1623 viafb_load_reg_num =
1624 iga1_crtc_reg.ver_blank_end.reg_num;
1625 reg = iga1_crtc_reg.ver_blank_end.reg;
1626 break;
1627 case V_SYNC_START_INDEX:
1628 reg_value =
1629 IGA1_VER_SYNC_START_FORMULA
1630 (device_timing.ver_sync_start);
1631 viafb_load_reg_num =
1632 iga1_crtc_reg.ver_sync_start.reg_num;
1633 reg = iga1_crtc_reg.ver_sync_start.reg;
1634 break;
1635 case V_SYNC_END_INDEX:
1636 reg_value =
1637 IGA1_VER_SYNC_END_FORMULA
1638 (device_timing.ver_sync_start,
1639 device_timing.ver_sync_end);
1640 viafb_load_reg_num =
1641 iga1_crtc_reg.ver_sync_end.reg_num;
1642 reg = iga1_crtc_reg.ver_sync_end.reg;
1643 break;
1644
1645 }
1646 }
1647
1648 if (set_iga == IGA2) {
1649 switch (i) {
1650 case H_TOTAL_INDEX:
1651 reg_value =
1652 IGA2_HOR_TOTAL_FORMULA(device_timing.
1653 hor_total);
1654 viafb_load_reg_num =
1655 iga2_crtc_reg.hor_total.reg_num;
1656 reg = iga2_crtc_reg.hor_total.reg;
1657 break;
1658 case H_ADDR_INDEX:
1659 reg_value =
1660 IGA2_HOR_ADDR_FORMULA(device_timing.
1661 hor_addr);
1662 viafb_load_reg_num =
1663 iga2_crtc_reg.hor_addr.reg_num;
1664 reg = iga2_crtc_reg.hor_addr.reg;
1665 break;
1666 case H_BLANK_START_INDEX:
1667 reg_value =
1668 IGA2_HOR_BLANK_START_FORMULA
1669 (device_timing.hor_blank_start);
1670 viafb_load_reg_num =
1671 iga2_crtc_reg.hor_blank_start.reg_num;
1672 reg = iga2_crtc_reg.hor_blank_start.reg;
1673 break;
1674 case H_BLANK_END_INDEX:
1675 reg_value =
1676 IGA2_HOR_BLANK_END_FORMULA
1677 (device_timing.hor_blank_start,
1678 device_timing.hor_blank_end);
1679 viafb_load_reg_num =
1680 iga2_crtc_reg.hor_blank_end.reg_num;
1681 reg = iga2_crtc_reg.hor_blank_end.reg;
1682 break;
1683 case H_SYNC_START_INDEX:
1684 reg_value =
1685 IGA2_HOR_SYNC_START_FORMULA
1686 (device_timing.hor_sync_start);
1687 if (UNICHROME_CN700 <=
1688 viaparinfo->chip_info->gfx_chip_name)
1689 viafb_load_reg_num =
1690 iga2_crtc_reg.hor_sync_start.
1691 reg_num;
1692 else
1693 viafb_load_reg_num = 3;
1694 reg = iga2_crtc_reg.hor_sync_start.reg;
1695 break;
1696 case H_SYNC_END_INDEX:
1697 reg_value =
1698 IGA2_HOR_SYNC_END_FORMULA
1699 (device_timing.hor_sync_start,
1700 device_timing.hor_sync_end);
1701 viafb_load_reg_num =
1702 iga2_crtc_reg.hor_sync_end.reg_num;
1703 reg = iga2_crtc_reg.hor_sync_end.reg;
1704 break;
1705 case V_TOTAL_INDEX:
1706 reg_value =
1707 IGA2_VER_TOTAL_FORMULA(device_timing.
1708 ver_total);
1709 viafb_load_reg_num =
1710 iga2_crtc_reg.ver_total.reg_num;
1711 reg = iga2_crtc_reg.ver_total.reg;
1712 break;
1713 case V_ADDR_INDEX:
1714 reg_value =
1715 IGA2_VER_ADDR_FORMULA(device_timing.
1716 ver_addr);
1717 viafb_load_reg_num =
1718 iga2_crtc_reg.ver_addr.reg_num;
1719 reg = iga2_crtc_reg.ver_addr.reg;
1720 break;
1721 case V_BLANK_START_INDEX:
1722 reg_value =
1723 IGA2_VER_BLANK_START_FORMULA
1724 (device_timing.ver_blank_start);
1725 viafb_load_reg_num =
1726 iga2_crtc_reg.ver_blank_start.reg_num;
1727 reg = iga2_crtc_reg.ver_blank_start.reg;
1728 break;
1729 case V_BLANK_END_INDEX:
1730 reg_value =
1731 IGA2_VER_BLANK_END_FORMULA
1732 (device_timing.ver_blank_start,
1733 device_timing.ver_blank_end);
1734 viafb_load_reg_num =
1735 iga2_crtc_reg.ver_blank_end.reg_num;
1736 reg = iga2_crtc_reg.ver_blank_end.reg;
1737 break;
1738 case V_SYNC_START_INDEX:
1739 reg_value =
1740 IGA2_VER_SYNC_START_FORMULA
1741 (device_timing.ver_sync_start);
1742 viafb_load_reg_num =
1743 iga2_crtc_reg.ver_sync_start.reg_num;
1744 reg = iga2_crtc_reg.ver_sync_start.reg;
1745 break;
1746 case V_SYNC_END_INDEX:
1747 reg_value =
1748 IGA2_VER_SYNC_END_FORMULA
1749 (device_timing.ver_sync_start,
1750 device_timing.ver_sync_end);
1751 viafb_load_reg_num =
1752 iga2_crtc_reg.ver_sync_end.reg_num;
1753 reg = iga2_crtc_reg.ver_sync_end.reg;
1754 break;
1755
1756 }
1757 }
1758 viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
1759 }
1760
1761 viafb_lock_crt();
1762} 1487}
1763 1488
1764void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, 1489void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga)
1765 struct VideoModeTable *video_mode, int bpp_byte, int set_iga)
1766{ 1490{
1767 struct display_timing crt_reg; 1491 struct display_timing crt_reg = var_to_timing(var);
1768 int i;
1769 int index = 0;
1770 int h_addr, v_addr;
1771 u32 clock, refresh = viafb_refresh;
1772
1773 if (viafb_SAMM_ON && set_iga == IGA2)
1774 refresh = viafb_refresh1;
1775
1776 for (i = 0; i < video_mode->mode_array; i++) {
1777 index = i;
1778
1779 if (crt_table[i].refresh_rate == refresh)
1780 break;
1781 }
1782 1492
1783 crt_reg = crt_table[index].crtc; 1493 if (iga == IGA1)
1494 via_set_primary_timing(&crt_reg);
1495 else if (iga == IGA2)
1496 via_set_secondary_timing(&crt_reg);
1784 1497
1785 /* Mode 640x480 has border, but LCD/DFP didn't have border. */ 1498 viafb_load_fetch_count_reg(var->xres, var->bits_per_pixel / 8, iga);
1786 /* So we would delete border. */ 1499 if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266
1787 if ((viafb_LCD_ON | viafb_DVI_ON) 1500 && viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400)
1788 && video_mode->crtc[0].crtc.hor_addr == 640 1501 viafb_load_FIFO_reg(iga, var->xres, var->yres);
1789 && video_mode->crtc[0].crtc.ver_addr == 480
1790 && refresh == 60) {
1791 /* The border is 8 pixels. */
1792 crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
1793
1794 /* Blanking time should add left and right borders. */
1795 crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
1796 }
1797
1798 h_addr = crt_reg.hor_addr;
1799 v_addr = crt_reg.ver_addr;
1800 if (set_iga == IGA1) {
1801 viafb_unlock_crt();
1802 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1803 }
1804
1805 switch (set_iga) {
1806 case IGA1:
1807 viafb_load_crtc_timing(crt_reg, IGA1);
1808 break;
1809 case IGA2:
1810 viafb_load_crtc_timing(crt_reg, IGA2);
1811 break;
1812 }
1813
1814 viafb_lock_crt();
1815 viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1816 viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
1817
1818 /* load FIFO */
1819 if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
1820 && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
1821 viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
1822
1823 clock = crt_reg.hor_total * crt_reg.ver_total
1824 * crt_table[index].refresh_rate;
1825 viafb_set_vclock(clock, set_iga);
1826 1502
1503 viafb_set_vclock(PICOS2KHZ(var->pixclock) * 1000, iga);
1827} 1504}
1828 1505
1829void __devinit viafb_init_chip_info(int chip_type) 1506void __devinit viafb_init_chip_info(int chip_type)
@@ -2092,23 +1769,9 @@ static u8 get_sync(struct fb_info *info)
2092 return polarity; 1769 return polarity;
2093} 1770}
2094 1771
2095int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, 1772static void hw_init(void)
2096 struct VideoModeTable *vmode_tbl1, int video_bpp1)
2097{ 1773{
2098 int i, j; 1774 int i;
2099 int port;
2100 u32 devices = viaparinfo->shared->iga1_devices
2101 | viaparinfo->shared->iga2_devices;
2102 u8 value, index, mask;
2103 struct crt_mode_table *crt_timing;
2104 struct crt_mode_table *crt_timing1 = NULL;
2105
2106 device_screen_off();
2107 crt_timing = vmode_tbl->crtc;
2108
2109 if (viafb_SAMM_ON == 1) {
2110 crt_timing1 = vmode_tbl1->crtc;
2111 }
2112 1775
2113 inb(VIAStatus); 1776 inb(VIAStatus);
2114 outb(0x00, VIAAR); 1777 outb(0x00, VIAAR);
@@ -2147,9 +1810,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2147 break; 1810 break;
2148 } 1811 }
2149 1812
1813 /* probably this should go to the scaling code one day */
2150 viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters)); 1814 viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
2151 device_off();
2152 via_set_state(devices, VIA_STATE_OFF);
2153 1815
2154 /* Fill VPIT Parameters */ 1816 /* Fill VPIT Parameters */
2155 /* Write Misc Register */ 1817 /* Write Misc Register */
@@ -2175,12 +1837,29 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2175 inb(VIAStatus); 1837 inb(VIAStatus);
2176 outb(0x20, VIAAR); 1838 outb(0x20, VIAAR);
2177 1839
1840 load_fix_bit_crtc_reg();
1841}
1842
1843int viafb_setmode(int video_bpp, int video_bpp1)
1844{
1845 int j;
1846 int port;
1847 u32 devices = viaparinfo->shared->iga1_devices
1848 | viaparinfo->shared->iga2_devices;
1849 u8 value, index, mask;
1850 struct fb_var_screeninfo var2;
1851
1852 device_screen_off();
1853 device_off();
1854 via_set_state(devices, VIA_STATE_OFF);
1855
1856 hw_init();
1857
2178 /* Update Patch Register */ 1858 /* Update Patch Register */
2179 1859
2180 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266 1860 if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266
2181 || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400) 1861 || viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)
2182 && vmode_tbl->crtc[0].crtc.hor_addr == 1024 1862 && viafbinfo->var.xres == 1024 && viafbinfo->var.yres == 768) {
2183 && vmode_tbl->crtc[0].crtc.ver_addr == 768) {
2184 for (j = 0; j < res_patch_table[0].table_length; j++) { 1863 for (j = 0; j < res_patch_table[0].table_length; j++) {
2185 index = res_patch_table[0].io_reg_table[j].index; 1864 index = res_patch_table[0].io_reg_table[j].index;
2186 port = res_patch_table[0].io_reg_table[j].port; 1865 port = res_patch_table[0].io_reg_table[j].port;
@@ -2190,7 +1869,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2190 } 1869 }
2191 } 1870 }
2192 1871
2193 load_fix_bit_crtc_reg();
2194 via_set_primary_pitch(viafbinfo->fix.line_length); 1872 via_set_primary_pitch(viafbinfo->fix.line_length);
2195 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length 1873 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2196 : viafbinfo->fix.line_length); 1874 : viafbinfo->fix.line_length);
@@ -2208,23 +1886,28 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2208 1886
2209 /* Clear On Screen */ 1887 /* Clear On Screen */
2210 1888
1889 if (viafb_dual_fb) {
1890 var2 = viafbinfo1->var;
1891 } else if (viafb_SAMM_ON) {
1892 viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
1893 viafb_second_xres, viafb_second_yres, viafb_refresh1));
1894 var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
1895 }
1896
2211 /* CRT set mode */ 1897 /* CRT set mode */
2212 if (viafb_CRT_ON) { 1898 if (viafb_CRT_ON) {
2213 if (viafb_SAMM_ON && 1899 if (viaparinfo->shared->iga2_devices & VIA_CRT
2214 viaparinfo->shared->iga2_devices & VIA_CRT) { 1900 && viafb_SAMM_ON)
2215 viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, 1901 viafb_fill_crtc_timing(&var2, IGA2);
2216 video_bpp1 / 8, IGA2); 1902 else
2217 } else { 1903 viafb_fill_crtc_timing(&viafbinfo->var,
2218 viafb_fill_crtc_timing(crt_timing, vmode_tbl,
2219 video_bpp / 8,
2220 (viaparinfo->shared->iga1_devices & VIA_CRT) 1904 (viaparinfo->shared->iga1_devices & VIA_CRT)
2221 ? IGA1 : IGA2); 1905 ? IGA1 : IGA2);
2222 }
2223 1906
2224 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode 1907 /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
2225 to 8 alignment (1368),there is several pixels (2 pixels) 1908 to 8 alignment (1368),there is several pixels (2 pixels)
2226 on right side of screen. */ 1909 on right side of screen. */
2227 if (vmode_tbl->crtc[0].crtc.hor_addr % 8) { 1910 if (viafbinfo->var.xres % 8) {
2228 viafb_unlock_crt(); 1911 viafb_unlock_crt();
2229 viafb_write_reg(CR02, VIACR, 1912 viafb_write_reg(CR02, VIACR,
2230 viafb_read_reg(VIACR, CR02) - 1); 1913 viafb_read_reg(VIACR, CR02) - 1);
@@ -2233,31 +1916,20 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2233 } 1916 }
2234 1917
2235 if (viafb_DVI_ON) { 1918 if (viafb_DVI_ON) {
2236 if (viafb_SAMM_ON && 1919 if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
2237 (viaparinfo->tmds_setting_info->iga_path == IGA2)) { 1920 && viafb_SAMM_ON)
2238 viafb_dvi_set_mode(viafb_get_mode 1921 viafb_dvi_set_mode(&var2, IGA2);
2239 (viaparinfo->tmds_setting_info->h_active, 1922 else
2240 viaparinfo->tmds_setting_info-> 1923 viafb_dvi_set_mode(&viafbinfo->var,
2241 v_active), 1924 viaparinfo->tmds_setting_info->iga_path);
2242 video_bpp1, viaparinfo->
2243 tmds_setting_info->iga_path);
2244 } else {
2245 viafb_dvi_set_mode(viafb_get_mode
2246 (viaparinfo->tmds_setting_info->h_active,
2247 viaparinfo->
2248 tmds_setting_info->v_active),
2249 video_bpp, viaparinfo->
2250 tmds_setting_info->iga_path);
2251 }
2252 } 1925 }
2253 1926
2254 if (viafb_LCD_ON) { 1927 if (viafb_LCD_ON) {
2255 if (viafb_SAMM_ON && 1928 if (viafb_SAMM_ON &&
2256 (viaparinfo->lvds_setting_info->iga_path == IGA2)) { 1929 (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
2257 viaparinfo->lvds_setting_info->bpp = video_bpp1; 1930 viaparinfo->lvds_setting_info->bpp = video_bpp1;
2258 viafb_lcd_set_mode(crt_timing1, viaparinfo-> 1931 viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
2259 lvds_setting_info, 1932 &viaparinfo->chip_info->lvds_chip_info);
2260 &viaparinfo->chip_info->lvds_chip_info);
2261 } else { 1933 } else {
2262 /* IGA1 doesn't have LCD scaling, so set it center. */ 1934 /* IGA1 doesn't have LCD scaling, so set it center. */
2263 if (viaparinfo->lvds_setting_info->iga_path == IGA1) { 1935 if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
@@ -2265,18 +1937,16 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2265 LCD_CENTERING; 1937 LCD_CENTERING;
2266 } 1938 }
2267 viaparinfo->lvds_setting_info->bpp = video_bpp; 1939 viaparinfo->lvds_setting_info->bpp = video_bpp;
2268 viafb_lcd_set_mode(crt_timing, viaparinfo-> 1940 viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
2269 lvds_setting_info, 1941 &viaparinfo->chip_info->lvds_chip_info);
2270 &viaparinfo->chip_info->lvds_chip_info);
2271 } 1942 }
2272 } 1943 }
2273 if (viafb_LCD2_ON) { 1944 if (viafb_LCD2_ON) {
2274 if (viafb_SAMM_ON && 1945 if (viafb_SAMM_ON &&
2275 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) { 1946 (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
2276 viaparinfo->lvds_setting_info2->bpp = video_bpp1; 1947 viaparinfo->lvds_setting_info2->bpp = video_bpp1;
2277 viafb_lcd_set_mode(crt_timing1, viaparinfo-> 1948 viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
2278 lvds_setting_info2, 1949 &viaparinfo->chip_info->lvds_chip_info2);
2279 &viaparinfo->chip_info->lvds_chip_info2);
2280 } else { 1950 } else {
2281 /* IGA1 doesn't have LCD scaling, so set it center. */ 1951 /* IGA1 doesn't have LCD scaling, so set it center. */
2282 if (viaparinfo->lvds_setting_info2->iga_path == IGA1) { 1952 if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
@@ -2284,9 +1954,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2284 LCD_CENTERING; 1954 LCD_CENTERING;
2285 } 1955 }
2286 viaparinfo->lvds_setting_info2->bpp = video_bpp; 1956 viaparinfo->lvds_setting_info2->bpp = video_bpp;
2287 viafb_lcd_set_mode(crt_timing, viaparinfo-> 1957 viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
2288 lvds_setting_info2, 1958 &viaparinfo->chip_info->lvds_chip_info2);
2289 &viaparinfo->chip_info->lvds_chip_info2);
2290 } 1959 }
2291 } 1960 }
2292 1961
@@ -2296,8 +1965,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2296 1965
2297 /* If set mode normally, save resolution information for hot-plug . */ 1966 /* If set mode normally, save resolution information for hot-plug . */
2298 if (!viafb_hotplug) { 1967 if (!viafb_hotplug) {
2299 viafb_hotplug_Xres = vmode_tbl->crtc[0].crtc.hor_addr; 1968 viafb_hotplug_Xres = viafbinfo->var.xres;
2300 viafb_hotplug_Yres = vmode_tbl->crtc[0].crtc.ver_addr; 1969 viafb_hotplug_Yres = viafbinfo->var.yres;
2301 viafb_hotplug_bpp = video_bpp; 1970 viafb_hotplug_bpp = video_bpp;
2302 viafb_hotplug_refresh = viafb_refresh; 1971 viafb_hotplug_refresh = viafb_refresh;
2303 1972
@@ -2348,42 +2017,14 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2348 return 1; 2017 return 1;
2349} 2018}
2350 2019
2351int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
2352{
2353 int i;
2354 struct crt_mode_table *best;
2355 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2356
2357 if (!vmode)
2358 return RES_640X480_60HZ_PIXCLOCK;
2359
2360 best = &vmode->crtc[0];
2361 for (i = 1; i < vmode->mode_array; i++) {
2362 if (abs(vmode->crtc[i].refresh_rate - vmode_refresh)
2363 < abs(best->refresh_rate - vmode_refresh))
2364 best = &vmode->crtc[i];
2365 }
2366
2367 return 1000000000 / (best->crtc.hor_total * best->crtc.ver_total)
2368 * 1000 / best->refresh_rate;
2369}
2370
2371int viafb_get_refresh(int hres, int vres, u32 long_refresh) 2020int viafb_get_refresh(int hres, int vres, u32 long_refresh)
2372{ 2021{
2373 int i;
2374 struct crt_mode_table *best; 2022 struct crt_mode_table *best;
2375 struct VideoModeTable *vmode = viafb_get_mode(hres, vres);
2376 2023
2377 if (!vmode) 2024 best = viafb_get_best_mode(hres, vres, long_refresh);
2025 if (!best)
2378 return 60; 2026 return 60;
2379 2027
2380 best = &vmode->crtc[0];
2381 for (i = 1; i < vmode->mode_array; i++) {
2382 if (abs(vmode->crtc[i].refresh_rate - long_refresh)
2383 < abs(best->refresh_rate - long_refresh))
2384 best = &vmode->crtc[i];
2385 }
2386
2387 if (abs(best->refresh_rate - long_refresh) > 3) { 2028 if (abs(best->refresh_rate - long_refresh) > 3) {
2388 if (hres == 1200 && vres == 900) 2029 if (hres == 1200 && vres == 900)
2389 return 49; /* OLPC DCON only supports 50 Hz */ 2030 return 49; /* OLPC DCON only supports 50 Hz */
@@ -2485,21 +2126,14 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2485} 2126}
2486 2127
2487/*According var's xres, yres fill var's other timing information*/ 2128/*According var's xres, yres fill var's other timing information*/
2488void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 2129void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
2489 struct VideoModeTable *vmode_tbl) 2130 struct crt_mode_table *mode)
2490{ 2131{
2491 struct crt_mode_table *crt_timing = NULL;
2492 struct display_timing crt_reg; 2132 struct display_timing crt_reg;
2493 int i = 0, index = 0;
2494 crt_timing = vmode_tbl->crtc;
2495 for (i = 0; i < vmode_tbl->mode_array; i++) {
2496 index = i;
2497 if (crt_timing[i].refresh_rate == refresh)
2498 break;
2499 }
2500 2133
2501 crt_reg = crt_timing[index].crtc; 2134 crt_reg = mode->crtc;
2502 var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh); 2135 var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total)
2136 * 1000 / mode->refresh_rate;
2503 var->left_margin = 2137 var->left_margin =
2504 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end); 2138 crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
2505 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr; 2139 var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
@@ -2509,8 +2143,8 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
2509 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; 2143 var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
2510 var->vsync_len = crt_reg.ver_sync_end; 2144 var->vsync_len = crt_reg.ver_sync_end;
2511 var->sync = 0; 2145 var->sync = 0;
2512 if (crt_timing[index].h_sync_polarity == POSITIVE) 2146 if (mode->h_sync_polarity == POSITIVE)
2513 var->sync |= FB_SYNC_HOR_HIGH_ACT; 2147 var->sync |= FB_SYNC_HOR_HIGH_ACT;
2514 if (crt_timing[index].v_sync_polarity == POSITIVE) 2148 if (mode->v_sync_polarity == POSITIVE)
2515 var->sync |= FB_SYNC_VERT_HIGH_ACT; 2149 var->sync |= FB_SYNC_VERT_HIGH_ACT;
2516} 2150}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index c7239eb83bae..4db5b6e8d8d0 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -51,40 +51,6 @@
51#define VIA_HSYNC_NEGATIVE 0x01 51#define VIA_HSYNC_NEGATIVE 0x01
52#define VIA_VSYNC_NEGATIVE 0x02 52#define VIA_VSYNC_NEGATIVE 0x02
53 53
54/***************************************************
55* Definition IGA1 Design Method of CRTC Registers *
56****************************************************/
57#define IGA1_HOR_TOTAL_FORMULA(x) (((x)/8)-5)
58#define IGA1_HOR_ADDR_FORMULA(x) (((x)/8)-1)
59#define IGA1_HOR_BLANK_START_FORMULA(x) (((x)/8)-1)
60#define IGA1_HOR_BLANK_END_FORMULA(x, y) (((x+y)/8)-1)
61#define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8)
62#define IGA1_HOR_SYNC_END_FORMULA(x, y) ((x+y)/8)
63
64#define IGA1_VER_TOTAL_FORMULA(x) ((x)-2)
65#define IGA1_VER_ADDR_FORMULA(x) ((x)-1)
66#define IGA1_VER_BLANK_START_FORMULA(x) ((x)-1)
67#define IGA1_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
68#define IGA1_VER_SYNC_START_FORMULA(x) ((x)-1)
69#define IGA1_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
70
71/***************************************************
72** Definition IGA2 Design Method of CRTC Registers *
73****************************************************/
74#define IGA2_HOR_TOTAL_FORMULA(x) ((x)-1)
75#define IGA2_HOR_ADDR_FORMULA(x) ((x)-1)
76#define IGA2_HOR_BLANK_START_FORMULA(x) ((x)-1)
77#define IGA2_HOR_BLANK_END_FORMULA(x, y) ((x+y)-1)
78#define IGA2_HOR_SYNC_START_FORMULA(x) ((x)-1)
79#define IGA2_HOR_SYNC_END_FORMULA(x, y) ((x+y)-1)
80
81#define IGA2_VER_TOTAL_FORMULA(x) ((x)-1)
82#define IGA2_VER_ADDR_FORMULA(x) ((x)-1)
83#define IGA2_VER_BLANK_START_FORMULA(x) ((x)-1)
84#define IGA2_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
85#define IGA2_VER_SYNC_START_FORMULA(x) ((x)-1)
86#define IGA2_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
87
88/**********************************************************/ 54/**********************************************************/
89/* Definition IGA2 Design Method of CRTC Shadow Registers */ 55/* Definition IGA2 Design Method of CRTC Shadow Registers */
90/**********************************************************/ 56/**********************************************************/
@@ -97,33 +63,6 @@
97#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x) 63#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x)
98#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y) 64#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y)
99 65
100/* Define Register Number for IGA1 CRTC Timing */
101
102/* location: {CR00,0,7},{CR36,3,3} */
103#define IGA1_HOR_TOTAL_REG_NUM 2
104/* location: {CR01,0,7} */
105#define IGA1_HOR_ADDR_REG_NUM 1
106/* location: {CR02,0,7} */
107#define IGA1_HOR_BLANK_START_REG_NUM 1
108/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
109#define IGA1_HOR_BLANK_END_REG_NUM 3
110/* location: {CR04,0,7},{CR33,4,4} */
111#define IGA1_HOR_SYNC_START_REG_NUM 2
112/* location: {CR05,0,4} */
113#define IGA1_HOR_SYNC_END_REG_NUM 1
114/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
115#define IGA1_VER_TOTAL_REG_NUM 4
116/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
117#define IGA1_VER_ADDR_REG_NUM 4
118/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
119#define IGA1_VER_BLANK_START_REG_NUM 4
120/* location: {CR16,0,7} */
121#define IGA1_VER_BLANK_END_REG_NUM 1
122/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
123#define IGA1_VER_SYNC_START_REG_NUM 4
124/* location: {CR11,0,3} */
125#define IGA1_VER_SYNC_END_REG_NUM 1
126
127/* Define Register Number for IGA2 Shadow CRTC Timing */ 66/* Define Register Number for IGA2 Shadow CRTC Timing */
128 67
129/* location: {CR6D,0,7},{CR71,3,3} */ 68/* location: {CR6D,0,7},{CR71,3,3} */
@@ -143,37 +82,6 @@
143/* location: {CR76,0,3} */ 82/* location: {CR76,0,3} */
144#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1 83#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1
145 84
146/* Define Register Number for IGA2 CRTC Timing */
147
148/* location: {CR50,0,7},{CR55,0,3} */
149#define IGA2_HOR_TOTAL_REG_NUM 2
150/* location: {CR51,0,7},{CR55,4,6} */
151#define IGA2_HOR_ADDR_REG_NUM 2
152/* location: {CR52,0,7},{CR54,0,2} */
153#define IGA2_HOR_BLANK_START_REG_NUM 2
154/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
155is reserved, so it may have problem to set 1600x1200 on IGA2. */
156/* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
157#define IGA2_HOR_BLANK_END_REG_NUM 3
158/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
159/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
160#define IGA2_HOR_SYNC_START_REG_NUM 4
161
162/* location: {CR57,0,7},{CR5C,6,6} */
163#define IGA2_HOR_SYNC_END_REG_NUM 2
164/* location: {CR58,0,7},{CR5D,0,2} */
165#define IGA2_VER_TOTAL_REG_NUM 2
166/* location: {CR59,0,7},{CR5D,3,5} */
167#define IGA2_VER_ADDR_REG_NUM 2
168/* location: {CR5A,0,7},{CR5C,0,2} */
169#define IGA2_VER_BLANK_START_REG_NUM 2
170/* location: {CR5E,0,7},{CR5C,3,5} */
171#define IGA2_VER_BLANK_END_REG_NUM 2
172/* location: {CR5E,0,7},{CR5F,5,7} */
173#define IGA2_VER_SYNC_START_REG_NUM 2
174/* location: {CR5F,0,4} */
175#define IGA2_VER_SYNC_END_REG_NUM 1
176
177/* Define Fetch Count Register*/ 85/* Define Fetch Count Register*/
178 86
179/* location: {SR1C,0,7},{SR1D,0,1} */ 87/* location: {SR1C,0,7},{SR1D,0,1} */
@@ -446,87 +354,12 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */
446/* location: {CR78,0,7},{CR79,6,7} */ 354/* location: {CR78,0,7},{CR79,6,7} */
447#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2 355#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2
448 356
449/************************************************
450 ***** Define IGA1 Display Timing *****
451 ************************************************/
452struct io_register { 357struct io_register {
453 u8 io_addr; 358 u8 io_addr;
454 u8 start_bit; 359 u8 start_bit;
455 u8 end_bit; 360 u8 end_bit;
456}; 361};
457 362
458/* IGA1 Horizontal Total */
459struct iga1_hor_total {
460 int reg_num;
461 struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
462};
463
464/* IGA1 Horizontal Addressable Video */
465struct iga1_hor_addr {
466 int reg_num;
467 struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
468};
469
470/* IGA1 Horizontal Blank Start */
471struct iga1_hor_blank_start {
472 int reg_num;
473 struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
474};
475
476/* IGA1 Horizontal Blank End */
477struct iga1_hor_blank_end {
478 int reg_num;
479 struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
480};
481
482/* IGA1 Horizontal Sync Start */
483struct iga1_hor_sync_start {
484 int reg_num;
485 struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
486};
487
488/* IGA1 Horizontal Sync End */
489struct iga1_hor_sync_end {
490 int reg_num;
491 struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
492};
493
494/* IGA1 Vertical Total */
495struct iga1_ver_total {
496 int reg_num;
497 struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
498};
499
500/* IGA1 Vertical Addressable Video */
501struct iga1_ver_addr {
502 int reg_num;
503 struct io_register reg[IGA1_VER_ADDR_REG_NUM];
504};
505
506/* IGA1 Vertical Blank Start */
507struct iga1_ver_blank_start {
508 int reg_num;
509 struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
510};
511
512/* IGA1 Vertical Blank End */
513struct iga1_ver_blank_end {
514 int reg_num;
515 struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
516};
517
518/* IGA1 Vertical Sync Start */
519struct iga1_ver_sync_start {
520 int reg_num;
521 struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
522};
523
524/* IGA1 Vertical Sync End */
525struct iga1_ver_sync_end {
526 int reg_num;
527 struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
528};
529
530/***************************************************** 363/*****************************************************
531** Define IGA2 Shadow Display Timing **** 364** Define IGA2 Shadow Display Timing ****
532*****************************************************/ 365*****************************************************/
@@ -579,82 +412,6 @@ struct iga2_shadow_ver_sync_end {
579 struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM]; 412 struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
580}; 413};
581 414
582/*****************************************************
583** Define IGA2 Display Timing ****
584******************************************************/
585
586/* IGA2 Horizontal Total */
587struct iga2_hor_total {
588 int reg_num;
589 struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
590};
591
592/* IGA2 Horizontal Addressable Video */
593struct iga2_hor_addr {
594 int reg_num;
595 struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
596};
597
598/* IGA2 Horizontal Blank Start */
599struct iga2_hor_blank_start {
600 int reg_num;
601 struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
602};
603
604/* IGA2 Horizontal Blank End */
605struct iga2_hor_blank_end {
606 int reg_num;
607 struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
608};
609
610/* IGA2 Horizontal Sync Start */
611struct iga2_hor_sync_start {
612 int reg_num;
613 struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
614};
615
616/* IGA2 Horizontal Sync End */
617struct iga2_hor_sync_end {
618 int reg_num;
619 struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
620};
621
622/* IGA2 Vertical Total */
623struct iga2_ver_total {
624 int reg_num;
625 struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
626};
627
628/* IGA2 Vertical Addressable Video */
629struct iga2_ver_addr {
630 int reg_num;
631 struct io_register reg[IGA2_VER_ADDR_REG_NUM];
632};
633
634/* IGA2 Vertical Blank Start */
635struct iga2_ver_blank_start {
636 int reg_num;
637 struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
638};
639
640/* IGA2 Vertical Blank End */
641struct iga2_ver_blank_end {
642 int reg_num;
643 struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
644};
645
646/* IGA2 Vertical Sync Start */
647struct iga2_ver_sync_start {
648 int reg_num;
649 struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
650};
651
652/* IGA2 Vertical Sync End */
653struct iga2_ver_sync_end {
654 int reg_num;
655 struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
656};
657
658/* IGA1 Fetch Count Register */ 415/* IGA1 Fetch Count Register */
659struct iga1_fetch_count { 416struct iga1_fetch_count {
660 int reg_num; 417 int reg_num;
@@ -817,21 +574,6 @@ struct display_queue_expire_num {
817 iga2_display_queue_expire_num_reg; 574 iga2_display_queue_expire_num_reg;
818}; 575};
819 576
820struct iga1_crtc_timing {
821 struct iga1_hor_total hor_total;
822 struct iga1_hor_addr hor_addr;
823 struct iga1_hor_blank_start hor_blank_start;
824 struct iga1_hor_blank_end hor_blank_end;
825 struct iga1_hor_sync_start hor_sync_start;
826 struct iga1_hor_sync_end hor_sync_end;
827 struct iga1_ver_total ver_total;
828 struct iga1_ver_addr ver_addr;
829 struct iga1_ver_blank_start ver_blank_start;
830 struct iga1_ver_blank_end ver_blank_end;
831 struct iga1_ver_sync_start ver_sync_start;
832 struct iga1_ver_sync_end ver_sync_end;
833};
834
835struct iga2_shadow_crtc_timing { 577struct iga2_shadow_crtc_timing {
836 struct iga2_shadow_hor_total hor_total_shadow; 578 struct iga2_shadow_hor_total hor_total_shadow;
837 struct iga2_shadow_hor_blank_end hor_blank_end_shadow; 579 struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
@@ -843,21 +585,6 @@ struct iga2_shadow_crtc_timing {
843 struct iga2_shadow_ver_sync_end ver_sync_end_shadow; 585 struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
844}; 586};
845 587
846struct iga2_crtc_timing {
847 struct iga2_hor_total hor_total;
848 struct iga2_hor_addr hor_addr;
849 struct iga2_hor_blank_start hor_blank_start;
850 struct iga2_hor_blank_end hor_blank_end;
851 struct iga2_hor_sync_start hor_sync_start;
852 struct iga2_hor_sync_end hor_sync_end;
853 struct iga2_ver_total ver_total;
854 struct iga2_ver_addr ver_addr;
855 struct iga2_ver_blank_start ver_blank_start;
856 struct iga2_ver_blank_end ver_blank_end;
857 struct iga2_ver_sync_start ver_sync_start;
858 struct iga2_ver_sync_end ver_sync_end;
859};
860
861/* device ID */ 588/* device ID */
862#define CLE266_FUNCTION3 0x3123 589#define CLE266_FUNCTION3 0x3123
863#define KM400_FUNCTION3 0x3205 590#define KM400_FUNCTION3 0x3205
@@ -910,9 +637,7 @@ extern int viafb_LCD_ON;
910extern int viafb_DVI_ON; 637extern int viafb_DVI_ON;
911extern int viafb_hotplug; 638extern int viafb_hotplug;
912 639
913void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, 640void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga);
914 struct VideoModeTable *video_mode, int bpp_byte, int set_iga);
915
916void viafb_set_vclock(u32 CLK, int set_iga); 641void viafb_set_vclock(u32 CLK, int set_iga);
917void viafb_load_reg(int timing_value, int viafb_load_reg_num, 642void viafb_load_reg(int timing_value, int viafb_load_reg_num,
918 struct io_register *reg, 643 struct io_register *reg,
@@ -932,13 +657,11 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
932void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 657void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
933 *p_gfx_dpa_setting); 658 *p_gfx_dpa_setting);
934 659
935int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, 660int viafb_setmode(int video_bpp, int video_bpp1);
936 struct VideoModeTable *vmode_tbl1, int video_bpp1); 661void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
937void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 662 struct crt_mode_table *mode);
938 struct VideoModeTable *vmode_tbl);
939void __devinit viafb_init_chip_info(int chip_type); 663void __devinit viafb_init_chip_info(int chip_type);
940void __devinit viafb_init_dac(int set_iga); 664void __devinit viafb_init_dac(int set_iga);
941int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
942int viafb_get_refresh(int hres, int vres, u32 float_refresh); 665int viafb_get_refresh(int hres, int vres, u32 float_refresh);
943void viafb_update_device_setting(int hres, int vres, int bpp, int flag); 666void viafb_update_device_setting(int hres, int vres, int bpp, int flag);
944 667
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 6e06981d638b..5f3b4e394e82 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -548,9 +548,8 @@ static void lcd_patch_skew(struct lvds_setting_information
548} 548}
549 549
550/* LCD Set Mode */ 550/* LCD Set Mode */
551void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, 551void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
552 struct lvds_setting_information *plvds_setting_info, 552 struct lvds_chip_information *plvds_chip_info)
553 struct lvds_chip_information *plvds_chip_info)
554{ 553{
555 int set_iga = plvds_setting_info->iga_path; 554 int set_iga = plvds_setting_info->iga_path;
556 int mode_bpp = plvds_setting_info->bpp; 555 int mode_bpp = plvds_setting_info->bpp;
@@ -559,16 +558,15 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
559 int panel_hres = plvds_setting_info->lcd_panel_hres; 558 int panel_hres = plvds_setting_info->lcd_panel_hres;
560 int panel_vres = plvds_setting_info->lcd_panel_vres; 559 int panel_vres = plvds_setting_info->lcd_panel_vres;
561 u32 clock; 560 u32 clock;
562 struct display_timing mode_crt_reg, panel_crt_reg; 561 struct display_timing mode_crt_reg, panel_crt_reg, timing;
563 struct crt_mode_table *panel_crt_table = NULL; 562 struct crt_mode_table *mode_crt_table, *panel_crt_table;
564 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres,
565 panel_vres);
566 563
567 DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n"); 564 DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
568 /* Get mode table */ 565 /* Get mode table */
566 mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60);
569 mode_crt_reg = mode_crt_table->crtc; 567 mode_crt_reg = mode_crt_table->crtc;
570 /* Get panel table Pointer */ 568 /* Get panel table Pointer */
571 panel_crt_table = vmode_tbl->crtc; 569 panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60);
572 panel_crt_reg = panel_crt_table->crtc; 570 panel_crt_reg = panel_crt_table->crtc;
573 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n"); 571 DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
574 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) 572 if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
@@ -576,31 +574,28 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
576 clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total 574 clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total
577 * panel_crt_table->refresh_rate; 575 * panel_crt_table->refresh_rate;
578 plvds_setting_info->vclk = clock; 576 plvds_setting_info->vclk = clock;
579 if (set_iga == IGA1) { 577
580 /* IGA1 doesn't have LCD scaling, so set it as centering. */ 578 if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
581 viafb_load_crtc_timing(lcd_centering_timging 579 && plvds_setting_info->display_method == LCD_EXPANDSION) {
582 (mode_crt_reg, panel_crt_reg), IGA1); 580 timing = panel_crt_reg;
581 load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
583 } else { 582 } else {
584 /* Expansion */ 583 timing = lcd_centering_timging(mode_crt_reg, panel_crt_reg);
585 if (plvds_setting_info->display_method == LCD_EXPANDSION 584 if (set_iga == IGA2)
586 && (set_hres < panel_hres || set_vres < panel_vres)) { 585 /* disable scaling */
587 /* expansion timing IGA2 loaded panel set timing*/ 586 via_write_reg_mask(VIACR, 0x79, 0x00,
588 viafb_load_crtc_timing(panel_crt_reg, IGA2);
589 DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
590 load_lcd_scaling(set_hres, set_vres, panel_hres,
591 panel_vres);
592 DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
593 } else { /* Centering */
594 /* centering timing IGA2 always loaded panel
595 and mode releative timing */
596 viafb_load_crtc_timing(lcd_centering_timging
597 (mode_crt_reg, panel_crt_reg), IGA2);
598 viafb_write_reg_mask(CR79, VIACR, 0x00,
599 BIT0 + BIT1 + BIT2); 587 BIT0 + BIT1 + BIT2);
600 /* LCD scaling disabled */
601 }
602 } 588 }
603 589
590 timing.hor_blank_end += timing.hor_blank_start;
591 timing.hor_sync_end += timing.hor_sync_start;
592 timing.ver_blank_end += timing.ver_blank_start;
593 timing.ver_sync_end += timing.ver_sync_start;
594 if (set_iga == IGA1)
595 via_set_primary_timing(&timing);
596 else if (set_iga == IGA2)
597 via_set_secondary_timing(&timing);
598
604 /* Fetch count for IGA2 only */ 599 /* Fetch count for IGA2 only */
605 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga); 600 viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
606 601
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 75f60a655b0e..77ca7b862e68 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -76,16 +76,13 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
76 *plvds_chip_info, 76 *plvds_chip_info,
77 struct lvds_setting_information 77 struct lvds_setting_information
78 *plvds_setting_info); 78 *plvds_setting_info);
79void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, 79void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
80 struct lvds_setting_information *plvds_setting_info, 80 struct lvds_chip_information *plvds_chip_info);
81 struct lvds_chip_information *plvds_chip_info);
82bool __devinit viafb_lvds_trasmitter_identify(void); 81bool __devinit viafb_lvds_trasmitter_identify(void);
83void viafb_init_lvds_output_interface(struct lvds_chip_information 82void viafb_init_lvds_output_interface(struct lvds_chip_information
84 *plvds_chip_info, 83 *plvds_chip_info,
85 struct lvds_setting_information 84 struct lvds_setting_information
86 *plvds_setting_info); 85 *plvds_setting_info);
87bool viafb_lcd_get_mobile_state(bool *mobile); 86bool viafb_lcd_get_mobile_state(bool *mobile);
88void viafb_load_crtc_timing(struct display_timing device_timing,
89 int set_iga);
90 87
91#endif /* __LCD_H__ */ 88#endif /* __LCD_H__ */
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index 61b0bd596b85..69d882cbe709 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -22,6 +22,8 @@
22#ifndef __SHARE_H__ 22#ifndef __SHARE_H__
23#define __SHARE_H__ 23#define __SHARE_H__
24 24
25#include "via_modesetting.h"
26
25/* Define Bit Field */ 27/* Define Bit Field */
26#define BIT0 0x01 28#define BIT0 0x01
27#define BIT1 0x02 29#define BIT1 0x02
@@ -634,10 +636,6 @@
634#define V_SYNC_SATRT_SHADOW_INDEX 18 636#define V_SYNC_SATRT_SHADOW_INDEX 18
635#define V_SYNC_END_SHADOW_INDEX 19 637#define V_SYNC_END_SHADOW_INDEX 19
636 638
637/* Definition Video Mode Pixel Clock (picoseconds)
638*/
639#define RES_640X480_60HZ_PIXCLOCK 39722
640
641/* LCD display method 639/* LCD display method
642*/ 640*/
643#define LCD_EXPANDSION 0x00 641#define LCD_EXPANDSION 0x00
@@ -648,23 +646,6 @@
648#define LCD_OPENLDI 0x00 646#define LCD_OPENLDI 0x00
649#define LCD_SPWG 0x01 647#define LCD_SPWG 0x01
650 648
651/* Define display timing
652*/
653struct display_timing {
654 u16 hor_total;
655 u16 hor_addr;
656 u16 hor_blank_start;
657 u16 hor_blank_end;
658 u16 hor_sync_start;
659 u16 hor_sync_end;
660 u16 ver_total;
661 u16 ver_addr;
662 u16 ver_blank_start;
663 u16 ver_blank_end;
664 u16 ver_sync_start;
665 u16 ver_sync_end;
666};
667
668struct crt_mode_table { 649struct crt_mode_table {
669 int refresh_rate; 650 int refresh_rate;
670 int h_sync_polarity; 651 int h_sync_polarity;
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
index eb112b621735..dd58b530c0df 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/via/via-core.c
@@ -35,7 +35,7 @@ static struct via_port_cfg adap_configs[] = {
35 * The OLPC XO-1.5 puts the camera power and reset lines onto 35 * The OLPC XO-1.5 puts the camera power and reset lines onto
36 * GPIO 2C. 36 * GPIO 2C.
37 */ 37 */
38static const struct via_port_cfg olpc_adap_configs[] = { 38static struct via_port_cfg olpc_adap_configs[] = {
39 [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 }, 39 [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x26 },
40 [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, 40 [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 },
41 [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, 41 [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c
index 3cddcff88ab9..0e431aee17bb 100644
--- a/drivers/video/via/via_modesetting.c
+++ b/drivers/video/via/via_modesetting.c
@@ -29,6 +29,110 @@
29#include "share.h" 29#include "share.h"
30#include "debug.h" 30#include "debug.h"
31 31
32
33void via_set_primary_timing(const struct display_timing *timing)
34{
35 struct display_timing raw;
36
37 raw.hor_total = timing->hor_total / 8 - 5;
38 raw.hor_addr = timing->hor_addr / 8 - 1;
39 raw.hor_blank_start = timing->hor_blank_start / 8 - 1;
40 raw.hor_blank_end = timing->hor_blank_end / 8 - 1;
41 raw.hor_sync_start = timing->hor_sync_start / 8;
42 raw.hor_sync_end = timing->hor_sync_end / 8;
43 raw.ver_total = timing->ver_total - 2;
44 raw.ver_addr = timing->ver_addr - 1;
45 raw.ver_blank_start = timing->ver_blank_start - 1;
46 raw.ver_blank_end = timing->ver_blank_end - 1;
47 raw.ver_sync_start = timing->ver_sync_start - 1;
48 raw.ver_sync_end = timing->ver_sync_end - 1;
49
50 /* unlock timing registers */
51 via_write_reg_mask(VIACR, 0x11, 0x00, 0x80);
52
53 via_write_reg(VIACR, 0x00, raw.hor_total & 0xFF);
54 via_write_reg(VIACR, 0x01, raw.hor_addr & 0xFF);
55 via_write_reg(VIACR, 0x02, raw.hor_blank_start & 0xFF);
56 via_write_reg_mask(VIACR, 0x03, raw.hor_blank_end & 0x1F, 0x1F);
57 via_write_reg(VIACR, 0x04, raw.hor_sync_start & 0xFF);
58 via_write_reg_mask(VIACR, 0x05, (raw.hor_sync_end & 0x1F)
59 | (raw.hor_blank_end << (7 - 5) & 0x80), 0x9F);
60 via_write_reg(VIACR, 0x06, raw.ver_total & 0xFF);
61 via_write_reg_mask(VIACR, 0x07, (raw.ver_total >> 8 & 0x01)
62 | (raw.ver_addr >> (8 - 1) & 0x02)
63 | (raw.ver_sync_start >> (8 - 2) & 0x04)
64 | (raw.ver_blank_start >> (8 - 3) & 0x08)
65 | (raw.ver_total >> (9 - 5) & 0x20)
66 | (raw.ver_addr >> (9 - 6) & 0x40)
67 | (raw.ver_sync_start >> (9 - 7) & 0x80), 0xEF);
68 via_write_reg_mask(VIACR, 0x09, raw.ver_blank_start >> (9 - 5) & 0x20,
69 0x20);
70 via_write_reg(VIACR, 0x10, raw.ver_sync_start & 0xFF);
71 via_write_reg_mask(VIACR, 0x11, raw.ver_sync_end & 0x0F, 0x0F);
72 via_write_reg(VIACR, 0x12, raw.ver_addr & 0xFF);
73 via_write_reg(VIACR, 0x15, raw.ver_blank_start & 0xFF);
74 via_write_reg(VIACR, 0x16, raw.ver_blank_end & 0xFF);
75 via_write_reg_mask(VIACR, 0x33, (raw.hor_sync_start >> (8 - 4) & 0x10)
76 | (raw.hor_blank_end >> (6 - 5) & 0x20), 0x30);
77 via_write_reg_mask(VIACR, 0x35, (raw.ver_total >> 10 & 0x01)
78 | (raw.ver_sync_start >> (10 - 1) & 0x02)
79 | (raw.ver_addr >> (10 - 2) & 0x04)
80 | (raw.ver_blank_start >> (10 - 3) & 0x08), 0x0F);
81 via_write_reg_mask(VIACR, 0x36, raw.hor_total >> (8 - 3) & 0x08, 0x08);
82
83 /* lock timing registers */
84 via_write_reg_mask(VIACR, 0x11, 0x80, 0x80);
85
86 /* reset timing control */
87 via_write_reg_mask(VIACR, 0x17, 0x00, 0x80);
88 via_write_reg_mask(VIACR, 0x17, 0x80, 0x80);
89}
90
91void via_set_secondary_timing(const struct display_timing *timing)
92{
93 struct display_timing raw;
94
95 raw.hor_total = timing->hor_total - 1;
96 raw.hor_addr = timing->hor_addr - 1;
97 raw.hor_blank_start = timing->hor_blank_start - 1;
98 raw.hor_blank_end = timing->hor_blank_end - 1;
99 raw.hor_sync_start = timing->hor_sync_start - 1;
100 raw.hor_sync_end = timing->hor_sync_end - 1;
101 raw.ver_total = timing->ver_total - 1;
102 raw.ver_addr = timing->ver_addr - 1;
103 raw.ver_blank_start = timing->ver_blank_start - 1;
104 raw.ver_blank_end = timing->ver_blank_end - 1;
105 raw.ver_sync_start = timing->ver_sync_start - 1;
106 raw.ver_sync_end = timing->ver_sync_end - 1;
107
108 via_write_reg(VIACR, 0x50, raw.hor_total & 0xFF);
109 via_write_reg(VIACR, 0x51, raw.hor_addr & 0xFF);
110 via_write_reg(VIACR, 0x52, raw.hor_blank_start & 0xFF);
111 via_write_reg(VIACR, 0x53, raw.hor_blank_end & 0xFF);
112 via_write_reg(VIACR, 0x54, (raw.hor_blank_start >> 8 & 0x07)
113 | (raw.hor_blank_end >> (8 - 3) & 0x38)
114 | (raw.hor_sync_start >> (8 - 6) & 0xC0));
115 via_write_reg_mask(VIACR, 0x55, (raw.hor_total >> 8 & 0x0F)
116 | (raw.hor_addr >> (8 - 4) & 0x70), 0x7F);
117 via_write_reg(VIACR, 0x56, raw.hor_sync_start & 0xFF);
118 via_write_reg(VIACR, 0x57, raw.hor_sync_end & 0xFF);
119 via_write_reg(VIACR, 0x58, raw.ver_total & 0xFF);
120 via_write_reg(VIACR, 0x59, raw.ver_addr & 0xFF);
121 via_write_reg(VIACR, 0x5A, raw.ver_blank_start & 0xFF);
122 via_write_reg(VIACR, 0x5B, raw.ver_blank_end & 0xFF);
123 via_write_reg(VIACR, 0x5C, (raw.ver_blank_start >> 8 & 0x07)
124 | (raw.ver_blank_end >> (8 - 3) & 0x38)
125 | (raw.hor_sync_end >> (8 - 6) & 0x40)
126 | (raw.hor_sync_start >> (10 - 7) & 0x80));
127 via_write_reg(VIACR, 0x5D, (raw.ver_total >> 8 & 0x07)
128 | (raw.ver_addr >> (8 - 3) & 0x38)
129 | (raw.hor_blank_end >> (11 - 6) & 0x40)
130 | (raw.hor_sync_start >> (11 - 7) & 0x80));
131 via_write_reg(VIACR, 0x5E, raw.ver_sync_start & 0xFF);
132 via_write_reg(VIACR, 0x5F, (raw.ver_sync_end & 0x1F)
133 | (raw.ver_sync_start >> (8 - 5) & 0xE0));
134}
135
32void via_set_primary_address(u32 addr) 136void via_set_primary_address(u32 addr)
33{ 137{
34 DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr); 138 DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/via/via_modesetting.h
index 013884543e91..06e09fe351ae 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/via/via_modesetting.h
@@ -33,6 +33,24 @@
33#define VIA_PITCH_MAX 0x3FF8 33#define VIA_PITCH_MAX 0x3FF8
34 34
35 35
36struct display_timing {
37 u16 hor_total;
38 u16 hor_addr;
39 u16 hor_blank_start;
40 u16 hor_blank_end;
41 u16 hor_sync_start;
42 u16 hor_sync_end;
43 u16 ver_total;
44 u16 ver_addr;
45 u16 ver_blank_start;
46 u16 ver_blank_end;
47 u16 ver_sync_start;
48 u16 ver_sync_end;
49};
50
51
52void via_set_primary_timing(const struct display_timing *timing);
53void via_set_secondary_timing(const struct display_timing *timing);
36void via_set_primary_address(u32 addr); 54void via_set_primary_address(u32 addr);
37void via_set_secondary_address(u32 addr); 55void via_set_secondary_address(u32 addr);
38void via_set_primary_pitch(u32 pitch); 56void via_set_primary_pitch(u32 pitch);
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 09fa57cea844..a13c258bd32f 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -38,8 +38,6 @@ static char *viafb_mode1;
38static int viafb_bpp = 32; 38static int viafb_bpp = 32;
39static int viafb_bpp1 = 32; 39static int viafb_bpp1 = 32;
40 40
41static unsigned int viafb_second_xres = 640;
42static unsigned int viafb_second_yres = 480;
43static unsigned int viafb_second_offset; 41static unsigned int viafb_second_offset;
44static int viafb_second_size; 42static int viafb_second_size;
45 43
@@ -201,7 +199,6 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
201 struct fb_info *info) 199 struct fb_info *info)
202{ 200{
203 int depth, refresh; 201 int depth, refresh;
204 struct VideoModeTable *vmode_entry;
205 struct viafb_par *ppar = info->par; 202 struct viafb_par *ppar = info->par;
206 u32 line; 203 u32 line;
207 204
@@ -211,8 +208,10 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
211 if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE) 208 if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
212 return -EINVAL; 209 return -EINVAL;
213 210
214 vmode_entry = viafb_get_mode(var->xres, var->yres); 211 /* the refresh rate is not important here, as we only want to know
215 if (!vmode_entry) { 212 * whether the resolution exists
213 */
214 if (!viafb_get_best_mode(var->xres, var->yres, 60)) {
216 DEBUG_MSG(KERN_INFO 215 DEBUG_MSG(KERN_INFO
217 "viafb: Mode %dx%dx%d not supported!!\n", 216 "viafb: Mode %dx%dx%d not supported!!\n",
218 var->xres, var->yres, var->bits_per_pixel); 217 var->xres, var->yres, var->bits_per_pixel);
@@ -254,7 +253,8 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
254 get_var_refresh(var)); 253 get_var_refresh(var));
255 254
256 /* Adjust var according to our driver's own table */ 255 /* Adjust var according to our driver's own table */
257 viafb_fill_var_timing_info(var, refresh, vmode_entry); 256 viafb_fill_var_timing_info(var,
257 viafb_get_best_mode(var->xres, var->yres, refresh));
258 if (var->accel_flags & FB_ACCELF_TEXT && 258 if (var->accel_flags & FB_ACCELF_TEXT &&
259 !ppar->shared->vdev->engine_mmio) 259 !ppar->shared->vdev->engine_mmio)
260 var->accel_flags = 0; 260 var->accel_flags = 0;
@@ -265,7 +265,6 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
265static int viafb_set_par(struct fb_info *info) 265static int viafb_set_par(struct fb_info *info)
266{ 266{
267 struct viafb_par *viapar = info->par; 267 struct viafb_par *viapar = info->par;
268 struct VideoModeTable *vmode_entry, *vmode_entry1 = NULL;
269 int refresh; 268 int refresh;
270 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 269 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
271 270
@@ -274,10 +273,7 @@ static int viafb_set_par(struct fb_info *info)
274 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres, 273 viafb_update_device_setting(viafbinfo->var.xres, viafbinfo->var.yres,
275 viafbinfo->var.bits_per_pixel, 0); 274 viafbinfo->var.bits_per_pixel, 0);
276 275
277 vmode_entry = viafb_get_mode(viafbinfo->var.xres, viafbinfo->var.yres);
278 if (viafb_dual_fb) { 276 if (viafb_dual_fb) {
279 vmode_entry1 = viafb_get_mode(viafbinfo1->var.xres,
280 viafbinfo1->var.yres);
281 viafb_update_device_setting(viafbinfo1->var.xres, 277 viafb_update_device_setting(viafbinfo1->var.xres,
282 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel, 278 viafbinfo1->var.yres, viafbinfo1->var.bits_per_pixel,
283 1); 279 1);
@@ -285,8 +281,6 @@ static int viafb_set_par(struct fb_info *info)
285 DEBUG_MSG(KERN_INFO 281 DEBUG_MSG(KERN_INFO
286 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n", 282 "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
287 viafb_second_xres, viafb_second_yres, viafb_bpp1); 283 viafb_second_xres, viafb_second_yres, viafb_bpp1);
288 vmode_entry1 = viafb_get_mode(viafb_second_xres,
289 viafb_second_yres);
290 284
291 viafb_update_device_setting(viafb_second_xres, 285 viafb_update_device_setting(viafb_second_xres,
292 viafb_second_yres, viafb_bpp1, 1); 286 viafb_second_yres, viafb_bpp1, 1);
@@ -294,7 +288,8 @@ static int viafb_set_par(struct fb_info *info)
294 288
295 refresh = viafb_get_refresh(info->var.xres, info->var.yres, 289 refresh = viafb_get_refresh(info->var.xres, info->var.yres,
296 get_var_refresh(&info->var)); 290 get_var_refresh(&info->var));
297 if (vmode_entry) { 291 if (viafb_get_best_mode(viafbinfo->var.xres, viafbinfo->var.yres,
292 refresh)) {
298 if (viafb_dual_fb && viapar->iga_path == IGA2) { 293 if (viafb_dual_fb && viapar->iga_path == IGA2) {
299 viafb_bpp1 = info->var.bits_per_pixel; 294 viafb_bpp1 = info->var.bits_per_pixel;
300 viafb_refresh1 = refresh; 295 viafb_refresh1 = refresh;
@@ -307,8 +302,7 @@ static int viafb_set_par(struct fb_info *info)
307 info->flags &= ~FBINFO_HWACCEL_DISABLED; 302 info->flags &= ~FBINFO_HWACCEL_DISABLED;
308 else 303 else
309 info->flags |= FBINFO_HWACCEL_DISABLED; 304 info->flags |= FBINFO_HWACCEL_DISABLED;
310 viafb_setmode(vmode_entry, info->var.bits_per_pixel, 305 viafb_setmode(info->var.bits_per_pixel, viafb_bpp1);
311 vmode_entry1, viafb_bpp1);
312 viafb_pan_display(&info->var, info); 306 viafb_pan_display(&info->var, info);
313 } 307 }
314 308
@@ -1164,7 +1158,8 @@ static ssize_t viafb_dvp0_proc_write(struct file *file,
1164 for (i = 0; i < 3; i++) { 1158 for (i = 0; i < 3; i++) {
1165 value = strsep(&pbuf, " "); 1159 value = strsep(&pbuf, " ");
1166 if (value != NULL) { 1160 if (value != NULL) {
1167 strict_strtoul(value, 0, (unsigned long *)&reg_val); 1161 if (kstrtou8(value, 0, &reg_val) < 0)
1162 return -EINVAL;
1168 DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i, 1163 DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
1169 reg_val); 1164 reg_val);
1170 switch (i) { 1165 switch (i) {
@@ -1234,7 +1229,8 @@ static ssize_t viafb_dvp1_proc_write(struct file *file,
1234 for (i = 0; i < 3; i++) { 1229 for (i = 0; i < 3; i++) {
1235 value = strsep(&pbuf, " "); 1230 value = strsep(&pbuf, " ");
1236 if (value != NULL) { 1231 if (value != NULL) {
1237 strict_strtoul(value, 0, (unsigned long *)&reg_val); 1232 if (kstrtou8(value, 0, &reg_val) < 0)
1233 return -EINVAL;
1238 switch (i) { 1234 switch (i) {
1239 case 0: 1235 case 0:
1240 viafb_write_reg_mask(CR9B, VIACR, 1236 viafb_write_reg_mask(CR9B, VIACR,
@@ -1292,7 +1288,8 @@ static ssize_t viafb_dfph_proc_write(struct file *file,
1292 if (copy_from_user(&buf[0], buffer, length)) 1288 if (copy_from_user(&buf[0], buffer, length))
1293 return -EFAULT; 1289 return -EFAULT;
1294 buf[length - 1] = '\0'; /*Ensure end string */ 1290 buf[length - 1] = '\0'; /*Ensure end string */
1295 strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val); 1291 if (kstrtou8(buf, 0, &reg_val) < 0)
1292 return -EINVAL;
1296 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f); 1293 viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
1297 return count; 1294 return count;
1298} 1295}
@@ -1331,7 +1328,8 @@ static ssize_t viafb_dfpl_proc_write(struct file *file,
1331 if (copy_from_user(&buf[0], buffer, length)) 1328 if (copy_from_user(&buf[0], buffer, length))
1332 return -EFAULT; 1329 return -EFAULT;
1333 buf[length - 1] = '\0'; /*Ensure end string */ 1330 buf[length - 1] = '\0'; /*Ensure end string */
1334 strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val); 1331 if (kstrtou8(buf, 0, &reg_val) < 0)
1332 return -EINVAL;
1335 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f); 1333 viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
1336 return count; 1334 return count;
1337} 1335}
@@ -1400,8 +1398,8 @@ static ssize_t viafb_vt1636_proc_write(struct file *file,
1400 for (i = 0; i < 2; i++) { 1398 for (i = 0; i < 2; i++) {
1401 value = strsep(&pbuf, " "); 1399 value = strsep(&pbuf, " ");
1402 if (value != NULL) { 1400 if (value != NULL) {
1403 strict_strtoul(value, 0, 1401 if (kstrtou8(value, 0, &reg_val.Data) < 0)
1404 (unsigned long *)&reg_val.Data); 1402 return -EINVAL;
1405 switch (i) { 1403 switch (i) {
1406 case 0: 1404 case 0:
1407 reg_val.Index = 0x08; 1405 reg_val.Index = 0x08;
@@ -1437,8 +1435,8 @@ static ssize_t viafb_vt1636_proc_write(struct file *file,
1437 for (i = 0; i < 2; i++) { 1435 for (i = 0; i < 2; i++) {
1438 value = strsep(&pbuf, " "); 1436 value = strsep(&pbuf, " ");
1439 if (value != NULL) { 1437 if (value != NULL) {
1440 strict_strtoul(value, 0, 1438 if (kstrtou8(value, 0, &reg_val.Data) < 0)
1441 (unsigned long *)&reg_val.Data); 1439 return -EINVAL;
1442 switch (i) { 1440 switch (i) {
1443 case 0: 1441 case 0:
1444 reg_val.Index = 0x08; 1442 reg_val.Index = 0x08;
@@ -1735,7 +1733,6 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
1735int __devinit via_fb_pci_probe(struct viafb_dev *vdev) 1733int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1736{ 1734{
1737 u32 default_xres, default_yres; 1735 u32 default_xres, default_yres;
1738 struct VideoModeTable *vmode_entry;
1739 struct fb_var_screeninfo default_var; 1736 struct fb_var_screeninfo default_var;
1740 int rc; 1737 int rc;
1741 u32 viafb_par_length; 1738 u32 viafb_par_length;
@@ -1808,7 +1805,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1808 } 1805 }
1809 1806
1810 parse_mode(viafb_mode, &default_xres, &default_yres); 1807 parse_mode(viafb_mode, &default_xres, &default_yres);
1811 vmode_entry = viafb_get_mode(default_xres, default_yres);
1812 if (viafb_SAMM_ON == 1) 1808 if (viafb_SAMM_ON == 1)
1813 parse_mode(viafb_mode1, &viafb_second_xres, 1809 parse_mode(viafb_mode1, &viafb_second_xres,
1814 &viafb_second_yres); 1810 &viafb_second_yres);
@@ -1818,9 +1814,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1818 default_var.xres_virtual = default_xres; 1814 default_var.xres_virtual = default_xres;
1819 default_var.yres_virtual = default_yres; 1815 default_var.yres_virtual = default_yres;
1820 default_var.bits_per_pixel = viafb_bpp; 1816 default_var.bits_per_pixel = viafb_bpp;
1821 viafb_fill_var_timing_info(&default_var, viafb_get_refresh( 1817 viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
1822 default_var.xres, default_var.yres, viafb_refresh), 1818 default_var.xres, default_var.yres, viafb_refresh));
1823 viafb_get_mode(default_var.xres, default_var.yres));
1824 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 1819 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
1825 viafbinfo->var = default_var; 1820 viafbinfo->var = default_var;
1826 1821
@@ -1859,9 +1854,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1859 default_var.xres_virtual = viafb_second_xres; 1854 default_var.xres_virtual = viafb_second_xres;
1860 default_var.yres_virtual = viafb_second_yres; 1855 default_var.yres_virtual = viafb_second_yres;
1861 default_var.bits_per_pixel = viafb_bpp1; 1856 default_var.bits_per_pixel = viafb_bpp1;
1862 viafb_fill_var_timing_info(&default_var, viafb_get_refresh( 1857 viafb_fill_var_timing_info(&default_var, viafb_get_best_mode(
1863 default_var.xres, default_var.yres, viafb_refresh1), 1858 default_var.xres, default_var.yres, viafb_refresh1));
1864 viafb_get_mode(default_var.xres, default_var.yres));
1865 1859
1866 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1); 1860 viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
1867 viafb_check_var(&default_var, viafbinfo1); 1861 viafb_check_var(&default_var, viafbinfo1);
@@ -1956,61 +1950,67 @@ static int __init viafb_setup(void)
1956 if (!*this_opt) 1950 if (!*this_opt)
1957 continue; 1951 continue;
1958 1952
1959 if (!strncmp(this_opt, "viafb_mode1=", 12)) 1953 if (!strncmp(this_opt, "viafb_mode1=", 12)) {
1960 viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL); 1954 viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
1961 else if (!strncmp(this_opt, "viafb_mode=", 11)) 1955 } else if (!strncmp(this_opt, "viafb_mode=", 11)) {
1962 viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL); 1956 viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL);
1963 else if (!strncmp(this_opt, "viafb_bpp1=", 11)) 1957 } else if (!strncmp(this_opt, "viafb_bpp1=", 11)) {
1964 strict_strtoul(this_opt + 11, 0, 1958 if (kstrtouint(this_opt + 11, 0, &viafb_bpp1) < 0)
1965 (unsigned long *)&viafb_bpp1); 1959 return -EINVAL;
1966 else if (!strncmp(this_opt, "viafb_bpp=", 10)) 1960 } else if (!strncmp(this_opt, "viafb_bpp=", 10)) {
1967 strict_strtoul(this_opt + 10, 0, 1961 if (kstrtouint(this_opt + 10, 0, &viafb_bpp) < 0)
1968 (unsigned long *)&viafb_bpp); 1962 return -EINVAL;
1969 else if (!strncmp(this_opt, "viafb_refresh1=", 15)) 1963 } else if (!strncmp(this_opt, "viafb_refresh1=", 15)) {
1970 strict_strtoul(this_opt + 15, 0, 1964 if (kstrtoint(this_opt + 15, 0, &viafb_refresh1) < 0)
1971 (unsigned long *)&viafb_refresh1); 1965 return -EINVAL;
1972 else if (!strncmp(this_opt, "viafb_refresh=", 14)) 1966 } else if (!strncmp(this_opt, "viafb_refresh=", 14)) {
1973 strict_strtoul(this_opt + 14, 0, 1967 if (kstrtoint(this_opt + 14, 0, &viafb_refresh) < 0)
1974 (unsigned long *)&viafb_refresh); 1968 return -EINVAL;
1975 else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21)) 1969 } else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21)) {
1976 strict_strtoul(this_opt + 21, 0, 1970 if (kstrtoint(this_opt + 21, 0,
1977 (unsigned long *)&viafb_lcd_dsp_method); 1971 &viafb_lcd_dsp_method) < 0)
1978 else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19)) 1972 return -EINVAL;
1979 strict_strtoul(this_opt + 19, 0, 1973 } else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19)) {
1980 (unsigned long *)&viafb_lcd_panel_id); 1974 if (kstrtoint(this_opt + 19, 0,
1981 else if (!strncmp(this_opt, "viafb_accel=", 12)) 1975 &viafb_lcd_panel_id) < 0)
1982 strict_strtoul(this_opt + 12, 0, 1976 return -EINVAL;
1983 (unsigned long *)&viafb_accel); 1977 } else if (!strncmp(this_opt, "viafb_accel=", 12)) {
1984 else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14)) 1978 if (kstrtoint(this_opt + 12, 0, &viafb_accel) < 0)
1985 strict_strtoul(this_opt + 14, 0, 1979 return -EINVAL;
1986 (unsigned long *)&viafb_SAMM_ON); 1980 } else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14)) {
1987 else if (!strncmp(this_opt, "viafb_active_dev=", 17)) 1981 if (kstrtoint(this_opt + 14, 0, &viafb_SAMM_ON) < 0)
1982 return -EINVAL;
1983 } else if (!strncmp(this_opt, "viafb_active_dev=", 17)) {
1988 viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL); 1984 viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL);
1989 else if (!strncmp(this_opt, 1985 } else if (!strncmp(this_opt,
1990 "viafb_display_hardware_layout=", 30)) 1986 "viafb_display_hardware_layout=", 30)) {
1991 strict_strtoul(this_opt + 30, 0, 1987 if (kstrtoint(this_opt + 30, 0,
1992 (unsigned long *)&viafb_display_hardware_layout); 1988 &viafb_display_hardware_layout) < 0)
1993 else if (!strncmp(this_opt, "viafb_second_size=", 18)) 1989 return -EINVAL;
1994 strict_strtoul(this_opt + 18, 0, 1990 } else if (!strncmp(this_opt, "viafb_second_size=", 18)) {
1995 (unsigned long *)&viafb_second_size); 1991 if (kstrtoint(this_opt + 18, 0, &viafb_second_size) < 0)
1996 else if (!strncmp(this_opt, 1992 return -EINVAL;
1997 "viafb_platform_epia_dvi=", 24)) 1993 } else if (!strncmp(this_opt,
1998 strict_strtoul(this_opt + 24, 0, 1994 "viafb_platform_epia_dvi=", 24)) {
1999 (unsigned long *)&viafb_platform_epia_dvi); 1995 if (kstrtoint(this_opt + 24, 0,
2000 else if (!strncmp(this_opt, 1996 &viafb_platform_epia_dvi) < 0)
2001 "viafb_device_lcd_dualedge=", 26)) 1997 return -EINVAL;
2002 strict_strtoul(this_opt + 26, 0, 1998 } else if (!strncmp(this_opt,
2003 (unsigned long *)&viafb_device_lcd_dualedge); 1999 "viafb_device_lcd_dualedge=", 26)) {
2004 else if (!strncmp(this_opt, "viafb_bus_width=", 16)) 2000 if (kstrtoint(this_opt + 26, 0,
2005 strict_strtoul(this_opt + 16, 0, 2001 &viafb_device_lcd_dualedge) < 0)
2006 (unsigned long *)&viafb_bus_width); 2002 return -EINVAL;
2007 else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) 2003 } else if (!strncmp(this_opt, "viafb_bus_width=", 16)) {
2008 strict_strtoul(this_opt + 15, 0, 2004 if (kstrtoint(this_opt + 16, 0, &viafb_bus_width) < 0)
2009 (unsigned long *)&viafb_lcd_mode); 2005 return -EINVAL;
2010 else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) 2006 } else if (!strncmp(this_opt, "viafb_lcd_mode=", 15)) {
2007 if (kstrtoint(this_opt + 15, 0, &viafb_lcd_mode) < 0)
2008 return -EINVAL;
2009 } else if (!strncmp(this_opt, "viafb_lcd_port=", 15)) {
2011 viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL); 2010 viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
2012 else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) 2011 } else if (!strncmp(this_opt, "viafb_dvi_port=", 15)) {
2013 viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL); 2012 viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL);
2013 }
2014 } 2014 }
2015 return 0; 2015 return 0;
2016} 2016}
@@ -2034,9 +2034,9 @@ int __init viafb_init(void)
2034 return r; 2034 return r;
2035#endif 2035#endif
2036 if (parse_mode(viafb_mode, &dummy_x, &dummy_y) 2036 if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
2037 || !viafb_get_mode(dummy_x, dummy_y) 2037 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
2038 || parse_mode(viafb_mode1, &dummy_x, &dummy_y) 2038 || parse_mode(viafb_mode1, &dummy_x, &dummy_y)
2039 || !viafb_get_mode(dummy_x, dummy_y) 2039 || !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
2040 || viafb_bpp < 0 || viafb_bpp > 32 2040 || viafb_bpp < 0 || viafb_bpp > 32
2041 || viafb_bpp1 < 0 || viafb_bpp1 > 32 2041 || viafb_bpp1 < 0 || viafb_bpp1 > 32
2042 || parse_active_dev()) 2042 || parse_active_dev())
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index 58df74e1417e..0911cac1b2ff 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -281,7 +281,7 @@ static struct crt_mode_table CRTM640x480[] = {
281 /*r_rate,hsp,vsp */ 281 /*r_rate,hsp,vsp */
282 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */ 282 /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
283 {REFRESH_60, M640X480_R60_HSP, M640X480_R60_VSP, 283 {REFRESH_60, M640X480_R60_HSP, M640X480_R60_VSP,
284 {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} }, 284 {800, 640, 640, 160, 656, 96, 525, 480, 480, 45, 490, 2} },
285 {REFRESH_75, M640X480_R75_HSP, M640X480_R75_VSP, 285 {REFRESH_75, M640X480_R75_HSP, M640X480_R75_VSP,
286 {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} }, 286 {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
287 {REFRESH_85, M640X480_R85_HSP, M640X480_R85_VSP, 287 {REFRESH_85, M640X480_R85_HSP, M640X480_R85_VSP,
@@ -863,26 +863,56 @@ int NUM_TOTAL_CLE266_ModeXregs = ARRAY_SIZE(CLE266_ModeXregs);
863int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table); 863int NUM_TOTAL_PATCH_MODE = ARRAY_SIZE(res_patch_table);
864 864
865 865
866struct VideoModeTable *viafb_get_mode(int hres, int vres) 866static struct VideoModeTable *get_modes(struct VideoModeTable *vmt, int n,
867 int hres, int vres)
867{ 868{
868 u32 i; 869 int i;
869 for (i = 0; i < ARRAY_SIZE(viafb_modes); i++) 870
870 if (viafb_modes[i].mode_array && 871 for (i = 0; i < n; i++)
871 viafb_modes[i].crtc[0].crtc.hor_addr == hres && 872 if (vmt[i].mode_array &&
872 viafb_modes[i].crtc[0].crtc.ver_addr == vres) 873 vmt[i].crtc[0].crtc.hor_addr == hres &&
874 vmt[i].crtc[0].crtc.ver_addr == vres)
873 return &viafb_modes[i]; 875 return &viafb_modes[i];
874 876
875 return NULL; 877 return NULL;
876} 878}
877 879
878struct VideoModeTable *viafb_get_rb_mode(int hres, int vres) 880static struct crt_mode_table *get_best_mode(struct VideoModeTable *vmt,
881 int refresh)
879{ 882{
880 u32 i; 883 struct crt_mode_table *best;
881 for (i = 0; i < ARRAY_SIZE(viafb_rb_modes); i++) 884 int i;
882 if (viafb_rb_modes[i].mode_array &&
883 viafb_rb_modes[i].crtc[0].crtc.hor_addr == hres &&
884 viafb_rb_modes[i].crtc[0].crtc.ver_addr == vres)
885 return &viafb_rb_modes[i];
886 885
887 return NULL; 886 if (!vmt)
887 return NULL;
888
889 best = &vmt->crtc[0];
890 for (i = 1; i < vmt->mode_array; i++) {
891 if (abs(vmt->crtc[i].refresh_rate - refresh)
892 < abs(best->refresh_rate - refresh))
893 best = &vmt->crtc[i];
894 }
895
896 return best;
897}
898
899static struct VideoModeTable *viafb_get_mode(int hres, int vres)
900{
901 return get_modes(viafb_modes, ARRAY_SIZE(viafb_modes), hres, vres);
902}
903
904struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh)
905{
906 return get_best_mode(viafb_get_mode(hres, vres), refresh);
907}
908
909static struct VideoModeTable *viafb_get_rb_mode(int hres, int vres)
910{
911 return get_modes(viafb_rb_modes, ARRAY_SIZE(viafb_rb_modes), hres,
912 vres);
913}
914
915struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh)
916{
917 return get_best_mode(viafb_get_rb_mode(hres, vres), refresh);
888} 918}
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
index 3751289eb450..5917a2b00e1b 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/via/viamode.h
@@ -60,7 +60,7 @@ extern struct io_reg PM1024x768[];
60extern struct patch_table res_patch_table[]; 60extern struct patch_table res_patch_table[];
61extern struct VPITTable VPIT; 61extern struct VPITTable VPIT;
62 62
63struct VideoModeTable *viafb_get_mode(int hres, int vres); 63struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh);
64struct VideoModeTable *viafb_get_rb_mode(int hres, int vres); 64struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh);
65 65
66#endif /* __VIAMODE_H__ */ 66#endif /* __VIAMODE_H__ */