1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef LYNXDRV_H_
3#define LYNXDRV_H_
4
5#define FB_ACCEL_SMI 0xab
6
7#define MHZ(x) ((x) * 1000000)
8
9#define DEFAULT_SM750_CHIP_CLOCK	290
10#define DEFAULT_SM750LE_CHIP_CLOCK	333
11#ifndef SM750LE_REVISION_ID
12#define SM750LE_REVISION_ID ((unsigned char)0xfe)
13#endif
14
15enum sm750_pnltype {
16	sm750_24TFT = 0,	/* 24bit tft */
17	sm750_dualTFT = 2,	/* dual 18 bit tft */
18	sm750_doubleTFT = 1,	/* 36 bit double pixel tft */
19};
20
21/* vga channel is not concerned  */
22enum sm750_dataflow {
23	sm750_simul_pri,	/* primary => all head */
24	sm750_simul_sec,	/* secondary => all head */
25	sm750_dual_normal,	/* primary => panel head and secondary => crt */
26	sm750_dual_swap,	/* primary => crt head and secondary => panel */
27};
28
29enum sm750_channel {
30	sm750_primary = 0,
31	/* enum value equal to the register filed data */
32	sm750_secondary = 1,
33};
34
35enum sm750_path {
36	sm750_panel = 1,
37	sm750_crt = 2,
38	sm750_pnc = 3,	/* panel and crt */
39};
40
41struct init_status {
42	ushort powerMode;
43	/* below three clocks are in unit of MHZ*/
44	ushort chip_clk;
45	ushort mem_clk;
46	ushort master_clk;
47	ushort setAllEngOff;
48	ushort resetMemory;
49};
50
51struct lynx_accel {
52	/* base virtual address of DPR registers */
53	volatile unsigned char __iomem *dprBase;
54	/* base virtual address of de data port */
55	volatile unsigned char __iomem *dpPortBase;
56
57	/* function pointers */
58	void (*de_init)(struct lynx_accel *accel);
59
60	int (*de_wait)(void);/* see if hardware ready to work */
61
62	int (*de_fillrect)(struct lynx_accel *accel,
63			   u32 base, u32 pitch, u32 bpp,
64			   u32 x, u32 y, u32 width, u32 height,
65			   u32 color, u32 rop);
66
67	int (*de_copyarea)(struct lynx_accel *accel,
68			   u32 s_base, u32 s_pitch,
69			   u32 sx, u32 sy,
70			   u32 d_base, u32 d_pitch,
71			   u32 bpp, u32 dx, u32 dy,
72			   u32 width, u32 height,
73			   u32 rop2);
74
75	int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf,
76			    u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch,
77			    u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
78			    u32 height, u32 f_color, u32 b_color, u32 rop2);
79
80};
81
82struct sm750_dev {
83	/* common members */
84	u16 devid;
85	u8 revid;
86	struct pci_dev *pdev;
87	struct fb_info *fbinfo[2];
88	struct lynx_accel accel;
89	int accel_off;
90	int fb_count;
91	int mtrr_off;
92	struct{
93		int vram;
94	} mtrr;
95	/* all smi graphic adaptor got below attributes */
96	unsigned long vidmem_start;
97	unsigned long vidreg_start;
98	__u32 vidmem_size;
99	__u32 vidreg_size;
100	void __iomem *pvReg;
101	unsigned char __iomem *pvMem;
102	/* locks*/
103	spinlock_t slock;
104
105	struct init_status initParm;
106	enum sm750_pnltype pnltype;
107	enum sm750_dataflow dataflow;
108	int nocrt;
109
110	/*
111	 * 0: no hardware cursor
112	 * 1: primary crtc hw cursor enabled,
113	 * 2: secondary crtc hw cursor enabled
114	 * 3: both ctrc hw cursor enabled
115	 */
116	int hwCursor;
117};
118
119struct lynx_cursor {
120	/* cursor width ,height and size */
121	int w;
122	int h;
123	int size;
124	/* hardware limitation */
125	int max_w;
126	int max_h;
127	/* base virtual address and offset  of cursor image */
128	char __iomem *vstart;
129	int offset;
130	/* mmio addr of hw cursor */
131	volatile char __iomem *mmio;
132};
133
134struct lynxfb_crtc {
135	unsigned char __iomem *v_cursor; /* virtual address of cursor */
136	unsigned char __iomem *v_screen; /* virtual address of on_screen */
137	int o_cursor; /* cursor address offset in vidmem */
138	int o_screen; /* onscreen address offset in vidmem */
139	int channel;/* which channel this crtc stands for*/
140	resource_size_t vidmem_size;/* this view's video memory max size */
141
142	/* below attributes belong to info->fix, their value depends on specific adaptor*/
143	u16 line_pad;/* padding information:0,1,2,4,8,16,... */
144	u16 xpanstep;
145	u16 ypanstep;
146	u16 ywrapstep;
147
148	void *priv;
149
150	/* cursor information */
151	struct lynx_cursor cursor;
152};
153
154struct lynxfb_output {
155	int dpms;
156	int paths;
157	/*
158	 * which paths(s) this output stands for,for sm750:
159	 * paths=1:means output for panel paths
160	 * paths=2:means output for crt paths
161	 * paths=3:means output for both panel and crt paths
162	 */
163
164	int *channel;
165	/*
166	 * which channel these outputs linked with,for sm750:
167	 * *channel=0 means primary channel
168	 * *channel=1 means secondary channel
169	 * output->channel ==> &crtc->channel
170	 */
171	void *priv;
172
173	int (*proc_setBLANK)(struct lynxfb_output *output, int blank);
174};
175
176struct lynxfb_par {
177	/* either 0 or 1 for dual head adaptor,0 is the older one registered */
178	int index;
179	unsigned int pseudo_palette[256];
180	struct lynxfb_crtc crtc;
181	struct lynxfb_output output;
182	struct fb_info *info;
183	struct sm750_dev *dev;
184};
185
186static inline unsigned long ps_to_hz(unsigned int psvalue)
187{
188	unsigned long long numerator = 1000 * 1000 * 1000 * 1000ULL;
189	/* 10^12 / picosecond period gives frequency in Hz */
190	do_div(numerator, psvalue);
191	return (unsigned long)numerator;
192}
193
194int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev);
195int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev);
196void hw_sm750_initAccel(struct sm750_dev *sm750_dev);
197int hw_sm750_deWait(void);
198int hw_sm750le_deWait(void);
199
200int hw_sm750_output_setMode(struct lynxfb_output *output,
201			    struct fb_var_screeninfo *var,
202			    struct fb_fix_screeninfo *fix);
203
204int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc,
205			    struct fb_var_screeninfo *var);
206
207int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
208			  struct fb_var_screeninfo *var,
209			  struct fb_fix_screeninfo *fix);
210
211int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index,
212		       ushort red, ushort green, ushort blue);
213
214int hw_sm750_setBLANK(struct lynxfb_output *output, int blank);
215int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank);
216int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
217			 const struct fb_var_screeninfo *var,
218			 const struct fb_info *info);
219
220#endif
221