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