[ARM] Fix ARM rwlock implementations
[linux-2.6] / include / asm-arm / arch-rpc / acornfb.h
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))