• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_encoder.h>
19 #include <drm/drm_fb_helper.h>
20 #include <drm/drm_gem.h>
21 #include <drm/drm_gem_vram_helper.h>
22 #include <drm/drm_vram_mm_helper.h>
23 
24 #include "mgag200_reg.h"
25 
26 #define DRIVER_AUTHOR		"Matthew Garrett"
27 
28 #define DRIVER_NAME		"mgag200"
29 #define DRIVER_DESC		"MGA G200 SE"
30 #define DRIVER_DATE		"20110418"
31 
32 #define DRIVER_MAJOR		1
33 #define DRIVER_MINOR		0
34 #define DRIVER_PATCHLEVEL	0
35 
36 #define MGAG200FB_CONN_LIMIT 1
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 ATTR_INDEX 0x1fc0
44 #define ATTR_DATA 0x1fc1
45 
46 #define WREG_ATTR(reg, v)					\
47 	do {							\
48 		RREG8(0x1fda);					\
49 		WREG8(ATTR_INDEX, reg);				\
50 		WREG8(ATTR_DATA, v);				\
51 	} while (0)						\
52 
53 #define WREG_SEQ(reg, v)					\
54 	do {							\
55 		WREG8(MGAREG_SEQ_INDEX, reg);			\
56 		WREG8(MGAREG_SEQ_DATA, v);			\
57 	} while (0)						\
58 
59 #define WREG_CRT(reg, v)					\
60 	do {							\
61 		WREG8(MGAREG_CRTC_INDEX, reg);			\
62 		WREG8(MGAREG_CRTC_DATA, v);			\
63 	} while (0)						\
64 
65 
66 #define WREG_ECRT(reg, v)					\
67 	do {							\
68 		WREG8(MGAREG_CRTCEXT_INDEX, reg);				\
69 		WREG8(MGAREG_CRTCEXT_DATA, v);				\
70 	} while (0)						\
71 
72 #define GFX_INDEX 0x1fce
73 #define GFX_DATA 0x1fcf
74 
75 #define WREG_GFX(reg, v)					\
76 	do {							\
77 		WREG8(GFX_INDEX, reg);				\
78 		WREG8(GFX_DATA, v);				\
79 	} while (0)						\
80 
81 #define DAC_INDEX 0x3c00
82 #define DAC_DATA 0x3c0a
83 
84 #define WREG_DAC(reg, v)					\
85 	do {							\
86 		WREG8(DAC_INDEX, reg);				\
87 		WREG8(DAC_DATA, v);				\
88 	} while (0)						\
89 
90 #define MGA_MISC_OUT 0x1fc2
91 #define MGA_MISC_IN 0x1fcc
92 
93 #define MGAG200_MAX_FB_HEIGHT 4096
94 #define MGAG200_MAX_FB_WIDTH 4096
95 
96 #define MATROX_DPMS_CLEARED (-1)
97 
98 #define to_mga_crtc(x) container_of(x, struct mga_crtc, base)
99 #define to_mga_encoder(x) container_of(x, struct mga_encoder, base)
100 #define to_mga_connector(x) container_of(x, struct mga_connector, base)
101 
102 struct mga_crtc {
103 	struct drm_crtc base;
104 	u8 lut_r[256], lut_g[256], lut_b[256];
105 	int last_dpms;
106 	bool enabled;
107 };
108 
109 struct mga_mode_info {
110 	bool mode_config_initialized;
111 	struct mga_crtc *crtc;
112 };
113 
114 struct mga_encoder {
115 	struct drm_encoder base;
116 	int last_dpms;
117 };
118 
119 
120 struct mga_i2c_chan {
121 	struct i2c_adapter adapter;
122 	struct drm_device *dev;
123 	struct i2c_algo_bit_data bit;
124 	int data, clock;
125 };
126 
127 struct mga_connector {
128 	struct drm_connector base;
129 	struct mga_i2c_chan *i2c;
130 };
131 
132 struct mga_cursor {
133 	/*
134 	   We have to have 2 buffers for the cursor to avoid occasional
135 	   corruption while switching cursor icons.
136 	   If either of these is NULL, then don't do hardware cursors, and
137 	   fall back to software.
138 	*/
139 	struct drm_gem_vram_object *pixels_1;
140 	struct drm_gem_vram_object *pixels_2;
141 	/* The currently displayed icon, this points to one of pixels_1, or pixels_2 */
142 	struct drm_gem_vram_object *pixels_current;
143 };
144 
145 struct mga_mc {
146 	resource_size_t			vram_size;
147 	resource_size_t			vram_base;
148 	resource_size_t			vram_window;
149 };
150 
151 enum mga_type {
152 	G200_SE_A,
153 	G200_SE_B,
154 	G200_WB,
155 	G200_EV,
156 	G200_EH,
157 	G200_EH3,
158 	G200_ER,
159 	G200_EW3,
160 };
161 
162 /* HW does not handle 'startadd' field correct. */
163 #define MGAG200_FLAG_HW_BUG_NO_STARTADD	(1ul << 8)
164 
165 #define MGAG200_TYPE_MASK	(0x000000ff)
166 #define MGAG200_FLAG_MASK	(0x00ffff00)
167 
168 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
169 
170 struct mga_device {
171 	struct drm_device		*dev;
172 	unsigned long			flags;
173 
174 	resource_size_t			rmmio_base;
175 	resource_size_t			rmmio_size;
176 	void __iomem			*rmmio;
177 
178 	struct mga_mc			mc;
179 	struct mga_mode_info		mode_info;
180 
181 	struct mga_cursor cursor;
182 
183 	bool				suspended;
184 	int				num_crtc;
185 	enum mga_type			type;
186 	int				has_sdram;
187 	struct drm_display_mode		mode;
188 
189 	int bpp_shifts[4];
190 
191 	int fb_mtrr;
192 
193 	/* SE model number stored in reg 0x1e24 */
194 	u32 unique_rev_id;
195 };
196 
197 static inline enum mga_type
mgag200_type_from_driver_data(kernel_ulong_t driver_data)198 mgag200_type_from_driver_data(kernel_ulong_t driver_data)
199 {
200 	return (enum mga_type)(driver_data & MGAG200_TYPE_MASK);
201 }
202 
203 static inline unsigned long
mgag200_flags_from_driver_data(kernel_ulong_t driver_data)204 mgag200_flags_from_driver_data(kernel_ulong_t driver_data)
205 {
206 	return driver_data & MGAG200_FLAG_MASK;
207 }
208 
209 				/* mgag200_mode.c */
210 int mgag200_modeset_init(struct mga_device *mdev);
211 void mgag200_modeset_fini(struct mga_device *mdev);
212 
213 				/* mgag200_main.c */
214 int mgag200_driver_load(struct drm_device *dev, unsigned long flags);
215 void mgag200_driver_unload(struct drm_device *dev);
216 
217 				/* mgag200_i2c.c */
218 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
219 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
220 
221 int mgag200_mm_init(struct mga_device *mdev);
222 void mgag200_mm_fini(struct mga_device *mdev);
223 int mgag200_mmap(struct file *filp, struct vm_area_struct *vma);
224 
225 int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
226 						uint32_t handle, uint32_t width, uint32_t height);
227 int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
228 
229 #endif				/* __MGAG200_DRV_H__ */
230