22
22
#include <linux/via-core.h>
23
24
#include "global.h"
25
static struct pll_map pll_value[] = {
28
{85, 3, 4}, /* ignoring bit difference: 0x00008000 */
33
{66, 2, 4}, /* ignoring bit difference: 0x00808000 */
34
{166, 5, 4}, /* ignoring bit difference: 0x00008000 */
38
{30, 2, 3}, /* ignoring bit difference: 0x00808000 */
42
{53, 3, 3}, /* ignoring bit difference: 0x00008000 */
43
{141, 4, 4}, /* ignoring bit difference: 0x00008000 */
48
{177, 5, 4}, /* ignoring bit difference: 0x00008000 */
53
{146, 4, 4}, /* ignoring bit difference: 0x00008000 */
57
{101, 5, 3}, /* ignoring bit difference: 0x00008000 */
58
{161, 4, 4}, /* ignoring bit difference: 0x00008000 */
63
{89, 4, 3}, /* ignoring bit difference: 0x00008000 */
68
{69, 3, 3}, /* ignoring bit difference: 0x00008000 */
73
{121, 5, 3}, /* ignoring bit difference: 0x00008000 */
78
{127, 5, 3}, /* ignoring bit difference: 0x00808000 */
83
{103, 4, 3}, /* ignoring bit difference: 0x00008000 */
87
{105, 4, 3}, /* ignoring bit difference: 0x00008000 */
88
{131, 5, 3}, /* ignoring bit difference: 0x00808000 */
89
{131, 5, 3}, /* ignoring bit difference: 0x00808000 */
93
{134, 5, 3}, /* ignoring bit difference: 0x00808000 */
98
{82, 3, 3}, /* ignoring bit difference: 0x00808000 */
99
{82, 3, 3}, /* ignoring bit difference: 0x00808000 */
103
{83, 3, 3}, /* ignoring bit difference: 0x00008000 */
108
{117, 4, 3}, /* ignoring bit difference: 0x00008000 */
113
{148, 5, 3}, /* ignoring bit difference: 0x00808000 */
117
{55, 7, 1}, /* ignoring bit difference: 0x00008000 */
118
{126, 4, 3}, /* ignoring bit difference: 0x00008000 */
125
{157, 5, 3} }, /* ignoring bit difference: 0x00808000 */
128
{169, 5, 3}, /* ignoring bit difference: 0x00808000 */
129
{169, 5, 3}, /* FIXED: old = {72, 2, 3} */
133
{172, 5, 3}, /* ignoring bit difference: 0x00808000 */
137
{109, 6, 2}, /* ignoring bit difference: 0x00008000 */
138
{109, 3, 3}, /* ignoring bit difference: 0x00008000 */
143
{182, 5, 3}, /* ignoring bit difference: 0x00808000 */
148
{150, 4, 3}, /* ignoring bit difference: 0x00808000 */
153
{114, 3, 3}, /* ignoring bit difference: 0x00008000 */
158
{195, 5, 3}, /* ignoring bit difference: 0x00808000 */
163
{196, 5, 3}, /* ignoring bit difference: 0x00808000 */
168
{161, 4, 3}, /* ignoring bit difference: 0x00808000 */
173
{66, 3, 2}, /* ignoring bit difference: 0x00008000 */
178
{68, 3, 2}, /* ignoring bit difference: 0x00008000 */
183
{93, 4, 2}, /* ignoring bit difference: 0x00800000 */
184
{93, 4, 2}, /* ignoring bit difference: 0x00800000 */
188
{117, 5, 2}, /* ignoring bit difference: 0x00008000 */
193
{118, 5, 2}, /* ignoring bit difference: 0x00808000 */
198
{120, 5, 2}, /* ignoring bit difference: 0x00808000 */
203
{124, 5, 2}, /* ignoring bit difference: 0x00808000 */
204
{174, 7, 2}, /* ignoring bit difference: 0x00808000 */
208
{132, 5, 2}, /* ignoring bit difference: 0x00008000 */
213
{137, 5, 2}, /* ignoring bit difference: 0x00808000 */
218
{141, 5, 2}, /* ignoring bit difference: 0x00808000 */
223
{119, 4, 2}, /* ignoring bit difference: 0x00808000 */
228
{121, 4, 2}, /* ignoring bit difference: 0x00808000 */
233
{95, 3, 2}, /* ignoring bit difference: 0x00808000 */
238
{166, 5, 2}, /* ignoring bit difference: 0x00808000 */
243
{133, 4, 2}, /* ignoring bit difference: 0x00808000 */
248
{170, 5, 2}, /* ignoring bit difference: 0x00808000 */
252
{53, 6, 0}, /* ignoring bit difference: 0x00008000 */
253
{106, 3, 2}, /* ignoring bit difference: 0x00008000 */
258
{28, 3, 0}, /* ignoring bit difference: 0x00804000 */
263
{191, 5, 2}, /* ignoring bit difference: 0x00808000 */
268
{116, 3, 2}, /* ignoring bit difference: 0x00808000 */
273
{206, 5, 2}, /* ignoring bit difference: 0x00808000 */
278
{86, 4, 1}, /* ignoring bit difference: 0x00808000 */
280
{86, 4, 1} }, /* FIXED: old = {84, 2, 1} */
283
{109, 5, 1}, /* ignoring bit difference: 0x00808000 */
287
{55, 5, 0}, /* ignoring bit difference: 0x00008000 */
288
{22, 2, 0}, /* ignoring bit difference: 0x00802000 */
293
{113, 5, 1}, /* ignoring bit difference: 0x00808000 */
298
{131, 5, 1}, /* ignoring bit difference: 0x00808000 */
303
{81, 3, 1}, /* ignoring bit difference: 0x00808000 */
308
{85, 3, 1}, /* ignoring bit difference: 0x00808000 */
313
{143, 5, 1}, /* ignoring bit difference: 0x00808000 */
318
{153, 5, 1}, /* ignoring bit difference: 0x00808000 */
323
{98, 3, 1}, /* ignoring bit difference: 0x00008000 */
328
{112, 3, 1}, /* ignoring bit difference: 0x00808000 */
332
{102, 5, 0}, /* ignoring bit difference: 0x00008000 */
333
{166, 4, 1}, /* ignoring bit difference: 0x00008000 */
338
{125, 3, 3}, /* ignoring bit difference: 0x00808000 */
343
{121, 5, 1}, /* ignoring bit difference: 0x00808000 */
348
{137, 4, 2}, /* ignoring bit difference: 0x00808000 */
25
#include "via_clock.h"
27
static struct pll_limit cle266_pll_limits[] = {
58
static struct pll_limit k800_pll_limits[] = {
77
static struct pll_limit cx700_pll_limits[] = {
92
static struct pll_limit vx855_pll_limits[] = {
103
/* according to VIA Technologies these values are based on experiment */
104
static struct io_reg scaling_parameters[] = {
105
{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
106
{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
107
{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
108
{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
109
{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
110
{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
111
{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
112
{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
113
{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
114
{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
115
{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
116
{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
117
{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
118
{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
121
static struct io_reg common_vga[] = {
122
{VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8)
123
[1] vertical display end (bit 8)
124
[2] vertical retrace start (bit 8)
125
[3] start vertical blanking (bit 8)
126
[4] line compare (bit 8)
127
[5] vertical total (bit 9)
128
[6] vertical display end (bit 9)
129
[7] vertical retrace start (bit 9) */
130
{VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan
131
[5-6] byte panning */
132
{VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line
133
[5] start vertical blanking (bit 9)
134
[6] line compare (bit 9)
136
{VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start
137
[5] cursor disable */
138
{VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end
140
{VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */
141
{VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */
142
{VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end
143
[6] memory refresh bandwidth
144
[7] CRTC register protect enable */
145
{VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location
146
[5] divide memory address clock by 4
147
[6] double word addressing */
148
{VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14
149
[2] divide scan line clock by 2
150
[3] divide memory address clock by 2
154
{VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */
363
157
static struct fifo_depth_select display_fifo_depth_reg = {
1656
static u32 cle266_encode_pll(struct pll_config pll)
1658
return (pll.multiplier << 8)
1663
static u32 k800_encode_pll(struct pll_config pll)
1665
return ((pll.divisor - 2) << 16)
1666
| (pll.rshift << 10)
1667
| (pll.multiplier - 2);
1670
static u32 vx855_encode_pll(struct pll_config pll)
1672
return (pll.divisor << 16)
1673
| (pll.rshift << 10)
1677
u32 viafb_get_clk_value(int clk)
1682
while (i < NUM_TOTAL_PLL_TABLE && clk != pll_value[i].clk)
1685
if (i == NUM_TOTAL_PLL_TABLE) {
1686
printk(KERN_WARNING "viafb_get_clk_value: PLL lookup failed!");
1688
switch (viaparinfo->chip_info->gfx_chip_name) {
1689
case UNICHROME_CLE266:
1690
case UNICHROME_K400:
1691
value = cle266_encode_pll(pll_value[i].cle266_pll);
1694
case UNICHROME_K800:
1695
case UNICHROME_PM800:
1696
case UNICHROME_CN700:
1697
value = k800_encode_pll(pll_value[i].k800_pll);
1700
case UNICHROME_CX700:
1701
case UNICHROME_CN750:
1702
case UNICHROME_K8M890:
1703
case UNICHROME_P4M890:
1704
case UNICHROME_P4M900:
1705
case UNICHROME_VX800:
1706
value = k800_encode_pll(pll_value[i].cx700_pll);
1709
case UNICHROME_VX855:
1710
case UNICHROME_VX900:
1711
value = vx855_encode_pll(pll_value[i].vx855_pll);
1449
static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,
1452
struct via_pll_config cur, up, down, best = {0, 1, 0};
1453
const u32 f0 = 14318180; /* X1 frequency */
1456
for (i = 0; i < size; i++) {
1457
cur.rshift = limits[i].rshift;
1458
cur.divisor = limits[i].divisor;
1459
cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift);
1460
f = abs(get_pll_output_frequency(f0, cur) - clk);
1464
if (abs(get_pll_output_frequency(f0, up) - clk) < f)
1466
else if (abs(get_pll_output_frequency(f0, down) - clk) < f)
1469
if (cur.multiplier < limits[i].multiplier_min)
1470
cur.multiplier = limits[i].multiplier_min;
1471
else if (cur.multiplier > limits[i].multiplier_max)
1472
cur.multiplier = limits[i].multiplier_max;
1474
f = abs(get_pll_output_frequency(f0, cur) - clk);
1475
if (f < abs(get_pll_output_frequency(f0, best) - clk))
1482
static struct via_pll_config get_best_pll_config(int clk)
1484
struct via_pll_config config;
1486
switch (viaparinfo->chip_info->gfx_chip_name) {
1487
case UNICHROME_CLE266:
1488
case UNICHROME_K400:
1489
config = get_pll_config(cle266_pll_limits,
1490
ARRAY_SIZE(cle266_pll_limits), clk);
1492
case UNICHROME_K800:
1493
case UNICHROME_PM800:
1494
case UNICHROME_CN700:
1495
config = get_pll_config(k800_pll_limits,
1496
ARRAY_SIZE(k800_pll_limits), clk);
1498
case UNICHROME_CX700:
1499
case UNICHROME_CN750:
1500
case UNICHROME_K8M890:
1501
case UNICHROME_P4M890:
1502
case UNICHROME_P4M900:
1503
case UNICHROME_VX800:
1504
config = get_pll_config(cx700_pll_limits,
1505
ARRAY_SIZE(cx700_pll_limits), clk);
1507
case UNICHROME_VX855:
1508
case UNICHROME_VX900:
1509
config = get_pll_config(vx855_pll_limits,
1510
ARRAY_SIZE(vx855_pll_limits), clk);
1720
1518
void viafb_set_vclock(u32 clk, int set_iga)
1722
/* H.W. Reset : ON */
1723
viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1725
if (set_iga == IGA1) {
1726
/* Change D,N FOR VCLK */
1727
switch (viaparinfo->chip_info->gfx_chip_name) {
1728
case UNICHROME_CLE266:
1729
case UNICHROME_K400:
1730
via_write_reg(VIASR, SR46, (clk & 0x00FF));
1731
via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8);
1734
case UNICHROME_K800:
1735
case UNICHROME_PM800:
1736
case UNICHROME_CN700:
1737
case UNICHROME_CX700:
1738
case UNICHROME_CN750:
1739
case UNICHROME_K8M890:
1740
case UNICHROME_P4M890:
1741
case UNICHROME_P4M900:
1742
case UNICHROME_VX800:
1743
case UNICHROME_VX855:
1744
case UNICHROME_VX900:
1745
via_write_reg(VIASR, SR44, (clk & 0x0000FF));
1746
via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8);
1747
via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16);
1752
if (set_iga == IGA2) {
1753
/* Change D,N FOR LCK */
1754
switch (viaparinfo->chip_info->gfx_chip_name) {
1755
case UNICHROME_CLE266:
1756
case UNICHROME_K400:
1757
via_write_reg(VIASR, SR44, (clk & 0x00FF));
1758
via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8);
1761
case UNICHROME_K800:
1762
case UNICHROME_PM800:
1763
case UNICHROME_CN700:
1764
case UNICHROME_CX700:
1765
case UNICHROME_CN750:
1766
case UNICHROME_K8M890:
1767
case UNICHROME_P4M890:
1768
case UNICHROME_P4M900:
1769
case UNICHROME_VX800:
1770
case UNICHROME_VX855:
1771
case UNICHROME_VX900:
1772
via_write_reg(VIASR, SR4A, (clk & 0x0000FF));
1773
via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8);
1774
via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16);
1779
/* H.W. Reset : OFF */
1780
viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
1783
if (set_iga == IGA1) {
1784
viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
1785
viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
1788
if (set_iga == IGA2) {
1789
viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2);
1790
viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2);
1520
struct via_pll_config config = get_best_pll_config(clk);
1522
if (set_iga == IGA1)
1523
clock.set_primary_pll(config);
1524
if (set_iga == IGA2)
1525
clock.set_secondary_pll(config);
1794
1528
via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */