0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define acornfb_bandwidth(var) ((var)->pixclock * 8 / (var)->bits_per_pixel)
0011
0012 static inline int
0013 acornfb_valid_pixrate(struct fb_var_screeninfo *var)
0014 {
0015 u_long limit;
0016
0017 if (!var->pixclock)
0018 return 0;
0019
0020
0021
0022
0023 if (current_par.using_vram) {
0024 if (current_par.vram_half_sam == 2048)
0025 limit = 6578;
0026 else
0027 limit = 13157;
0028 } else {
0029 limit = 26315;
0030 }
0031
0032 return acornfb_bandwidth(var) >= limit;
0033 }
0034
0035
0036
0037
0038
0039
0040
0041 static inline u_int
0042 acornfb_vidc20_find_pll(u_int pixclk)
0043 {
0044 u_int r, best_r = 2, best_v = 2;
0045 int best_d = 0x7fffffff;
0046
0047 for (r = 2; r <= 32; r++) {
0048 u_int rr, v, p;
0049 int d;
0050
0051 rr = 41667 * r;
0052
0053 v = (rr + pixclk / 2) / pixclk;
0054
0055 if (v > 32 || v < 2)
0056 continue;
0057
0058 p = (rr + v / 2) / v;
0059
0060 d = pixclk - p;
0061
0062 if (d < 0)
0063 d = -d;
0064
0065 if (d < best_d) {
0066 best_d = d;
0067 best_v = v - 1;
0068 best_r = r - 1;
0069 }
0070
0071 if (d == 0)
0072 break;
0073 }
0074
0075 return best_v << 8 | best_r;
0076 }
0077
0078 static inline void
0079 acornfb_vidc20_find_rates(struct vidc_timing *vidc,
0080 struct fb_var_screeninfo *var)
0081 {
0082 u_int div;
0083
0084
0085 div = var->pixclock / 9090;
0086
0087
0088 if (div == 0)
0089 div = 1;
0090 if (div > 8)
0091 div = 8;
0092
0093
0094 switch (div) {
0095 case 1: vidc->control |= VIDC20_CTRL_PIX_CK; break;
0096 case 2: vidc->control |= VIDC20_CTRL_PIX_CK2; break;
0097 case 3: vidc->control |= VIDC20_CTRL_PIX_CK3; break;
0098 case 4: vidc->control |= VIDC20_CTRL_PIX_CK4; break;
0099 case 5: vidc->control |= VIDC20_CTRL_PIX_CK5; break;
0100 case 6: vidc->control |= VIDC20_CTRL_PIX_CK6; break;
0101 case 7: vidc->control |= VIDC20_CTRL_PIX_CK7; break;
0102 case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break;
0103 }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 if (current_par.using_vram) {
0114 if (current_par.vram_half_sam == 2048)
0115 vidc->control |= VIDC20_CTRL_FIFO_24;
0116 else
0117 vidc->control |= VIDC20_CTRL_FIFO_28;
0118 } else {
0119 unsigned long bandwidth = acornfb_bandwidth(var);
0120
0121
0122 if (bandwidth > 33334)
0123 vidc->control |= VIDC20_CTRL_FIFO_16;
0124 else if (bandwidth > 26666)
0125 vidc->control |= VIDC20_CTRL_FIFO_20;
0126 else if (bandwidth > 22222)
0127 vidc->control |= VIDC20_CTRL_FIFO_24;
0128 else
0129 vidc->control |= VIDC20_CTRL_FIFO_28;
0130 }
0131
0132
0133 vidc->pll_ctl = acornfb_vidc20_find_pll(var->pixclock / div);
0134 }
0135
0136 #define acornfb_default_control() (VIDC20_CTRL_PIX_VCLK)
0137 #define acornfb_default_econtrol() (VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3))