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