acornfb.h 3.3 KB

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