Commit | Line | Data |
---|---|---|
414c4531 DA |
1 | /* |
2 | * Copyright 2010 Matt Turner. | |
3 | * Copyright 2012 Red Hat | |
4 | * | |
5 | * This file is subject to the terms and conditions of the GNU General | |
6 | * Public License version 2. See the file COPYING in the main | |
7 | * directory of this archive for more details. | |
8 | * | |
9 | * Authors: Matthew Garrett | |
10 | * Matt Turner | |
11 | * Dave Airlie | |
12 | */ | |
13 | #ifndef __MGAG200_DRV_H__ | |
14 | #define __MGAG200_DRV_H__ | |
15 | ||
16 | #include <video/vga.h> | |
17 | ||
760285e7 DH |
18 | #include <drm/drm_fb_helper.h> |
19 | #include <drm/ttm/ttm_bo_api.h> | |
20 | #include <drm/ttm/ttm_bo_driver.h> | |
21 | #include <drm/ttm/ttm_placement.h> | |
22 | #include <drm/ttm/ttm_memory.h> | |
23 | #include <drm/ttm/ttm_module.h> | |
414c4531 | 24 | |
d9fc9413 DV |
25 | #include <drm/drm_gem.h> |
26 | ||
414c4531 DA |
27 | #include <linux/i2c.h> |
28 | #include <linux/i2c-algo-bit.h> | |
29 | ||
30 | #include "mgag200_reg.h" | |
31 | ||
32 | #define DRIVER_AUTHOR "Matthew Garrett" | |
33 | ||
34 | #define DRIVER_NAME "mgag200" | |
35 | #define DRIVER_DESC "MGA G200 SE" | |
36 | #define DRIVER_DATE "20110418" | |
37 | ||
38 | #define DRIVER_MAJOR 1 | |
39 | #define DRIVER_MINOR 0 | |
40 | #define DRIVER_PATCHLEVEL 0 | |
41 | ||
42 | #define MGAG200FB_CONN_LIMIT 1 | |
43 | ||
44 | #define RREG8(reg) ioread8(((void __iomem *)mdev->rmmio) + (reg)) | |
45 | #define WREG8(reg, v) iowrite8(v, ((void __iomem *)mdev->rmmio) + (reg)) | |
46 | #define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg)) | |
47 | #define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg)) | |
48 | ||
49 | #define ATTR_INDEX 0x1fc0 | |
50 | #define ATTR_DATA 0x1fc1 | |
51 | ||
52 | #define WREG_ATTR(reg, v) \ | |
53 | do { \ | |
54 | RREG8(0x1fda); \ | |
55 | WREG8(ATTR_INDEX, reg); \ | |
56 | WREG8(ATTR_DATA, v); \ | |
57 | } while (0) \ | |
58 | ||
59 | #define WREG_SEQ(reg, v) \ | |
60 | do { \ | |
61 | WREG8(MGAREG_SEQ_INDEX, reg); \ | |
62 | WREG8(MGAREG_SEQ_DATA, v); \ | |
63 | } while (0) \ | |
64 | ||
65 | #define WREG_CRT(reg, v) \ | |
66 | do { \ | |
67 | WREG8(MGAREG_CRTC_INDEX, reg); \ | |
68 | WREG8(MGAREG_CRTC_DATA, v); \ | |
69 | } while (0) \ | |
70 | ||
71 | ||
72 | #define WREG_ECRT(reg, v) \ | |
73 | do { \ | |
74 | WREG8(MGAREG_CRTCEXT_INDEX, reg); \ | |
75 | WREG8(MGAREG_CRTCEXT_DATA, v); \ | |
76 | } while (0) \ | |
77 | ||
78 | #define GFX_INDEX 0x1fce | |
79 | #define GFX_DATA 0x1fcf | |
80 | ||
81 | #define WREG_GFX(reg, v) \ | |
82 | do { \ | |
83 | WREG8(GFX_INDEX, reg); \ | |
84 | WREG8(GFX_DATA, v); \ | |
85 | } while (0) \ | |
86 | ||
87 | #define DAC_INDEX 0x3c00 | |
88 | #define DAC_DATA 0x3c0a | |
89 | ||
90 | #define WREG_DAC(reg, v) \ | |
91 | do { \ | |
92 | WREG8(DAC_INDEX, reg); \ | |
93 | WREG8(DAC_DATA, v); \ | |
94 | } while (0) \ | |
95 | ||
96 | #define MGA_MISC_OUT 0x1fc2 | |
97 | #define MGA_MISC_IN 0x1fcc | |
98 | ||
99 | #define MGAG200_MAX_FB_HEIGHT 4096 | |
100 | #define MGAG200_MAX_FB_WIDTH 4096 | |
101 | ||
102 | #define MATROX_DPMS_CLEARED (-1) | |
103 | ||
104 | #define to_mga_crtc(x) container_of(x, struct mga_crtc, base) | |
105 | #define to_mga_encoder(x) container_of(x, struct mga_encoder, base) | |
106 | #define to_mga_connector(x) container_of(x, struct mga_connector, base) | |
107 | #define to_mga_framebuffer(x) container_of(x, struct mga_framebuffer, base) | |
108 | ||
109 | struct mga_framebuffer { | |
110 | struct drm_framebuffer base; | |
111 | struct drm_gem_object *obj; | |
112 | }; | |
113 | ||
114 | struct mga_fbdev { | |
115 | struct drm_fb_helper helper; | |
116 | struct mga_framebuffer mfb; | |
414c4531 DA |
117 | void *sysram; |
118 | int size; | |
119 | struct ttm_bo_kmap_obj mapping; | |
64171959 DA |
120 | int x1, y1, x2, y2; /* dirty rect */ |
121 | spinlock_t dirty_lock; | |
414c4531 DA |
122 | }; |
123 | ||
124 | struct mga_crtc { | |
125 | struct drm_crtc base; | |
126 | u8 lut_r[256], lut_g[256], lut_b[256]; | |
127 | int last_dpms; | |
128 | bool enabled; | |
129 | }; | |
130 | ||
131 | struct mga_mode_info { | |
132 | bool mode_config_initialized; | |
133 | struct mga_crtc *crtc; | |
134 | }; | |
135 | ||
136 | struct mga_encoder { | |
137 | struct drm_encoder base; | |
138 | int last_dpms; | |
139 | }; | |
140 | ||
141 | ||
142 | struct mga_i2c_chan { | |
143 | struct i2c_adapter adapter; | |
144 | struct drm_device *dev; | |
145 | struct i2c_algo_bit_data bit; | |
146 | int data, clock; | |
147 | }; | |
148 | ||
149 | struct mga_connector { | |
150 | struct drm_connector base; | |
151 | struct mga_i2c_chan *i2c; | |
152 | }; | |
153 | ||
a080db9f CH |
154 | struct mga_cursor { |
155 | /* | |
156 | We have to have 2 buffers for the cursor to avoid occasional | |
157 | corruption while switching cursor icons. | |
158 | If either of these is NULL, then don't do hardware cursors, and | |
159 | fall back to software. | |
160 | */ | |
161 | struct mgag200_bo *pixels_1; | |
162 | struct mgag200_bo *pixels_2; | |
163 | u64 pixels_1_gpu_addr, pixels_2_gpu_addr; | |
164 | /* The currently displayed icon, this points to one of pixels_1, or pixels_2 */ | |
165 | struct mgag200_bo *pixels_current; | |
166 | /* The previously displayed icon */ | |
167 | struct mgag200_bo *pixels_prev; | |
168 | }; | |
414c4531 DA |
169 | |
170 | struct mga_mc { | |
171 | resource_size_t vram_size; | |
172 | resource_size_t vram_base; | |
173 | resource_size_t vram_window; | |
174 | }; | |
175 | ||
176 | enum mga_type { | |
177 | G200_SE_A, | |
178 | G200_SE_B, | |
179 | G200_WB, | |
180 | G200_EV, | |
181 | G200_EH, | |
182 | G200_ER, | |
6d857c18 | 183 | G200_EW3, |
414c4531 DA |
184 | }; |
185 | ||
186 | #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) | |
187 | ||
188 | struct mga_device { | |
189 | struct drm_device *dev; | |
190 | unsigned long flags; | |
191 | ||
192 | resource_size_t rmmio_base; | |
193 | resource_size_t rmmio_size; | |
194 | void __iomem *rmmio; | |
195 | ||
414c4531 DA |
196 | struct mga_mc mc; |
197 | struct mga_mode_info mode_info; | |
198 | ||
199 | struct mga_fbdev *mfbdev; | |
a080db9f | 200 | struct mga_cursor cursor; |
414c4531 DA |
201 | |
202 | bool suspended; | |
203 | int num_crtc; | |
204 | enum mga_type type; | |
205 | int has_sdram; | |
206 | struct drm_display_mode mode; | |
207 | ||
208 | int bpp_shifts[4]; | |
209 | ||
210 | int fb_mtrr; | |
211 | ||
212 | struct { | |
213 | struct drm_global_reference mem_global_ref; | |
214 | struct ttm_bo_global_ref bo_global_ref; | |
215 | struct ttm_bo_device bdev; | |
414c4531 DA |
216 | } ttm; |
217 | ||
abbee623 JL |
218 | /* SE model number stored in reg 0x1e24 */ |
219 | u32 unique_rev_id; | |
414c4531 DA |
220 | }; |
221 | ||
222 | ||
223 | struct mgag200_bo { | |
224 | struct ttm_buffer_object bo; | |
225 | struct ttm_placement placement; | |
226 | struct ttm_bo_kmap_obj kmap; | |
227 | struct drm_gem_object gem; | |
f1217ed0 | 228 | struct ttm_place placements[3]; |
414c4531 DA |
229 | int pin_count; |
230 | }; | |
231 | #define gem_to_mga_bo(gobj) container_of((gobj), struct mgag200_bo, gem) | |
232 | ||
233 | static inline struct mgag200_bo * | |
234 | mgag200_bo(struct ttm_buffer_object *bo) | |
235 | { | |
236 | return container_of(bo, struct mgag200_bo, bo); | |
237 | } | |
715f59cc | 238 | /* mgag200_crtc.c */ |
414c4531 DA |
239 | void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
240 | u16 blue, int regno); | |
241 | void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | |
242 | u16 *blue, int regno); | |
243 | ||
244 | /* mgag200_mode.c */ | |
245 | int mgag200_modeset_init(struct mga_device *mdev); | |
246 | void mgag200_modeset_fini(struct mga_device *mdev); | |
247 | ||
715f59cc | 248 | /* mgag200_fb.c */ |
414c4531 DA |
249 | int mgag200_fbdev_init(struct mga_device *mdev); |
250 | void mgag200_fbdev_fini(struct mga_device *mdev); | |
251 | ||
252 | /* mgag200_main.c */ | |
253 | int mgag200_framebuffer_init(struct drm_device *dev, | |
254 | struct mga_framebuffer *mfb, | |
1eb83451 | 255 | const struct drm_mode_fb_cmd2 *mode_cmd, |
414c4531 DA |
256 | struct drm_gem_object *obj); |
257 | ||
258 | ||
259 | int mgag200_driver_load(struct drm_device *dev, unsigned long flags); | |
260 | int mgag200_driver_unload(struct drm_device *dev); | |
261 | int mgag200_gem_create(struct drm_device *dev, | |
262 | u32 size, bool iskernel, | |
263 | struct drm_gem_object **obj); | |
414c4531 DA |
264 | int mgag200_dumb_create(struct drm_file *file, |
265 | struct drm_device *dev, | |
266 | struct drm_mode_create_dumb *args); | |
414c4531 DA |
267 | void mgag200_gem_free_object(struct drm_gem_object *obj); |
268 | int | |
269 | mgag200_dumb_mmap_offset(struct drm_file *file, | |
270 | struct drm_device *dev, | |
271 | uint32_t handle, | |
272 | uint64_t *offset); | |
715f59cc | 273 | /* mgag200_i2c.c */ |
414c4531 DA |
274 | struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); |
275 | void mgag200_i2c_destroy(struct mga_i2c_chan *i2c); | |
276 | ||
277 | #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) | |
278 | void mgag200_ttm_placement(struct mgag200_bo *bo, int domain); | |
279 | ||
06597ce8 ML |
280 | static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait) |
281 | { | |
282 | int ret; | |
283 | ||
dfd5e50e | 284 | ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); |
06597ce8 ML |
285 | if (ret) { |
286 | if (ret != -ERESTARTSYS && ret != -EBUSY) | |
287 | DRM_ERROR("reserve failed %p\n", bo); | |
288 | return ret; | |
289 | } | |
290 | return 0; | |
291 | } | |
292 | ||
293 | static inline void mgag200_bo_unreserve(struct mgag200_bo *bo) | |
294 | { | |
295 | ttm_bo_unreserve(&bo->bo); | |
296 | } | |
297 | ||
414c4531 DA |
298 | int mgag200_bo_create(struct drm_device *dev, int size, int align, |
299 | uint32_t flags, struct mgag200_bo **pastbo); | |
300 | int mgag200_mm_init(struct mga_device *mdev); | |
301 | void mgag200_mm_fini(struct mga_device *mdev); | |
302 | int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); | |
303 | int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr); | |
304 | int mgag200_bo_unpin(struct mgag200_bo *bo); | |
305 | int mgag200_bo_push_sysram(struct mgag200_bo *bo); | |
a080db9f CH |
306 | /* mgag200_cursor.c */ |
307 | int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |
308 | uint32_t handle, uint32_t width, uint32_t height); | |
309 | int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); | |
310 | ||
414c4531 | 311 | #endif /* __MGAG200_DRV_H__ */ |