Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'viafb-pll' into viafb-next

Conflicts:
drivers/video/via/viamode.c

Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>

+586 -406
+11
drivers/video/Kconfig
··· 1607 1607 correct output device configuration. 1608 1608 Its use is strongly discouraged. 1609 1609 1610 + config FB_VIA_X_COMPATIBILITY 1611 + bool "X server compatibility" 1612 + depends on FB_VIA 1613 + default n 1614 + help 1615 + This option reduces the functionality (power saving, ...) of the 1616 + framebuffer to avoid negative impact on the OpenChrome X server. 1617 + If you use any X server other than fbdev you should enable this 1618 + otherwise it should be safe to disable it and allow using all 1619 + features. 1620 + 1610 1621 endif 1611 1622 1612 1623 config FB_NEOMAGIC
+1 -1
drivers/video/via/Makefile
··· 6 6 7 7 viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \ 8 8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ 9 - via-core.o via-gpio.o via_modesetting.o 9 + via-core.o via-gpio.o via_modesetting.o via_clock.o
+142 -383
drivers/video/via/hw.c
··· 22 22 #include <linux/via-core.h> 23 23 #include <asm/olpc.h> 24 24 #include "global.h" 25 + #include "via_clock.h" 25 26 26 - static struct pll_config cle266_pll_config[] = { 27 - {19, 4, 0}, 28 - {26, 5, 0}, 29 - {28, 5, 0}, 30 - {31, 5, 0}, 31 - {33, 5, 0}, 32 - {55, 5, 0}, 33 - {102, 5, 0}, 34 - {53, 6, 0}, 35 - {92, 6, 0}, 36 - {98, 6, 0}, 37 - {112, 6, 0}, 38 - {41, 7, 0}, 39 - {60, 7, 0}, 40 - {99, 7, 0}, 41 - {100, 7, 0}, 42 - {83, 8, 0}, 43 - {86, 8, 0}, 44 - {108, 8, 0}, 45 - {87, 9, 0}, 46 - {118, 9, 0}, 47 - {95, 12, 0}, 48 - {115, 12, 0}, 49 - {108, 13, 0}, 50 - {83, 17, 0}, 51 - {67, 20, 0}, 52 - {86, 20, 0}, 53 - {98, 20, 0}, 54 - {121, 24, 0}, 55 - {99, 29, 0}, 56 - {33, 3, 1}, 57 - {15, 4, 1}, 58 - {23, 4, 1}, 59 - {37, 5, 1}, 60 - {83, 5, 1}, 61 - {85, 5, 1}, 62 - {94, 5, 1}, 63 - {103, 5, 1}, 64 - {109, 5, 1}, 65 - {113, 5, 1}, 66 - {121, 5, 1}, 67 - {82, 6, 1}, 68 - {31, 7, 1}, 69 - {55, 7, 1}, 70 - {84, 7, 1}, 71 - {83, 8, 1}, 72 - {76, 9, 1}, 73 - {127, 9, 1}, 74 - {33, 4, 2}, 75 - {75, 4, 2}, 76 - {119, 4, 2}, 77 - {121, 4, 2}, 78 - {91, 5, 2}, 79 - {118, 5, 2}, 80 - {83, 6, 2}, 81 - {109, 6, 2}, 82 - {90, 7, 2}, 83 - {93, 2, 3}, 84 - {53, 3, 3}, 85 - {73, 4, 3}, 86 - {89, 4, 3}, 87 - {105, 4, 3}, 88 - {117, 4, 3}, 89 - {101, 5, 3}, 90 - {121, 5, 3}, 91 - {127, 5, 3}, 92 - {99, 7, 3} 27 + static struct pll_limit cle266_pll_limits[] = { 28 + {19, 19, 4, 0}, 29 + {26, 102, 5, 0}, 30 + {53, 112, 6, 0}, 31 + {41, 100, 7, 0}, 32 + {83, 108, 8, 0}, 33 + {87, 118, 9, 0}, 34 + {95, 115, 12, 0}, 35 + {108, 108, 13, 0}, 36 + {83, 83, 17, 0}, 37 + {67, 98, 20, 0}, 38 + {121, 121, 24, 0}, 39 + {99, 99, 29, 0}, 40 + {33, 33, 3, 1}, 41 + {15, 23, 4, 1}, 42 + {37, 121, 5, 1}, 43 + {82, 82, 6, 1}, 44 + {31, 84, 7, 1}, 45 + {83, 83, 8, 1}, 46 + {76, 127, 9, 1}, 47 + {33, 121, 4, 2}, 48 + {91, 118, 5, 2}, 49 + {83, 109, 6, 2}, 50 + {90, 90, 7, 2}, 51 + {93, 93, 2, 3}, 52 + {53, 53, 3, 3}, 53 + {73, 117, 4, 3}, 54 + {101, 127, 5, 3}, 55 + {99, 99, 7, 3} 93 56 }; 94 57 95 - static struct pll_config k800_pll_config[] = { 96 - {22, 2, 0}, 97 - {28, 3, 0}, 98 - {81, 3, 1}, 99 - {85, 3, 1}, 100 - {98, 3, 1}, 101 - {112, 3, 1}, 102 - {86, 4, 1}, 103 - {166, 4, 1}, 104 - {109, 5, 1}, 105 - {113, 5, 1}, 106 - {121, 5, 1}, 107 - {131, 5, 1}, 108 - {143, 5, 1}, 109 - {153, 5, 1}, 110 - {66, 3, 2}, 111 - {68, 3, 2}, 112 - {95, 3, 2}, 113 - {106, 3, 2}, 114 - {116, 3, 2}, 115 - {93, 4, 2}, 116 - {119, 4, 2}, 117 - {121, 4, 2}, 118 - {133, 4, 2}, 119 - {137, 4, 2}, 120 - {117, 5, 2}, 121 - {118, 5, 2}, 122 - {120, 5, 2}, 123 - {124, 5, 2}, 124 - {132, 5, 2}, 125 - {137, 5, 2}, 126 - {141, 5, 2}, 127 - {166, 5, 2}, 128 - {170, 5, 2}, 129 - {191, 5, 2}, 130 - {206, 5, 2}, 131 - {208, 5, 2}, 132 - {30, 2, 3}, 133 - {69, 3, 3}, 134 - {82, 3, 3}, 135 - {83, 3, 3}, 136 - {109, 3, 3}, 137 - {114, 3, 3}, 138 - {125, 3, 3}, 139 - {89, 4, 3}, 140 - {103, 4, 3}, 141 - {117, 4, 3}, 142 - {126, 4, 3}, 143 - {150, 4, 3}, 144 - {161, 4, 3}, 145 - {121, 5, 3}, 146 - {127, 5, 3}, 147 - {131, 5, 3}, 148 - {134, 5, 3}, 149 - {148, 5, 3}, 150 - {169, 5, 3}, 151 - {172, 5, 3}, 152 - {182, 5, 3}, 153 - {195, 5, 3}, 154 - {196, 5, 3}, 155 - {208, 5, 3}, 156 - {66, 2, 4}, 157 - {85, 3, 4}, 158 - {141, 4, 4}, 159 - {146, 4, 4}, 160 - {161, 4, 4}, 161 - {177, 5, 4} 58 + static struct pll_limit k800_pll_limits[] = { 59 + {22, 22, 2, 0}, 60 + {28, 28, 3, 0}, 61 + {81, 112, 3, 1}, 62 + {86, 166, 4, 1}, 63 + {109, 153, 5, 1}, 64 + {66, 116, 3, 2}, 65 + {93, 137, 4, 2}, 66 + {117, 208, 5, 2}, 67 + {30, 30, 2, 3}, 68 + {69, 125, 3, 3}, 69 + {89, 161, 4, 3}, 70 + {121, 208, 5, 3}, 71 + {66, 66, 2, 4}, 72 + {85, 85, 3, 4}, 73 + {141, 161, 4, 4}, 74 + {177, 177, 5, 4} 162 75 }; 163 76 164 - static struct pll_config cx700_pll_config[] = { 165 - {98, 3, 1}, 166 - {86, 4, 1}, 167 - {109, 5, 1}, 168 - {110, 5, 1}, 169 - {113, 5, 1}, 170 - {121, 5, 1}, 171 - {131, 5, 1}, 172 - {135, 5, 1}, 173 - {142, 5, 1}, 174 - {143, 5, 1}, 175 - {153, 5, 1}, 176 - {187, 5, 1}, 177 - {208, 5, 1}, 178 - {68, 2, 2}, 179 - {95, 3, 2}, 180 - {116, 3, 2}, 181 - {93, 4, 2}, 182 - {119, 4, 2}, 183 - {133, 4, 2}, 184 - {137, 4, 2}, 185 - {151, 4, 2}, 186 - {166, 4, 2}, 187 - {110, 5, 2}, 188 - {112, 5, 2}, 189 - {117, 5, 2}, 190 - {118, 5, 2}, 191 - {120, 5, 2}, 192 - {132, 5, 2}, 193 - {137, 5, 2}, 194 - {141, 5, 2}, 195 - {151, 5, 2}, 196 - {166, 5, 2}, 197 - {175, 5, 2}, 198 - {191, 5, 2}, 199 - {206, 5, 2}, 200 - {174, 7, 2}, 201 - {82, 3, 3}, 202 - {109, 3, 3}, 203 - {117, 4, 3}, 204 - {150, 4, 3}, 205 - {161, 4, 3}, 206 - {112, 5, 3}, 207 - {115, 5, 3}, 208 - {121, 5, 3}, 209 - {127, 5, 3}, 210 - {129, 5, 3}, 211 - {131, 5, 3}, 212 - {134, 5, 3}, 213 - {138, 5, 3}, 214 - {148, 5, 3}, 215 - {157, 5, 3}, 216 - {169, 5, 3}, 217 - {172, 5, 3}, 218 - {190, 5, 3}, 219 - {195, 5, 3}, 220 - {196, 5, 3}, 221 - {208, 5, 3}, 222 - {141, 5, 4}, 223 - {150, 5, 4}, 224 - {166, 5, 4}, 225 - {176, 5, 4}, 226 - {177, 5, 4}, 227 - {183, 5, 4}, 228 - {202, 5, 4} 77 + static struct pll_limit cx700_pll_limits[] = { 78 + {98, 98, 3, 1}, 79 + {86, 86, 4, 1}, 80 + {109, 208, 5, 1}, 81 + {68, 68, 2, 2}, 82 + {95, 116, 3, 2}, 83 + {93, 166, 4, 2}, 84 + {110, 206, 5, 2}, 85 + {174, 174, 7, 2}, 86 + {82, 109, 3, 3}, 87 + {117, 161, 4, 3}, 88 + {112, 208, 5, 3}, 89 + {141, 202, 5, 4} 229 90 }; 230 91 231 - static struct pll_config vx855_pll_config[] = { 232 - {86, 4, 1}, 233 - {108, 5, 1}, 234 - {110, 5, 1}, 235 - {113, 5, 1}, 236 - {121, 5, 1}, 237 - {131, 5, 1}, 238 - {135, 5, 1}, 239 - {142, 5, 1}, 240 - {143, 5, 1}, 241 - {153, 5, 1}, 242 - {164, 5, 1}, 243 - {187, 5, 1}, 244 - {208, 5, 1}, 245 - {110, 5, 2}, 246 - {112, 5, 2}, 247 - {117, 5, 2}, 248 - {118, 5, 2}, 249 - {124, 5, 2}, 250 - {132, 5, 2}, 251 - {137, 5, 2}, 252 - {141, 5, 2}, 253 - {149, 5, 2}, 254 - {151, 5, 2}, 255 - {159, 5, 2}, 256 - {166, 5, 2}, 257 - {167, 5, 2}, 258 - {172, 5, 2}, 259 - {189, 5, 2}, 260 - {191, 5, 2}, 261 - {194, 5, 2}, 262 - {206, 5, 2}, 263 - {208, 5, 2}, 264 - {83, 3, 3}, 265 - {88, 3, 3}, 266 - {109, 3, 3}, 267 - {112, 3, 3}, 268 - {103, 4, 3}, 269 - {105, 4, 3}, 270 - {161, 4, 3}, 271 - {112, 5, 3}, 272 - {115, 5, 3}, 273 - {121, 5, 3}, 274 - {127, 5, 3}, 275 - {134, 5, 3}, 276 - {137, 5, 3}, 277 - {148, 5, 3}, 278 - {157, 5, 3}, 279 - {169, 5, 3}, 280 - {172, 5, 3}, 281 - {182, 5, 3}, 282 - {191, 5, 3}, 283 - {195, 5, 3}, 284 - {209, 5, 3}, 285 - {142, 4, 4}, 286 - {146, 4, 4}, 287 - {161, 4, 4}, 288 - {141, 5, 4}, 289 - {150, 5, 4}, 290 - {165, 5, 4}, 291 - {176, 5, 4} 92 + static struct pll_limit vx855_pll_limits[] = { 93 + {86, 86, 4, 1}, 94 + {108, 208, 5, 1}, 95 + {110, 208, 5, 2}, 96 + {83, 112, 3, 3}, 97 + {103, 161, 4, 3}, 98 + {112, 209, 5, 3}, 99 + {142, 161, 4, 4}, 100 + {141, 176, 5, 4} 292 101 }; 293 102 294 103 /* according to VIA Technologies these values are based on experiment */ ··· 521 712 {VIA_LVDS1, "LVDS1"}, 522 713 {VIA_LVDS2, "LVDS2"} 523 714 }; 715 + 716 + /* structure with function pointers to support clock control */ 717 + static struct via_clock clock; 524 718 525 719 static void load_fix_bit_crtc_reg(void); 526 720 static void __devinit init_gfx_chip_info(int chip_type); ··· 1446 1634 1447 1635 } 1448 1636 1449 - static u32 cle266_encode_pll(struct pll_config pll) 1450 - { 1451 - return (pll.multiplier << 8) 1452 - | (pll.rshift << 6) 1453 - | pll.divisor; 1454 - } 1455 - 1456 - static u32 k800_encode_pll(struct pll_config pll) 1457 - { 1458 - return ((pll.divisor - 2) << 16) 1459 - | (pll.rshift << 10) 1460 - | (pll.multiplier - 2); 1461 - } 1462 - 1463 - static u32 vx855_encode_pll(struct pll_config pll) 1464 - { 1465 - return (pll.divisor << 16) 1466 - | (pll.rshift << 10) 1467 - | pll.multiplier; 1468 - } 1469 - 1470 - static inline u32 get_pll_internal_frequency(u32 ref_freq, 1471 - struct pll_config pll) 1472 - { 1473 - return ref_freq / pll.divisor * pll.multiplier; 1474 - } 1475 - 1476 - static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) 1477 - { 1478 - return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; 1479 - } 1480 - 1481 - static struct pll_config get_pll_config(struct pll_config *config, int size, 1637 + static struct via_pll_config get_pll_config(struct pll_limit *limits, int size, 1482 1638 int clk) 1483 1639 { 1484 - struct pll_config best = config[0]; 1640 + struct via_pll_config cur, up, down, best = {0, 1, 0}; 1485 1641 const u32 f0 = 14318180; /* X1 frequency */ 1486 - int i; 1642 + int i, f; 1487 1643 1488 - for (i = 1; i < size; i++) { 1489 - if (abs(get_pll_output_frequency(f0, config[i]) - clk) 1490 - < abs(get_pll_output_frequency(f0, best) - clk)) 1491 - best = config[i]; 1644 + for (i = 0; i < size; i++) { 1645 + cur.rshift = limits[i].rshift; 1646 + cur.divisor = limits[i].divisor; 1647 + cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); 1648 + f = abs(get_pll_output_frequency(f0, cur) - clk); 1649 + up = down = cur; 1650 + up.multiplier++; 1651 + down.multiplier--; 1652 + if (abs(get_pll_output_frequency(f0, up) - clk) < f) 1653 + cur = up; 1654 + else if (abs(get_pll_output_frequency(f0, down) - clk) < f) 1655 + cur = down; 1656 + 1657 + if (cur.multiplier < limits[i].multiplier_min) 1658 + cur.multiplier = limits[i].multiplier_min; 1659 + else if (cur.multiplier > limits[i].multiplier_max) 1660 + cur.multiplier = limits[i].multiplier_max; 1661 + 1662 + f = abs(get_pll_output_frequency(f0, cur) - clk); 1663 + if (f < abs(get_pll_output_frequency(f0, best) - clk)) 1664 + best = cur; 1492 1665 } 1493 1666 1494 1667 return best; 1495 1668 } 1496 1669 1497 - u32 viafb_get_clk_value(int clk) 1670 + static struct via_pll_config get_best_pll_config(int clk) 1498 1671 { 1499 - u32 value = 0; 1672 + struct via_pll_config config; 1500 1673 1501 1674 switch (viaparinfo->chip_info->gfx_chip_name) { 1502 1675 case UNICHROME_CLE266: 1503 1676 case UNICHROME_K400: 1504 - value = cle266_encode_pll(get_pll_config(cle266_pll_config, 1505 - ARRAY_SIZE(cle266_pll_config), clk)); 1677 + config = get_pll_config(cle266_pll_limits, 1678 + ARRAY_SIZE(cle266_pll_limits), clk); 1506 1679 break; 1507 1680 case UNICHROME_K800: 1508 1681 case UNICHROME_PM800: 1509 1682 case UNICHROME_CN700: 1510 - value = k800_encode_pll(get_pll_config(k800_pll_config, 1511 - ARRAY_SIZE(k800_pll_config), clk)); 1683 + config = get_pll_config(k800_pll_limits, 1684 + ARRAY_SIZE(k800_pll_limits), clk); 1512 1685 break; 1513 1686 case UNICHROME_CX700: 1514 1687 case UNICHROME_CN750: ··· 1501 1704 case UNICHROME_P4M890: 1502 1705 case UNICHROME_P4M900: 1503 1706 case UNICHROME_VX800: 1504 - value = k800_encode_pll(get_pll_config(cx700_pll_config, 1505 - ARRAY_SIZE(cx700_pll_config), clk)); 1707 + config = get_pll_config(cx700_pll_limits, 1708 + ARRAY_SIZE(cx700_pll_limits), clk); 1506 1709 break; 1507 1710 case UNICHROME_VX855: 1508 1711 case UNICHROME_VX900: 1509 - value = vx855_encode_pll(get_pll_config(vx855_pll_config, 1510 - ARRAY_SIZE(vx855_pll_config), clk)); 1712 + config = get_pll_config(vx855_pll_limits, 1713 + ARRAY_SIZE(vx855_pll_limits), clk); 1511 1714 break; 1512 1715 } 1513 1716 1514 - return value; 1717 + return config; 1515 1718 } 1516 1719 1517 1720 /* Set VCLK*/ 1518 1721 void viafb_set_vclock(u32 clk, int set_iga) 1519 1722 { 1520 - /* H.W. Reset : ON */ 1521 - viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1723 + struct via_pll_config config = get_best_pll_config(clk); 1522 1724 1523 - if (set_iga == IGA1) { 1524 - /* Change D,N FOR VCLK */ 1525 - switch (viaparinfo->chip_info->gfx_chip_name) { 1526 - case UNICHROME_CLE266: 1527 - case UNICHROME_K400: 1528 - via_write_reg(VIASR, SR46, (clk & 0x00FF)); 1529 - via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); 1530 - break; 1531 - 1532 - case UNICHROME_K800: 1533 - case UNICHROME_PM800: 1534 - case UNICHROME_CN700: 1535 - case UNICHROME_CX700: 1536 - case UNICHROME_CN750: 1537 - case UNICHROME_K8M890: 1538 - case UNICHROME_P4M890: 1539 - case UNICHROME_P4M900: 1540 - case UNICHROME_VX800: 1541 - case UNICHROME_VX855: 1542 - case UNICHROME_VX900: 1543 - via_write_reg(VIASR, SR44, (clk & 0x0000FF)); 1544 - via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); 1545 - via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); 1546 - break; 1547 - } 1548 - } 1549 - 1550 - if (set_iga == IGA2) { 1551 - /* Change D,N FOR LCK */ 1552 - switch (viaparinfo->chip_info->gfx_chip_name) { 1553 - case UNICHROME_CLE266: 1554 - case UNICHROME_K400: 1555 - via_write_reg(VIASR, SR44, (clk & 0x00FF)); 1556 - via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); 1557 - break; 1558 - 1559 - case UNICHROME_K800: 1560 - case UNICHROME_PM800: 1561 - case UNICHROME_CN700: 1562 - case UNICHROME_CX700: 1563 - case UNICHROME_CN750: 1564 - case UNICHROME_K8M890: 1565 - case UNICHROME_P4M890: 1566 - case UNICHROME_P4M900: 1567 - case UNICHROME_VX800: 1568 - case UNICHROME_VX855: 1569 - case UNICHROME_VX900: 1570 - via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); 1571 - via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); 1572 - via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); 1573 - break; 1574 - } 1575 - } 1576 - 1577 - /* H.W. Reset : OFF */ 1578 - viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); 1579 - 1580 - /* Reset PLL */ 1581 - if (set_iga == IGA1) { 1582 - viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); 1583 - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); 1584 - } 1585 - 1586 - if (set_iga == IGA2) { 1587 - viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); 1588 - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); 1589 - } 1725 + if (set_iga == IGA1) 1726 + clock.set_primary_pll(config); 1727 + if (set_iga == IGA2) 1728 + clock.set_secondary_pll(config); 1590 1729 1591 1730 /* Fire! */ 1592 1731 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ ··· 1768 2035 int i; 1769 2036 int index = 0; 1770 2037 int h_addr, v_addr; 1771 - u32 pll_D_N, clock, refresh = viafb_refresh; 2038 + u32 clock, refresh = viafb_refresh; 1772 2039 1773 2040 if (viafb_SAMM_ON && set_iga == IGA2) 1774 2041 refresh = viafb_refresh1; ··· 1822 2089 1823 2090 clock = crt_reg.hor_total * crt_reg.ver_total 1824 2091 * crt_table[index].refresh_rate; 1825 - pll_D_N = viafb_get_clk_value(clock); 1826 - DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); 1827 - viafb_set_vclock(pll_D_N, set_iga); 2092 + viafb_set_vclock(clock, set_iga); 1828 2093 1829 2094 } 1830 2095 1831 2096 void __devinit viafb_init_chip_info(int chip_type) 1832 2097 { 2098 + via_clock_init(&clock, chip_type); 1833 2099 init_gfx_chip_info(chip_type); 1834 2100 init_tmds_chip_info(); 1835 2101 init_lvds_chip_info(); ··· 2315 2583 via_set_sync_polarity(viaparinfo->shared->iga2_devices, 2316 2584 get_sync(viafbinfo1)); 2317 2585 } 2586 + 2587 + clock.set_engine_pll_state(VIA_STATE_ON); 2588 + clock.set_primary_clock_source(VIA_CLKSRC_X1, true); 2589 + clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); 2590 + 2591 + #ifdef CONFIG_FB_VIA_X_COMPATIBILITY 2592 + clock.set_primary_pll_state(VIA_STATE_ON); 2593 + clock.set_primary_clock_state(VIA_STATE_ON); 2594 + clock.set_secondary_pll_state(VIA_STATE_ON); 2595 + clock.set_secondary_clock_state(VIA_STATE_ON); 2596 + #else 2597 + if (viaparinfo->shared->iga1_devices) { 2598 + clock.set_primary_pll_state(VIA_STATE_ON); 2599 + clock.set_primary_clock_state(VIA_STATE_ON); 2600 + } else { 2601 + clock.set_primary_pll_state(VIA_STATE_OFF); 2602 + clock.set_primary_clock_state(VIA_STATE_OFF); 2603 + } 2604 + 2605 + if (viaparinfo->shared->iga2_devices) { 2606 + clock.set_secondary_pll_state(VIA_STATE_ON); 2607 + clock.set_secondary_clock_state(VIA_STATE_ON); 2608 + } else { 2609 + clock.set_secondary_pll_state(VIA_STATE_OFF); 2610 + clock.set_secondary_clock_state(VIA_STATE_OFF); 2611 + } 2612 + #endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ 2318 2613 2319 2614 via_set_state(devices, VIA_STATE_ON); 2320 2615 device_screen_on();
+3 -11
drivers/video/via/hw.h
··· 732 732 struct _lcd_ver_scaling_factor lcd_ver_scaling_factor; 733 733 }; 734 734 735 - struct pll_config { 736 - u16 multiplier; 735 + struct pll_limit { 736 + u16 multiplier_min; 737 + u16 multiplier_max; 737 738 u8 divisor; 738 739 u8 rshift; 739 - }; 740 - 741 - struct pll_map { 742 - u32 clk; 743 - struct pll_config cle266_pll; 744 - struct pll_config k800_pll; 745 - struct pll_config cx700_pll; 746 - struct pll_config vx855_pll; 747 740 }; 748 741 749 742 struct rgbLUT { ··· 928 935 void viafb_unlock_crt(void); 929 936 void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); 930 937 void viafb_write_regx(struct io_reg RegTable[], int ItemNum); 931 - u32 viafb_get_clk_value(int clk); 932 938 void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active); 933 939 void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 934 940 *p_gfx_dpa_setting);
+2 -5
drivers/video/via/lcd.c
··· 558 558 int set_vres = plvds_setting_info->v_active; 559 559 int panel_hres = plvds_setting_info->lcd_panel_hres; 560 560 int panel_vres = plvds_setting_info->lcd_panel_vres; 561 - u32 pll_D_N, clock; 561 + u32 clock; 562 562 struct display_timing mode_crt_reg, panel_crt_reg; 563 563 struct crt_mode_table *panel_crt_table = NULL; 564 564 struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, ··· 609 609 viafb_load_FIFO_reg(set_iga, set_hres, set_vres); 610 610 611 611 fill_lcd_format(); 612 - 613 - pll_D_N = viafb_get_clk_value(clock); 614 - DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); 615 - viafb_set_vclock(pll_D_N, set_iga); 612 + viafb_set_vclock(clock, set_iga); 616 613 lcd_patch_skew(plvds_setting_info, plvds_chip_info); 617 614 618 615 /* If K8M800, enable LCD Prefetch Mode. */
+349
drivers/video/via/via_clock.c
··· 1 + /* 2 + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 3 + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 4 + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public 8 + * License as published by the Free Software Foundation; 9 + * either version 2, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 13 + * the implied warranty of MERCHANTABILITY or FITNESS FOR 14 + * A PARTICULAR PURPOSE.See the GNU General Public License 15 + * for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 20 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 + */ 22 + /* 23 + * clock and PLL management functions 24 + */ 25 + 26 + #include <linux/kernel.h> 27 + #include <linux/via-core.h> 28 + #include "via_clock.h" 29 + #include "global.h" 30 + #include "debug.h" 31 + 32 + const char *via_slap = "Please slap VIA Technologies to motivate them " 33 + "releasing full documentation for your platform!\n"; 34 + 35 + static inline u32 cle266_encode_pll(struct via_pll_config pll) 36 + { 37 + return (pll.multiplier << 8) 38 + | (pll.rshift << 6) 39 + | pll.divisor; 40 + } 41 + 42 + static inline u32 k800_encode_pll(struct via_pll_config pll) 43 + { 44 + return ((pll.divisor - 2) << 16) 45 + | (pll.rshift << 10) 46 + | (pll.multiplier - 2); 47 + } 48 + 49 + static inline u32 vx855_encode_pll(struct via_pll_config pll) 50 + { 51 + return (pll.divisor << 16) 52 + | (pll.rshift << 10) 53 + | pll.multiplier; 54 + } 55 + 56 + static inline void cle266_set_primary_pll_encoded(u32 data) 57 + { 58 + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ 59 + via_write_reg(VIASR, 0x46, data & 0xFF); 60 + via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); 61 + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ 62 + } 63 + 64 + static inline void k800_set_primary_pll_encoded(u32 data) 65 + { 66 + via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ 67 + via_write_reg(VIASR, 0x44, data & 0xFF); 68 + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); 69 + via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); 70 + via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ 71 + } 72 + 73 + static inline void cle266_set_secondary_pll_encoded(u32 data) 74 + { 75 + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ 76 + via_write_reg(VIASR, 0x44, data & 0xFF); 77 + via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); 78 + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ 79 + } 80 + 81 + static inline void k800_set_secondary_pll_encoded(u32 data) 82 + { 83 + via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ 84 + via_write_reg(VIASR, 0x4A, data & 0xFF); 85 + via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); 86 + via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); 87 + via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ 88 + } 89 + 90 + static inline void set_engine_pll_encoded(u32 data) 91 + { 92 + via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */ 93 + via_write_reg(VIASR, 0x47, data & 0xFF); 94 + via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF); 95 + via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF); 96 + via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */ 97 + } 98 + 99 + static void cle266_set_primary_pll(struct via_pll_config config) 100 + { 101 + cle266_set_primary_pll_encoded(cle266_encode_pll(config)); 102 + } 103 + 104 + static void k800_set_primary_pll(struct via_pll_config config) 105 + { 106 + k800_set_primary_pll_encoded(k800_encode_pll(config)); 107 + } 108 + 109 + static void vx855_set_primary_pll(struct via_pll_config config) 110 + { 111 + k800_set_primary_pll_encoded(vx855_encode_pll(config)); 112 + } 113 + 114 + static void cle266_set_secondary_pll(struct via_pll_config config) 115 + { 116 + cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); 117 + } 118 + 119 + static void k800_set_secondary_pll(struct via_pll_config config) 120 + { 121 + k800_set_secondary_pll_encoded(k800_encode_pll(config)); 122 + } 123 + 124 + static void vx855_set_secondary_pll(struct via_pll_config config) 125 + { 126 + k800_set_secondary_pll_encoded(vx855_encode_pll(config)); 127 + } 128 + 129 + static void k800_set_engine_pll(struct via_pll_config config) 130 + { 131 + set_engine_pll_encoded(k800_encode_pll(config)); 132 + } 133 + 134 + static void vx855_set_engine_pll(struct via_pll_config config) 135 + { 136 + set_engine_pll_encoded(vx855_encode_pll(config)); 137 + } 138 + 139 + static void set_primary_pll_state(u8 state) 140 + { 141 + u8 value; 142 + 143 + switch (state) { 144 + case VIA_STATE_ON: 145 + value = 0x20; 146 + break; 147 + case VIA_STATE_OFF: 148 + value = 0x00; 149 + break; 150 + default: 151 + return; 152 + } 153 + 154 + via_write_reg_mask(VIASR, 0x2D, value, 0x30); 155 + } 156 + 157 + static void set_secondary_pll_state(u8 state) 158 + { 159 + u8 value; 160 + 161 + switch (state) { 162 + case VIA_STATE_ON: 163 + value = 0x08; 164 + break; 165 + case VIA_STATE_OFF: 166 + value = 0x00; 167 + break; 168 + default: 169 + return; 170 + } 171 + 172 + via_write_reg_mask(VIASR, 0x2D, value, 0x0C); 173 + } 174 + 175 + static void set_engine_pll_state(u8 state) 176 + { 177 + u8 value; 178 + 179 + switch (state) { 180 + case VIA_STATE_ON: 181 + value = 0x02; 182 + break; 183 + case VIA_STATE_OFF: 184 + value = 0x00; 185 + break; 186 + default: 187 + return; 188 + } 189 + 190 + via_write_reg_mask(VIASR, 0x2D, value, 0x03); 191 + } 192 + 193 + static void set_primary_clock_state(u8 state) 194 + { 195 + u8 value; 196 + 197 + switch (state) { 198 + case VIA_STATE_ON: 199 + value = 0x20; 200 + break; 201 + case VIA_STATE_OFF: 202 + value = 0x00; 203 + break; 204 + default: 205 + return; 206 + } 207 + 208 + via_write_reg_mask(VIASR, 0x1B, value, 0x30); 209 + } 210 + 211 + static void set_secondary_clock_state(u8 state) 212 + { 213 + u8 value; 214 + 215 + switch (state) { 216 + case VIA_STATE_ON: 217 + value = 0x80; 218 + break; 219 + case VIA_STATE_OFF: 220 + value = 0x00; 221 + break; 222 + default: 223 + return; 224 + } 225 + 226 + via_write_reg_mask(VIASR, 0x1B, value, 0xC0); 227 + } 228 + 229 + static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) 230 + { 231 + u8 data = 0; 232 + 233 + switch (source) { 234 + case VIA_CLKSRC_X1: 235 + data = 0x00; 236 + break; 237 + case VIA_CLKSRC_TVX1: 238 + data = 0x02; 239 + break; 240 + case VIA_CLKSRC_TVPLL: 241 + data = 0x04; /* 0x06 should be the same */ 242 + break; 243 + case VIA_CLKSRC_DVP1TVCLKR: 244 + data = 0x0A; 245 + break; 246 + case VIA_CLKSRC_CAP0: 247 + data = 0xC; 248 + break; 249 + case VIA_CLKSRC_CAP1: 250 + data = 0x0E; 251 + break; 252 + } 253 + 254 + if (!use_pll) 255 + data |= 1; 256 + 257 + return data; 258 + } 259 + 260 + static void set_primary_clock_source(enum via_clksrc source, bool use_pll) 261 + { 262 + u8 data = set_clock_source_common(source, use_pll) << 4; 263 + via_write_reg_mask(VIACR, 0x6C, data, 0xF0); 264 + } 265 + 266 + static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) 267 + { 268 + u8 data = set_clock_source_common(source, use_pll); 269 + via_write_reg_mask(VIACR, 0x6C, data, 0x0F); 270 + } 271 + 272 + static void dummy_set_clock_state(u8 state) 273 + { 274 + printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap); 275 + } 276 + 277 + static void dummy_set_clock_source(enum via_clksrc source, bool use_pll) 278 + { 279 + printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap); 280 + } 281 + 282 + static void dummy_set_pll_state(u8 state) 283 + { 284 + printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); 285 + } 286 + 287 + static void dummy_set_pll(struct via_pll_config config) 288 + { 289 + printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); 290 + } 291 + 292 + void via_clock_init(struct via_clock *clock, int gfx_chip) 293 + { 294 + switch (gfx_chip) { 295 + case UNICHROME_CLE266: 296 + case UNICHROME_K400: 297 + clock->set_primary_clock_state = dummy_set_clock_state; 298 + clock->set_primary_clock_source = dummy_set_clock_source; 299 + clock->set_primary_pll_state = dummy_set_pll_state; 300 + clock->set_primary_pll = cle266_set_primary_pll; 301 + 302 + clock->set_secondary_clock_state = dummy_set_clock_state; 303 + clock->set_secondary_clock_source = dummy_set_clock_source; 304 + clock->set_secondary_pll_state = dummy_set_pll_state; 305 + clock->set_secondary_pll = cle266_set_secondary_pll; 306 + 307 + clock->set_engine_pll_state = dummy_set_pll_state; 308 + clock->set_engine_pll = dummy_set_pll; 309 + break; 310 + case UNICHROME_K800: 311 + case UNICHROME_PM800: 312 + case UNICHROME_CN700: 313 + case UNICHROME_CX700: 314 + case UNICHROME_CN750: 315 + case UNICHROME_K8M890: 316 + case UNICHROME_P4M890: 317 + case UNICHROME_P4M900: 318 + case UNICHROME_VX800: 319 + clock->set_primary_clock_state = set_primary_clock_state; 320 + clock->set_primary_clock_source = set_primary_clock_source; 321 + clock->set_primary_pll_state = set_primary_pll_state; 322 + clock->set_primary_pll = k800_set_primary_pll; 323 + 324 + clock->set_secondary_clock_state = set_secondary_clock_state; 325 + clock->set_secondary_clock_source = set_secondary_clock_source; 326 + clock->set_secondary_pll_state = set_secondary_pll_state; 327 + clock->set_secondary_pll = k800_set_secondary_pll; 328 + 329 + clock->set_engine_pll_state = set_engine_pll_state; 330 + clock->set_engine_pll = k800_set_engine_pll; 331 + break; 332 + case UNICHROME_VX855: 333 + case UNICHROME_VX900: 334 + clock->set_primary_clock_state = set_primary_clock_state; 335 + clock->set_primary_clock_source = set_primary_clock_source; 336 + clock->set_primary_pll_state = set_primary_pll_state; 337 + clock->set_primary_pll = vx855_set_primary_pll; 338 + 339 + clock->set_secondary_clock_state = set_secondary_clock_state; 340 + clock->set_secondary_clock_source = set_secondary_clock_source; 341 + clock->set_secondary_pll_state = set_secondary_pll_state; 342 + clock->set_secondary_pll = vx855_set_secondary_pll; 343 + 344 + clock->set_engine_pll_state = set_engine_pll_state; 345 + clock->set_engine_pll = vx855_set_engine_pll; 346 + break; 347 + 348 + } 349 + }
+76
drivers/video/via/via_clock.h
··· 1 + /* 2 + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 3 + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 4 + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public 8 + * License as published by the Free Software Foundation; 9 + * either version 2, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 13 + * the implied warranty of MERCHANTABILITY or FITNESS FOR 14 + * A PARTICULAR PURPOSE.See the GNU General Public License 15 + * for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 20 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 + */ 22 + /* 23 + * clock and PLL management functions 24 + */ 25 + 26 + #ifndef __VIA_CLOCK_H__ 27 + #define __VIA_CLOCK_H__ 28 + 29 + #include <linux/types.h> 30 + 31 + enum via_clksrc { 32 + VIA_CLKSRC_X1 = 0, 33 + VIA_CLKSRC_TVX1, 34 + VIA_CLKSRC_TVPLL, 35 + VIA_CLKSRC_DVP1TVCLKR, 36 + VIA_CLKSRC_CAP0, 37 + VIA_CLKSRC_CAP1, 38 + }; 39 + 40 + struct via_pll_config { 41 + u16 multiplier; 42 + u8 divisor; 43 + u8 rshift; 44 + }; 45 + 46 + struct via_clock { 47 + void (*set_primary_clock_state)(u8 state); 48 + void (*set_primary_clock_source)(enum via_clksrc src, bool use_pll); 49 + void (*set_primary_pll_state)(u8 state); 50 + void (*set_primary_pll)(struct via_pll_config config); 51 + 52 + void (*set_secondary_clock_state)(u8 state); 53 + void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll); 54 + void (*set_secondary_pll_state)(u8 state); 55 + void (*set_secondary_pll)(struct via_pll_config config); 56 + 57 + void (*set_engine_pll_state)(u8 state); 58 + void (*set_engine_pll)(struct via_pll_config config); 59 + }; 60 + 61 + 62 + static inline u32 get_pll_internal_frequency(u32 ref_freq, 63 + struct via_pll_config pll) 64 + { 65 + return ref_freq / pll.divisor * pll.multiplier; 66 + } 67 + 68 + static inline u32 get_pll_output_frequency(u32 ref_freq, 69 + struct via_pll_config pll) 70 + { 71 + return get_pll_internal_frequency(ref_freq, pll) >> pll.rshift; 72 + } 73 + 74 + void via_clock_init(struct via_clock *clock, int gfx_chip); 75 + 76 + #endif /* __VIA_CLOCK_H__ */
+2 -6
drivers/video/via/viamode.c
··· 37 37 {VIACR, CR69, 0xFF, 0x00}, 38 38 {VIACR, CR6A, 0xFF, 0x40}, 39 39 {VIACR, CR6B, 0xFF, 0x00}, 40 - {VIACR, CR6C, 0xFF, 0x00}, 41 40 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 42 41 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 43 42 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ ··· 82 83 {VIACR, CR69, 0xFF, 0x00}, 83 84 {VIACR, CR6A, 0xFD, 0x40}, 84 85 {VIACR, CR6B, 0xFF, 0x00}, 85 - {VIACR, CR6C, 0xFF, 0x00}, 86 86 {VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */ 87 87 {VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */ 88 88 {VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */ ··· 151 153 {VIASR, SR1B, 0xFF, 0xF0}, 152 154 {VIASR, SR1E, 0xFF, 0x01}, 153 155 {VIASR, SR2A, 0xFF, 0x00}, 154 - {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ 156 + {VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ 155 157 {VIACR, CR32, 0xFF, 0x00}, 156 158 {VIACR, CR33, 0xFF, 0x00}, 157 159 {VIACR, CR35, 0xFF, 0x00}, ··· 160 162 {VIACR, CR69, 0xFF, 0x00}, 161 163 {VIACR, CR6A, 0xFF, 0x40}, 162 164 {VIACR, CR6B, 0xFF, 0x00}, 163 - {VIACR, CR6C, 0xFF, 0x00}, 164 165 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 165 166 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 166 167 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */ ··· 189 192 {VIASR, SR2A, 0xF0, 0x00}, 190 193 {VIASR, SR58, 0xFF, 0x00}, 191 194 {VIASR, SR59, 0xFF, 0x00}, 192 - {VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */ 195 + {VIASR, SR2D, 0xC0, 0xC0}, /* delayed E3_ECK */ 193 196 {VIACR, CR32, 0xFF, 0x00}, 194 197 {VIACR, CR33, 0x7F, 0x00}, 195 198 {VIACR, CR35, 0xFF, 0x00}, ··· 197 200 {VIACR, CR69, 0xFF, 0x00}, 198 201 {VIACR, CR6A, 0xFD, 0x60}, 199 202 {VIACR, CR6B, 0xFF, 0x00}, 200 - {VIACR, CR6C, 0xFF, 0x00}, 201 203 {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */ 202 204 {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */ 203 205 {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */