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