Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  arch/arm/mach-rpc/include/mach/acornfb.h
0004  *
0005  *  Copyright (C) 1999 Russell King
0006  *
0007  *  AcornFB architecture specific code
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      * Limits below are taken from RISC OS bandwidthlimit file
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  * Try to find the best PLL parameters for the pixel clock.
0037  * This algorithm seems to give best predictable results,
0038  * and produces the same values as detailed in the VIDC20
0039  * data sheet.
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     /* Select pixel-clock divisor to keep PLL in range */
0085     div = var->pixclock / 9090; /*9921*/
0086 
0087     /* Limit divisor */
0088     if (div == 0)
0089         div = 1;
0090     if (div > 8)
0091         div = 8;
0092 
0093     /* Encode divisor to VIDC20 setting */
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      * With VRAM, the FIFO can be set to the highest possible setting
0107      * because there are no latency considerations for other memory
0108      * accesses. However, in 64 bit bus mode the FIFO preload value
0109      * must not be set to VIDC20_CTRL_FIFO_28 because this will let
0110      * the FIFO overflow. See VIDC20 manual page 33 (6.0 Setting the
0111      * FIFO preload value).
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         /* Encode bandwidth as VIDC20 setting */
0122         if (bandwidth > 33334)      /* < 30.0MB/s */
0123             vidc->control |= VIDC20_CTRL_FIFO_16;
0124         else if (bandwidth > 26666) /* < 37.5MB/s */
0125             vidc->control |= VIDC20_CTRL_FIFO_20;
0126         else if (bandwidth > 22222) /* < 45.0MB/s */
0127             vidc->control |= VIDC20_CTRL_FIFO_24;
0128         else                /* > 45.0MB/s */
0129             vidc->control |= VIDC20_CTRL_FIFO_28;
0130     }
0131 
0132     /* Find the PLL values */
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))