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