Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
acornfb.h
Go to the documentation of this file.
1 /*
2  * arch/arm/mach-rpc/include/mach/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))