Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/include/asm-arm/arch-rpc/acornfb.h | |
3 | * | |
4 | * Copyright (C) 1999 Russell King | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * AcornFB architecture specific code | |
11 | */ | |
12 | ||
13 | #define acornfb_bandwidth(var) ((var)->pixclock * 8 / (var)->bits_per_pixel) | |
14 | ||
15 | static inline int | |
16 | acornfb_valid_pixrate(struct fb_var_screeninfo *var) | |
17 | { | |
18 | u_long limit; | |
19 | ||
20 | if (!var->pixclock) | |
21 | return 0; | |
22 | ||
23 | /* | |
24 | * Limits below are taken from RISC OS bandwidthlimit file | |
25 | */ | |
26 | if (current_par.using_vram) { | |
27 | if (current_par.vram_half_sam == 2048) | |
28 | limit = 6578; | |
29 | else | |
30 | limit = 13157; | |
31 | } else { | |
32 | limit = 26315; | |
33 | } | |
34 | ||
35 | return acornfb_bandwidth(var) >= limit; | |
36 | } | |
37 | ||
38 | /* | |
39 | * Try to find the best PLL parameters for the pixel clock. | |
40 | * This algorithm seems to give best predictable results, | |
41 | * and produces the same values as detailed in the VIDC20 | |
42 | * data sheet. | |
43 | */ | |
44 | static inline u_int | |
45 | acornfb_vidc20_find_pll(u_int pixclk) | |
46 | { | |
47 | u_int r, best_r = 2, best_v = 2; | |
48 | int best_d = 0x7fffffff; | |
49 | ||
50 | for (r = 2; r <= 32; r++) { | |
51 | u_int rr, v, p; | |
52 | int d; | |
53 | ||
54 | rr = 41667 * r; | |
55 | ||
56 | v = (rr + pixclk / 2) / pixclk; | |
57 | ||
58 | if (v > 32 || v < 2) | |
59 | continue; | |
60 | ||
61 | p = (rr + v / 2) / v; | |
62 | ||
63 | d = pixclk - p; | |
64 | ||
65 | if (d < 0) | |
66 | d = -d; | |
67 | ||
68 | if (d < best_d) { | |
69 | best_d = d; | |
70 | best_v = v - 1; | |
71 | best_r = r - 1; | |
72 | } | |
73 | ||
74 | if (d == 0) | |
75 | break; | |
76 | } | |
77 | ||
78 | return best_v << 8 | best_r; | |
79 | } | |
80 | ||
81 | static inline void | |
82 | acornfb_vidc20_find_rates(struct vidc_timing *vidc, | |
83 | struct fb_var_screeninfo *var) | |
84 | { | |
85 | u_int div; | |
86 | ||
87 | /* Select pixel-clock divisor to keep PLL in range */ | |
88 | div = var->pixclock / 9090; /*9921*/ | |
89 | ||
90 | /* Limit divisor */ | |
91 | if (div == 0) | |
92 | div = 1; | |
93 | if (div > 8) | |
94 | div = 8; | |
95 | ||
96 | /* Encode divisor to VIDC20 setting */ | |
97 | switch (div) { | |
98 | case 1: vidc->control |= VIDC20_CTRL_PIX_CK; break; | |
99 | case 2: vidc->control |= VIDC20_CTRL_PIX_CK2; break; | |
100 | case 3: vidc->control |= VIDC20_CTRL_PIX_CK3; break; | |
101 | case 4: vidc->control |= VIDC20_CTRL_PIX_CK4; break; | |
102 | case 5: vidc->control |= VIDC20_CTRL_PIX_CK5; break; | |
103 | case 6: vidc->control |= VIDC20_CTRL_PIX_CK6; break; | |
104 | case 7: vidc->control |= VIDC20_CTRL_PIX_CK7; break; | |
105 | case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break; | |
106 | } | |
107 | ||
108 | /* | |
109 | * With VRAM, the FIFO can be set to the highest possible setting | |
110 | * because there are no latency considerations for other memory | |
111 | * accesses. However, in 64 bit bus mode the FIFO preload value | |
112 | * must not be set to VIDC20_CTRL_FIFO_28 because this will let | |
113 | * the FIFO overflow. See VIDC20 manual page 33 (6.0 Setting the | |
114 | * FIFO preload value). | |
115 | */ | |
116 | if (current_par.using_vram) { | |
117 | if (current_par.vram_half_sam == 2048) | |
118 | vidc->control |= VIDC20_CTRL_FIFO_24; | |
119 | else | |
120 | vidc->control |= VIDC20_CTRL_FIFO_28; | |
121 | } else { | |
122 | unsigned long bandwidth = acornfb_bandwidth(var); | |
123 | ||
124 | /* Encode bandwidth as VIDC20 setting */ | |
125 | if (bandwidth > 33334) /* < 30.0MB/s */ | |
126 | vidc->control |= VIDC20_CTRL_FIFO_16; | |
127 | else if (bandwidth > 26666) /* < 37.5MB/s */ | |
128 | vidc->control |= VIDC20_CTRL_FIFO_20; | |
129 | else if (bandwidth > 22222) /* < 45.0MB/s */ | |
130 | vidc->control |= VIDC20_CTRL_FIFO_24; | |
131 | else /* > 45.0MB/s */ | |
132 | vidc->control |= VIDC20_CTRL_FIFO_28; | |
133 | } | |
134 | ||
135 | /* Find the PLL values */ | |
136 | vidc->pll_ctl = acornfb_vidc20_find_pll(var->pixclock / div); | |
137 | } | |
138 | ||
139 | #define acornfb_default_control() (VIDC20_CTRL_PIX_VCLK) | |
140 | #define acornfb_default_econtrol() (VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3)) |