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