xref: /linux/drivers/gpu/drm/mgag200/mgag200_drv.h (revision 1baf9127c482a3a58aef81d92ae751798e2db202)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2010 Matt Turner.
4  * Copyright 2012 Red Hat
5  *
6  * Authors: Matthew Garrett
7  * 	    Matt Turner
8  *	    Dave Airlie
9  */
10 #ifndef __MGAG200_DRV_H__
11 #define __MGAG200_DRV_H__
12 
13 #include <linux/i2c-algo-bit.h>
14 #include <linux/i2c.h>
15 
16 #include <video/vga.h>
17 
18 #include <drm/drm_connector.h>
19 #include <drm/drm_crtc.h>
20 #include <drm/drm_encoder.h>
21 #include <drm/drm_fb_helper.h>
22 #include <drm/drm_gem.h>
23 #include <drm/drm_gem_shmem_helper.h>
24 #include <drm/drm_plane.h>
25 
26 #include "mgag200_reg.h"
27 
28 #define DRIVER_AUTHOR		"Matthew Garrett"
29 
30 #define DRIVER_NAME		"mgag200"
31 #define DRIVER_DESC		"MGA G200 SE"
32 #define DRIVER_DATE		"20110418"
33 
34 #define DRIVER_MAJOR		1
35 #define DRIVER_MINOR		0
36 #define DRIVER_PATCHLEVEL	0
37 
38 #define RREG8(reg) ioread8(((void __iomem *)mdev->rmmio) + (reg))
39 #define WREG8(reg, v) iowrite8(v, ((void __iomem *)mdev->rmmio) + (reg))
40 #define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg))
41 #define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg))
42 
43 #define MGA_BIOS_OFFSET		0x7ffc
44 
45 #define ATTR_INDEX 0x1fc0
46 #define ATTR_DATA 0x1fc1
47 
48 #define WREG_MISC(v)						\
49 	WREG8(MGA_MISC_OUT, v)
50 
51 #define RREG_MISC(v)						\
52 	((v) = RREG8(MGA_MISC_IN))
53 
54 #define WREG_MISC_MASKED(v, mask)				\
55 	do {							\
56 		u8 misc_;					\
57 		u8 mask_ = (mask);				\
58 		RREG_MISC(misc_);				\
59 		misc_ &= ~mask_;				\
60 		misc_ |= ((v) & mask_);				\
61 		WREG_MISC(misc_);				\
62 	} while (0)
63 
64 #define WREG_ATTR(reg, v)					\
65 	do {							\
66 		RREG8(0x1fda);					\
67 		WREG8(ATTR_INDEX, reg);				\
68 		WREG8(ATTR_DATA, v);				\
69 	} while (0)						\
70 
71 #define RREG_SEQ(reg, v)					\
72 	do {							\
73 		WREG8(MGAREG_SEQ_INDEX, reg);			\
74 		v = RREG8(MGAREG_SEQ_DATA);			\
75 	} while (0)						\
76 
77 #define WREG_SEQ(reg, v)					\
78 	do {							\
79 		WREG8(MGAREG_SEQ_INDEX, reg);			\
80 		WREG8(MGAREG_SEQ_DATA, v);			\
81 	} while (0)						\
82 
83 #define RREG_CRT(reg, v)					\
84 	do {							\
85 		WREG8(MGAREG_CRTC_INDEX, reg);			\
86 		v = RREG8(MGAREG_CRTC_DATA);			\
87 	} while (0)						\
88 
89 #define WREG_CRT(reg, v)					\
90 	do {							\
91 		WREG8(MGAREG_CRTC_INDEX, reg);			\
92 		WREG8(MGAREG_CRTC_DATA, v);			\
93 	} while (0)						\
94 
95 #define RREG_ECRT(reg, v)					\
96 	do {							\
97 		WREG8(MGAREG_CRTCEXT_INDEX, reg);		\
98 		v = RREG8(MGAREG_CRTCEXT_DATA);			\
99 	} while (0)						\
100 
101 #define WREG_ECRT(reg, v)					\
102 	do {							\
103 		WREG8(MGAREG_CRTCEXT_INDEX, reg);				\
104 		WREG8(MGAREG_CRTCEXT_DATA, v);				\
105 	} while (0)						\
106 
107 #define GFX_INDEX 0x1fce
108 #define GFX_DATA 0x1fcf
109 
110 #define WREG_GFX(reg, v)					\
111 	do {							\
112 		WREG8(GFX_INDEX, reg);				\
113 		WREG8(GFX_DATA, v);				\
114 	} while (0)						\
115 
116 #define DAC_INDEX 0x3c00
117 #define DAC_DATA 0x3c0a
118 
119 #define WREG_DAC(reg, v)					\
120 	do {							\
121 		WREG8(DAC_INDEX, reg);				\
122 		WREG8(DAC_DATA, v);				\
123 	} while (0)						\
124 
125 #define MGA_MISC_OUT 0x1fc2
126 #define MGA_MISC_IN 0x1fcc
127 
128 /*
129  * TODO: This is a pretty large set of default values for all kinds of
130  *       settings. It should be split and set in the various DRM helpers,
131  *       such as the CRTC reset or atomic_enable helpers. The PLL values
132  *       probably belong to each model's PLL code.
133  */
134 #define MGAG200_DAC_DEFAULT(xvrefctrl, xpixclkctrl, xmiscctrl, xsyspllm, xsysplln, xsyspllp)	\
135 	/* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,				\
136 	/* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,				\
137 	/* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,				\
138 	/* 0x18: */     (xvrefctrl),								\
139 	/* 0x19: */        0,									\
140 	/* 0x1a: */     (xpixclkctrl),								\
141 	/* 0x1b: */     0xff, 0xbf, 0x20,							\
142 	/* 0x1e: */	(xmiscctrl),								\
143 	/* 0x1f: */	0x20,									\
144 	/* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,				\
145 	/* 0x28: */     0x00, 0x00, 0x00, 0x00,							\
146 	/* 0x2c: */     (xsyspllm),								\
147 	/* 0x2d: */     (xsysplln),								\
148 	/* 0x2e: */     (xsyspllp),								\
149 	/* 0x2f: */     0x40,									\
150 	/* 0x30: */     0x00, 0xb0, 0x00, 0xc2, 0x34, 0x14, 0x02, 0x83,				\
151 	/* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3a,				\
152 	/* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,				\
153 	/* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0				\
154 
155 #define MGAG200_MAX_FB_HEIGHT 4096
156 #define MGAG200_MAX_FB_WIDTH 4096
157 
158 struct mga_device;
159 struct mgag200_pll;
160 
161 /*
162  * Stores parameters for programming the PLLs
163  *
164  * Fref: reference frequency (A: 25.175 Mhz, B: 28.361, C: XX Mhz)
165  * Fo: output frequency
166  * Fvco = Fref * (N / M)
167  * Fo = Fvco / P
168  *
169  * S = [0..3]
170  */
171 struct mgag200_pll_values {
172 	unsigned int m;
173 	unsigned int n;
174 	unsigned int p;
175 	unsigned int s;
176 };
177 
178 struct mgag200_pll_funcs {
179 	int (*compute)(struct mgag200_pll *pll, long clock, struct mgag200_pll_values *pllc);
180 	void (*update)(struct mgag200_pll *pll, const struct mgag200_pll_values *pllc);
181 };
182 
183 struct mgag200_pll {
184 	struct mga_device *mdev;
185 
186 	const struct mgag200_pll_funcs *funcs;
187 };
188 
189 struct mgag200_crtc_state {
190 	struct drm_crtc_state base;
191 
192 	/* Primary-plane format; required for modesetting and color mgmt. */
193 	const struct drm_format_info *format;
194 
195 	struct mgag200_pll_values pixpllc;
196 };
197 
198 static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_state *base)
199 {
200 	return container_of(base, struct mgag200_crtc_state, base);
201 }
202 
203 struct mga_i2c_chan {
204 	struct i2c_adapter adapter;
205 	struct drm_device *dev;
206 	struct i2c_algo_bit_data bit;
207 	int data, clock;
208 };
209 
210 enum mga_type {
211 	G200_PCI,
212 	G200_AGP,
213 	G200_SE_A,
214 	G200_SE_B,
215 	G200_WB,
216 	G200_EV,
217 	G200_EH,
218 	G200_EH3,
219 	G200_ER,
220 	G200_EW3,
221 };
222 
223 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
224 
225 struct mgag200_device_info {
226 	u16 max_hdisplay;
227 	u16 max_vdisplay;
228 
229 	/*
230 	 * Maximum memory bandwidth (MiB/sec). Setting this to zero disables
231 	 * the rsp test during mode validation.
232 	 */
233 	unsigned long max_mem_bandwidth;
234 
235 	/* HW has external source (e.g., BMC) to synchronize with */
236 	bool has_vidrst:1;
237 
238 	struct {
239 		unsigned data_bit:3;
240 		unsigned clock_bit:3;
241 	} i2c;
242 
243 	/*
244 	 * HW does not handle 'startadd' register correctly. Always set
245 	 * it's value to 0.
246 	 */
247 	bool bug_no_startadd:1;
248 };
249 
250 #define MGAG200_DEVICE_INFO_INIT(_max_hdisplay, _max_vdisplay, _max_mem_bandwidth, \
251 				 _has_vidrst, _i2c_data_bit, _i2c_clock_bit, \
252 				 _bug_no_startadd) \
253 	{ \
254 		.max_hdisplay = (_max_hdisplay), \
255 		.max_vdisplay = (_max_vdisplay), \
256 		.max_mem_bandwidth = (_max_mem_bandwidth), \
257 		.has_vidrst = (_has_vidrst), \
258 		.i2c = { \
259 			.data_bit = (_i2c_data_bit), \
260 			.clock_bit = (_i2c_clock_bit), \
261 		}, \
262 		.bug_no_startadd = (_bug_no_startadd), \
263 	}
264 
265 struct mga_device {
266 	struct drm_device base;
267 
268 	const struct mgag200_device_info *info;
269 
270 	struct resource			*rmmio_res;
271 	void __iomem			*rmmio;
272 	struct mutex			rmmio_lock; /* Protects access to rmmio */
273 
274 	struct resource			*vram_res;
275 	void __iomem			*vram;
276 	resource_size_t			vram_available;
277 
278 	enum mga_type			type;
279 
280 	struct mgag200_pll pixpll;
281 	struct drm_plane primary_plane;
282 	struct drm_crtc crtc;
283 	struct drm_encoder encoder;
284 	struct mga_i2c_chan i2c;
285 	struct drm_connector connector;
286 };
287 
288 static inline struct mga_device *to_mga_device(struct drm_device *dev)
289 {
290 	return container_of(dev, struct mga_device, base);
291 }
292 
293 struct mgag200_g200_device {
294 	struct mga_device base;
295 
296 	/* PLL constants */
297 	long ref_clk;
298 	long pclk_min;
299 	long pclk_max;
300 };
301 
302 static inline struct mgag200_g200_device *to_mgag200_g200_device(struct drm_device *dev)
303 {
304 	return container_of(to_mga_device(dev), struct mgag200_g200_device, base);
305 }
306 
307 struct mgag200_g200se_device {
308 	struct mga_device base;
309 
310 	/* SE model number stored in reg 0x1e24 */
311 	u32 unique_rev_id;
312 };
313 
314 static inline struct mgag200_g200se_device *to_mgag200_g200se_device(struct drm_device *dev)
315 {
316 	return container_of(to_mga_device(dev), struct mgag200_g200se_device, base);
317 }
318 
319 				/* mgag200_drv.c */
320 int mgag200_init_pci_options(struct pci_dev *pdev, u32 option, u32 option2);
321 resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size);
322 resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
323 int mgag200_device_preinit(struct mga_device *mdev);
324 int mgag200_device_init(struct mga_device *mdev, enum mga_type type,
325 			const struct mgag200_device_info *info);
326 
327 				/* mgag200_<device type>.c */
328 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
329 					      enum mga_type type);
330 struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
331 						enum mga_type type);
332 void mgag200_g200wb_init_registers(struct mga_device *mdev);
333 struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
334 						enum mga_type type);
335 struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
336 						enum mga_type type);
337 void mgag200_g200eh_init_registers(struct mga_device *mdev);
338 struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
339 						enum mga_type type);
340 struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
341 						 enum mga_type type);
342 struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
343 						enum mga_type type);
344 struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
345 						 enum mga_type type);
346 
347 				/* mgag200_mode.c */
348 resource_size_t mgag200_device_probe_vram(struct mga_device *mdev);
349 void mgag200_init_registers(struct mga_device *mdev);
350 int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_fb_available);
351 
352 				/* mgag200_i2c.c */
353 int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
354 
355 				/* mgag200_pll.c */
356 int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev);
357 
358 #endif				/* __MGAG200_DRV_H__ */
359