import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / 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_valid_pixrate(rate) (1)
14
15 /*
16  * Try to find the best PLL parameters for the pixel clock.
17  * This algorithm seems to give best predictable results,
18  * and produces the same values as detailed in the VIDC20
19  * data sheet.
20  */
21 static inline u_int
22 acornfb_vidc20_find_pll(u_int pixclk)
23 {
24         u_int r, best_r = 2, best_v = 2;
25         int best_d = 0x7fffffff;
26
27         for (r = 2; r <= 32; r++) {
28                 u_int rr, v, p;
29                 int d;
30
31                 rr = 41667 * r;
32
33                 v = (rr + pixclk / 2) / pixclk;
34
35                 if (v > 32 || v < 2)
36                         continue;
37
38                 p = (rr + v / 2) / v;
39
40                 d = pixclk - p;
41
42                 if (d < 0)
43                         d = -d;
44
45                 if (d < best_d) {
46                         best_d = d;
47                         best_v = v - 1;
48                         best_r = r - 1;
49                 }
50
51                 if (d == 0)
52                         break;
53         }
54
55         return best_v << 8 | best_r;
56 }
57
58 static inline void
59 acornfb_vidc20_find_rates(struct vidc_timing *vidc,
60                           struct fb_var_screeninfo *var)
61 {
62         u_int div, bandwidth;
63
64         /* Select pixel-clock divisor to keep PLL in range */
65         div = var->pixclock / 9090; /*9921*/
66
67         /* Limit divisor */
68         if (div == 0)
69                 div = 1;
70         if (div > 8)
71                 div = 8;
72
73         /* Encode divisor to VIDC20 setting */
74         switch (div) {
75         case 1: vidc->control |= VIDC20_CTRL_PIX_CK;  break;
76         case 2: vidc->control |= VIDC20_CTRL_PIX_CK2; break;
77         case 3: vidc->control |= VIDC20_CTRL_PIX_CK3; break;
78         case 4: vidc->control |= VIDC20_CTRL_PIX_CK4; break;
79         case 5: vidc->control |= VIDC20_CTRL_PIX_CK5; break;
80         case 6: vidc->control |= VIDC20_CTRL_PIX_CK6; break;
81         case 7: vidc->control |= VIDC20_CTRL_PIX_CK7; break;
82         case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break;
83         }
84
85         /* Calculate bandwidth */
86         bandwidth = var->pixclock * 8 / var->bits_per_pixel;
87
88         /* Encode bandwidth as VIDC20 setting */
89         if (bandwidth > 33334)
90                 vidc->control |= VIDC20_CTRL_FIFO_16;   /* < 30.0MB/s */
91         else if (bandwidth > 26666)
92                 vidc->control |= VIDC20_CTRL_FIFO_20;   /* < 37.5MB/s */
93         else if (bandwidth > 22222)
94                 vidc->control |= VIDC20_CTRL_FIFO_24;   /* < 45.0MB/s */
95         else
96                 vidc->control |= VIDC20_CTRL_FIFO_28;   /* > 45.0MB/s */
97
98         /* Find the PLL values */
99         vidc->pll_ctl  = acornfb_vidc20_find_pll(var->pixclock / div);
100 }
101
102 #define acornfb_default_control()       (VIDC20_CTRL_PIX_VCLK)
103 #define acornfb_default_econtrol()      (VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3))