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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
#ifndef LYNXDRV_H_
#define LYNXDRV_H_
#define FB_ACCEL_SMI 0xab
/* please use revision id to distinguish sm750le and sm750*/
#define SPC_SM750 0
//#define SPC_SM750LE 8
#define MB(x) ((x)<<20)
#define MHZ(x) ((x) * 1000000)
/* align should be 2,4,8,16 */
#define PADDING(align,data) (((data)+(align)-1)&(~((align) -1)))
extern int smi_indent;
struct lynx_accel{
/* base virtual address of DPR registers */
volatile unsigned char __iomem * dprBase;
/* base virtual address of de data port */
volatile unsigned char __iomem * dpPortBase;
/* function fointers */
void (*de_init)(struct lynx_accel *);
int (*de_wait)(void);/* see if hardware ready to work */
int (*de_fillrect)(struct lynx_accel *,u32,u32,u32,
u32,u32,u32,u32,u32,u32);
int (*de_copyarea)(struct lynx_accel *,u32,u32,u32,u32,
u32,u32,u32,u32,
u32,u32,u32,u32);
int (*de_imageblit)(struct lynx_accel *,const char *,u32,u32,u32,
u32,u32,u32,u32,u32,u32,u32,u32,u32);
};
/* lynx_share stands for a presentation of two frame buffer
that use one smi adaptor , it is similar to a basic class of C++
*/
struct lynx_share{
/* common members */
u16 devid;
u8 revid;
struct pci_dev * pdev;
struct fb_info * fbinfo[2];
struct lynx_accel accel;
int accel_off;
int dual;
#ifdef CONFIG_MTRR
int mtrr_off;
struct{
int vram;
int vram_added;
}mtrr;
#endif
/* all smi graphic adaptor got below attributes */
unsigned long vidmem_start;
unsigned long vidreg_start;
__u32 vidmem_size;
__u32 vidreg_size;
void __iomem * pvReg;
unsigned char __iomem * pvMem;
/* locks*/
spinlock_t slock;
/* function pointers */
void (*suspend)(struct lynx_share*);
void (*resume)(struct lynx_share*);
};
struct lynx_cursor{
/* cursor width ,height and size */
int w;
int h;
int size;
/* hardware limitation */
int maxW;
int maxH;
/* base virtual address and offset of cursor image */
char __iomem * vstart;
int offset;
/* mmio addr of hw cursor */
volatile char __iomem * mmio;
/* the lynx_share of this adaptor */
struct lynx_share * share;
/* proc_routines */
void (*enable)(struct lynx_cursor *);
void (*disable)(struct lynx_cursor *);
void (*setSize)(struct lynx_cursor *,int,int);
void (*setPos)(struct lynx_cursor *,int,int);
void (*setColor)(struct lynx_cursor *,u32,u32);
void (*setData)(struct lynx_cursor *,u16,const u8*,const u8*);
};
struct lynxfb_crtc{
unsigned char __iomem * vCursor;//virtual address of cursor
unsigned char __iomem * vScreen;//virtual address of on_screen
int oCursor;//cursor address offset in vidmem
int oScreen;//onscreen address offset in vidmem
int channel;/* which channel this crtc stands for*/
resource_size_t vidmem_size;/* this view's video memory max size */
/* below attributes belong to info->fix, their value depends on specific adaptor*/
u16 line_pad;/* padding information:0,1,2,4,8,16,... */
u16 xpanstep;
u16 ypanstep;
u16 ywrapstep;
void * priv;
int(*proc_setMode)(struct lynxfb_crtc*,
struct fb_var_screeninfo*,
struct fb_fix_screeninfo*);
int(*proc_checkMode)(struct lynxfb_crtc*,struct fb_var_screeninfo*);
int(*proc_setColReg)(struct lynxfb_crtc*,ushort,ushort,ushort,ushort);
void (*clear)(struct lynxfb_crtc*);
/* pan display */
int (*proc_panDisplay)(struct lynxfb_crtc *,
const struct fb_var_screeninfo *,
const struct fb_info *);
/* cursor information */
struct lynx_cursor cursor;
};
struct lynxfb_output{
int dpms;
int paths;
/* which paths(s) this output stands for,for sm750:
paths=1:means output for panel paths
paths=2:means output for crt paths
paths=3:means output for both panel and crt paths
*/
int * channel;
/* which channel these outputs linked with,for sm750:
*channel=0 means primary channel
*channel=1 means secondary channel
output->channel ==> &crtc->channel
*/
void * priv;
int(*proc_setMode)(struct lynxfb_output*,
struct fb_var_screeninfo*,
struct fb_fix_screeninfo*);
int(*proc_checkMode)(struct lynxfb_output*,struct fb_var_screeninfo*);
int(*proc_setBLANK)(struct lynxfb_output*,int);
void (*clear)(struct lynxfb_output*);
};
struct lynxfb_par{
/* either 0 or 1 for dual head adaptor,0 is the older one registered */
int index;
unsigned int pseudo_palette[256];
struct lynxfb_crtc crtc;
struct lynxfb_output output;
struct fb_info * info;
struct lynx_share * share;
};
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#define PS_TO_HZ(ps) \
({ \
unsigned long long hz = 1000*1000*1000*1000ULL; \
do_div(hz,ps); \
(unsigned long)hz;})
static inline unsigned long ps_to_hz(unsigned int psvalue)
{
unsigned long long numerator=1000*1000*1000*1000ULL;
/* 10^12 / picosecond period gives frequency in Hz */
do_div(numerator, psvalue);
return (unsigned long)numerator;
}
#endif
|