Commit | Line | Data |
---|---|---|
f9aa76a8 DA |
1 | /* |
2 | * Copyright 2012 Red Hat | |
3 | * | |
4 | * This file is subject to the terms and conditions of the GNU General | |
5 | * Public License version 2. See the file COPYING in the main | |
6 | * directory of this archive for more details. | |
7 | * | |
8 | * Authors: Matthew Garrett | |
9 | * Dave Airlie | |
10 | */ | |
11 | #ifndef __CIRRUS_DRV_H__ | |
12 | #define __CIRRUS_DRV_H__ | |
13 | ||
14 | #include <video/vga.h> | |
15 | ||
16 | #include <drm/drm_fb_helper.h> | |
17 | ||
760285e7 DH |
18 | #include <drm/ttm/ttm_bo_api.h> |
19 | #include <drm/ttm/ttm_bo_driver.h> | |
20 | #include <drm/ttm/ttm_placement.h> | |
21 | #include <drm/ttm/ttm_memory.h> | |
22 | #include <drm/ttm/ttm_module.h> | |
f9aa76a8 | 23 | |
d9fc9413 DV |
24 | #include <drm/drm_gem.h> |
25 | ||
f9aa76a8 DA |
26 | #define DRIVER_AUTHOR "Matthew Garrett" |
27 | ||
28 | #define DRIVER_NAME "cirrus" | |
29 | #define DRIVER_DESC "qemu Cirrus emulation" | |
30 | #define DRIVER_DATE "20110418" | |
31 | ||
32 | #define DRIVER_MAJOR 1 | |
33 | #define DRIVER_MINOR 0 | |
34 | #define DRIVER_PATCHLEVEL 0 | |
35 | ||
36 | #define CIRRUSFB_CONN_LIMIT 1 | |
37 | ||
38 | #define RREG8(reg) ioread8(((void __iomem *)cdev->rmmio) + (reg)) | |
39 | #define WREG8(reg, v) iowrite8(v, ((void __iomem *)cdev->rmmio) + (reg)) | |
40 | #define RREG32(reg) ioread32(((void __iomem *)cdev->rmmio) + (reg)) | |
41 | #define WREG32(reg, v) iowrite32(v, ((void __iomem *)cdev->rmmio) + (reg)) | |
42 | ||
43 | #define SEQ_INDEX 4 | |
44 | #define SEQ_DATA 5 | |
45 | ||
46 | #define WREG_SEQ(reg, v) \ | |
47 | do { \ | |
48 | WREG8(SEQ_INDEX, reg); \ | |
49 | WREG8(SEQ_DATA, v); \ | |
50 | } while (0) \ | |
51 | ||
52 | #define CRT_INDEX 0x14 | |
53 | #define CRT_DATA 0x15 | |
54 | ||
55 | #define WREG_CRT(reg, v) \ | |
56 | do { \ | |
57 | WREG8(CRT_INDEX, reg); \ | |
58 | WREG8(CRT_DATA, v); \ | |
59 | } while (0) \ | |
60 | ||
61 | #define GFX_INDEX 0xe | |
62 | #define GFX_DATA 0xf | |
63 | ||
64 | #define WREG_GFX(reg, v) \ | |
65 | do { \ | |
66 | WREG8(GFX_INDEX, reg); \ | |
67 | WREG8(GFX_DATA, v); \ | |
68 | } while (0) \ | |
69 | ||
70 | /* | |
71 | * Cirrus has a "hidden" DAC register that can be accessed by writing to | |
72 | * the pixel mask register to reset the state, then reading from the register | |
73 | * four times. The next write will then pass to the DAC | |
74 | */ | |
75 | #define VGA_DAC_MASK 0x6 | |
76 | ||
77 | #define WREG_HDR(v) \ | |
78 | do { \ | |
79 | RREG8(VGA_DAC_MASK); \ | |
80 | RREG8(VGA_DAC_MASK); \ | |
81 | RREG8(VGA_DAC_MASK); \ | |
82 | RREG8(VGA_DAC_MASK); \ | |
83 | WREG8(VGA_DAC_MASK, v); \ | |
84 | } while (0) \ | |
85 | ||
86 | ||
87 | #define CIRRUS_MAX_FB_HEIGHT 4096 | |
88 | #define CIRRUS_MAX_FB_WIDTH 4096 | |
89 | ||
90 | #define CIRRUS_DPMS_CLEARED (-1) | |
91 | ||
92 | #define to_cirrus_crtc(x) container_of(x, struct cirrus_crtc, base) | |
93 | #define to_cirrus_encoder(x) container_of(x, struct cirrus_encoder, base) | |
94 | #define to_cirrus_framebuffer(x) container_of(x, struct cirrus_framebuffer, base) | |
95 | ||
96 | struct cirrus_crtc { | |
97 | struct drm_crtc base; | |
98 | u8 lut_r[256], lut_g[256], lut_b[256]; | |
99 | int last_dpms; | |
100 | bool enabled; | |
101 | }; | |
102 | ||
103 | struct cirrus_fbdev; | |
104 | struct cirrus_mode_info { | |
105 | bool mode_config_initialized; | |
106 | struct cirrus_crtc *crtc; | |
107 | /* pointer to fbdev info structure */ | |
108 | struct cirrus_fbdev *gfbdev; | |
109 | }; | |
110 | ||
111 | struct cirrus_encoder { | |
112 | struct drm_encoder base; | |
113 | int last_dpms; | |
114 | }; | |
115 | ||
116 | struct cirrus_connector { | |
117 | struct drm_connector base; | |
118 | }; | |
119 | ||
120 | struct cirrus_framebuffer { | |
121 | struct drm_framebuffer base; | |
122 | struct drm_gem_object *obj; | |
123 | }; | |
124 | ||
125 | struct cirrus_mc { | |
126 | resource_size_t vram_size; | |
127 | resource_size_t vram_base; | |
128 | }; | |
129 | ||
130 | struct cirrus_device { | |
131 | struct drm_device *dev; | |
132 | unsigned long flags; | |
133 | ||
134 | resource_size_t rmmio_base; | |
135 | resource_size_t rmmio_size; | |
136 | void __iomem *rmmio; | |
137 | ||
138 | struct cirrus_mc mc; | |
139 | struct cirrus_mode_info mode_info; | |
140 | ||
141 | int num_crtc; | |
142 | int fb_mtrr; | |
143 | ||
144 | struct { | |
145 | struct drm_global_reference mem_global_ref; | |
146 | struct ttm_bo_global_ref bo_global_ref; | |
147 | struct ttm_bo_device bdev; | |
f9aa76a8 | 148 | } ttm; |
93b4cc56 | 149 | bool mm_inited; |
f9aa76a8 DA |
150 | }; |
151 | ||
152 | ||
153 | struct cirrus_fbdev { | |
154 | struct drm_fb_helper helper; | |
155 | struct cirrus_framebuffer gfb; | |
f9aa76a8 DA |
156 | void *sysram; |
157 | int size; | |
f3b2bbdc DA |
158 | int x1, y1, x2, y2; /* dirty rect */ |
159 | spinlock_t dirty_lock; | |
f9aa76a8 DA |
160 | }; |
161 | ||
162 | struct cirrus_bo { | |
163 | struct ttm_buffer_object bo; | |
164 | struct ttm_placement placement; | |
165 | struct ttm_bo_kmap_obj kmap; | |
166 | struct drm_gem_object gem; | |
f1217ed0 | 167 | struct ttm_place placements[3]; |
f9aa76a8 DA |
168 | int pin_count; |
169 | }; | |
170 | #define gem_to_cirrus_bo(gobj) container_of((gobj), struct cirrus_bo, gem) | |
171 | ||
172 | static inline struct cirrus_bo * | |
173 | cirrus_bo(struct ttm_buffer_object *bo) | |
174 | { | |
175 | return container_of(bo, struct cirrus_bo, bo); | |
176 | } | |
177 | ||
178 | ||
179 | #define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base) | |
180 | #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) | |
181 | ||
182 | /* cirrus_mode.c */ | |
183 | void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |
184 | u16 blue, int regno); | |
185 | void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | |
186 | u16 *blue, int regno); | |
187 | ||
188 | ||
189 | /* cirrus_main.c */ | |
190 | int cirrus_device_init(struct cirrus_device *cdev, | |
191 | struct drm_device *ddev, | |
192 | struct pci_dev *pdev, | |
193 | uint32_t flags); | |
194 | void cirrus_device_fini(struct cirrus_device *cdev); | |
f9aa76a8 DA |
195 | void cirrus_gem_free_object(struct drm_gem_object *obj); |
196 | int cirrus_dumb_mmap_offset(struct drm_file *file, | |
197 | struct drm_device *dev, | |
198 | uint32_t handle, | |
199 | uint64_t *offset); | |
200 | int cirrus_gem_create(struct drm_device *dev, | |
201 | u32 size, bool iskernel, | |
202 | struct drm_gem_object **obj); | |
203 | int cirrus_dumb_create(struct drm_file *file, | |
204 | struct drm_device *dev, | |
205 | struct drm_mode_create_dumb *args); | |
f9aa76a8 DA |
206 | |
207 | int cirrus_framebuffer_init(struct drm_device *dev, | |
208 | struct cirrus_framebuffer *gfb, | |
1eb83451 | 209 | const struct drm_mode_fb_cmd2 *mode_cmd, |
f9aa76a8 DA |
210 | struct drm_gem_object *obj); |
211 | ||
8975626e ZR |
212 | bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height, |
213 | int bpp, int pitch); | |
214 | ||
f9aa76a8 DA |
215 | /* cirrus_display.c */ |
216 | int cirrus_modeset_init(struct cirrus_device *cdev); | |
217 | void cirrus_modeset_fini(struct cirrus_device *cdev); | |
218 | ||
219 | /* cirrus_fbdev.c */ | |
220 | int cirrus_fbdev_init(struct cirrus_device *cdev); | |
221 | void cirrus_fbdev_fini(struct cirrus_device *cdev); | |
222 | ||
223 | ||
224 | ||
225 | /* cirrus_irq.c */ | |
226 | void cirrus_driver_irq_preinstall(struct drm_device *dev); | |
227 | int cirrus_driver_irq_postinstall(struct drm_device *dev); | |
228 | void cirrus_driver_irq_uninstall(struct drm_device *dev); | |
e9f0d76f | 229 | irqreturn_t cirrus_driver_irq_handler(int irq, void *arg); |
f9aa76a8 DA |
230 | |
231 | /* cirrus_kms.c */ | |
232 | int cirrus_driver_load(struct drm_device *dev, unsigned long flags); | |
233 | int cirrus_driver_unload(struct drm_device *dev); | |
234 | extern struct drm_ioctl_desc cirrus_ioctls[]; | |
235 | extern int cirrus_max_ioctl; | |
236 | ||
237 | int cirrus_mm_init(struct cirrus_device *cirrus); | |
238 | void cirrus_mm_fini(struct cirrus_device *cirrus); | |
239 | void cirrus_ttm_placement(struct cirrus_bo *bo, int domain); | |
240 | int cirrus_bo_create(struct drm_device *dev, int size, int align, | |
241 | uint32_t flags, struct cirrus_bo **pcirrusbo); | |
242 | int cirrus_mmap(struct file *filp, struct vm_area_struct *vma); | |
37c5a525 ML |
243 | |
244 | static inline int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait) | |
245 | { | |
246 | int ret; | |
247 | ||
ee3939e0 | 248 | ret = ttm_bo_reserve(&bo->bo, true, no_wait, false, NULL); |
37c5a525 ML |
249 | if (ret) { |
250 | if (ret != -ERESTARTSYS && ret != -EBUSY) | |
251 | DRM_ERROR("reserve failed %p\n", bo); | |
252 | return ret; | |
253 | } | |
254 | return 0; | |
255 | } | |
256 | ||
257 | static inline void cirrus_bo_unreserve(struct cirrus_bo *bo) | |
258 | { | |
259 | ttm_bo_unreserve(&bo->bo); | |
260 | } | |
261 | ||
f9aa76a8 DA |
262 | int cirrus_bo_push_sysram(struct cirrus_bo *bo); |
263 | int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr); | |
7f551b1e TI |
264 | |
265 | extern int cirrus_bpp; | |
266 | ||
f9aa76a8 | 267 | #endif /* __CIRRUS_DRV_H__ */ |