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