Commit | Line | Data |
---|---|---|
312fec14 DA |
1 | /* |
2 | * Copyright 2012 Red Hat Inc. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the | |
6 | * "Software"), to deal in the Software without restriction, including | |
7 | * without limitation the rights to use, copy, modify, merge, publish, | |
8 | * distribute, sub license, and/or sell copies of the Software, and to | |
9 | * permit persons to whom the Software is furnished to do so, subject to | |
10 | * the following conditions: | |
11 | * | |
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
14 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |
15 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | |
16 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |
17 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |
18 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | |
19 | * | |
20 | * The above copyright notice and this permission notice (including the | |
21 | * next paragraph) shall be included in all copies or substantial portions | |
22 | * of the Software. | |
23 | * | |
24 | */ | |
25 | /* | |
26 | * Authors: Dave Airlie <airlied@redhat.com> | |
27 | */ | |
28 | #ifndef __AST_DRV_H__ | |
29 | #define __AST_DRV_H__ | |
30 | ||
760285e7 | 31 | #include <drm/drm_fb_helper.h> |
312fec14 | 32 | |
760285e7 DH |
33 | #include <drm/ttm/ttm_bo_api.h> |
34 | #include <drm/ttm/ttm_bo_driver.h> | |
35 | #include <drm/ttm/ttm_placement.h> | |
36 | #include <drm/ttm/ttm_memory.h> | |
37 | #include <drm/ttm/ttm_module.h> | |
312fec14 | 38 | |
d9fc9413 DV |
39 | #include <drm/drm_gem.h> |
40 | ||
312fec14 DA |
41 | #include <linux/i2c.h> |
42 | #include <linux/i2c-algo-bit.h> | |
43 | ||
44 | #define DRIVER_AUTHOR "Dave Airlie" | |
45 | ||
46 | #define DRIVER_NAME "ast" | |
47 | #define DRIVER_DESC "AST" | |
48 | #define DRIVER_DATE "20120228" | |
49 | ||
50 | #define DRIVER_MAJOR 0 | |
51 | #define DRIVER_MINOR 1 | |
52 | #define DRIVER_PATCHLEVEL 0 | |
53 | ||
54 | #define PCI_CHIP_AST2000 0x2000 | |
55 | #define PCI_CHIP_AST2100 0x2010 | |
56 | #define PCI_CHIP_AST1180 0x1180 | |
57 | ||
58 | ||
59 | enum ast_chip { | |
60 | AST2000, | |
61 | AST2100, | |
62 | AST1100, | |
63 | AST2200, | |
64 | AST2150, | |
65 | AST2300, | |
1453bf4c | 66 | AST2400, |
312fec14 DA |
67 | AST1180, |
68 | }; | |
69 | ||
83c6620b DA |
70 | enum ast_tx_chip { |
71 | AST_TX_NONE, | |
72 | AST_TX_SIL164, | |
73 | AST_TX_ITE66121, | |
74 | AST_TX_DP501, | |
75 | }; | |
76 | ||
312fec14 DA |
77 | #define AST_DRAM_512Mx16 0 |
78 | #define AST_DRAM_1Gx16 1 | |
79 | #define AST_DRAM_512Mx32 2 | |
80 | #define AST_DRAM_1Gx32 3 | |
81 | #define AST_DRAM_2Gx16 6 | |
82 | #define AST_DRAM_4Gx16 7 | |
83 | ||
84 | struct ast_fbdev; | |
85 | ||
86 | struct ast_private { | |
87 | struct drm_device *dev; | |
88 | ||
89 | void __iomem *regs; | |
90 | void __iomem *ioregs; | |
91 | ||
92 | enum ast_chip chip; | |
93 | bool vga2_clone; | |
94 | uint32_t dram_bus_width; | |
95 | uint32_t dram_type; | |
96 | uint32_t mclk; | |
97 | uint32_t vram_size; | |
98 | ||
99 | struct ast_fbdev *fbdev; | |
100 | ||
101 | int fb_mtrr; | |
102 | ||
103 | struct { | |
104 | struct drm_global_reference mem_global_ref; | |
105 | struct ttm_bo_global_ref bo_global_ref; | |
106 | struct ttm_bo_device bdev; | |
312fec14 DA |
107 | } ttm; |
108 | ||
109 | struct drm_gem_object *cursor_cache; | |
110 | uint64_t cursor_cache_gpu_addr; | |
bfb89928 DV |
111 | /* Acces to this cache is protected by the crtc->mutex of the only crtc |
112 | * we have. */ | |
312fec14 DA |
113 | struct ttm_bo_kmap_obj cache_kmap; |
114 | int next_cursor; | |
f1f62f2c | 115 | bool support_wide_screen; |
83c6620b DA |
116 | |
117 | enum ast_tx_chip tx_chip_type; | |
118 | u8 dp501_maxclk; | |
119 | u8 *dp501_fw_addr; | |
120 | const struct firmware *dp501_fw; /* dp501 fw */ | |
312fec14 DA |
121 | }; |
122 | ||
123 | int ast_driver_load(struct drm_device *dev, unsigned long flags); | |
124 | int ast_driver_unload(struct drm_device *dev); | |
125 | ||
126 | struct ast_gem_object; | |
127 | ||
128 | #define AST_IO_AR_PORT_WRITE (0x40) | |
129 | #define AST_IO_MISC_PORT_WRITE (0x42) | |
0dd68309 | 130 | #define AST_IO_VGA_ENABLE_PORT (0x43) |
312fec14 | 131 | #define AST_IO_SEQ_PORT (0x44) |
0dd68309 | 132 | #define AST_IO_DAC_INDEX_READ (0x47) |
312fec14 DA |
133 | #define AST_IO_DAC_INDEX_WRITE (0x48) |
134 | #define AST_IO_DAC_DATA (0x49) | |
135 | #define AST_IO_GR_PORT (0x4E) | |
136 | #define AST_IO_CRTC_PORT (0x54) | |
137 | #define AST_IO_INPUT_STATUS1_READ (0x5A) | |
138 | #define AST_IO_MISC_PORT_READ (0x4C) | |
139 | ||
0dd68309 BH |
140 | #define AST_IO_MM_OFFSET (0x380) |
141 | ||
312fec14 DA |
142 | #define __ast_read(x) \ |
143 | static inline u##x ast_read##x(struct ast_private *ast, u32 reg) { \ | |
144 | u##x val = 0;\ | |
145 | val = ioread##x(ast->regs + reg); \ | |
146 | return val;\ | |
147 | } | |
148 | ||
149 | __ast_read(8); | |
150 | __ast_read(16); | |
151 | __ast_read(32) | |
152 | ||
153 | #define __ast_io_read(x) \ | |
154 | static inline u##x ast_io_read##x(struct ast_private *ast, u32 reg) { \ | |
155 | u##x val = 0;\ | |
156 | val = ioread##x(ast->ioregs + reg); \ | |
157 | return val;\ | |
158 | } | |
159 | ||
160 | __ast_io_read(8); | |
161 | __ast_io_read(16); | |
162 | __ast_io_read(32); | |
163 | ||
164 | #define __ast_write(x) \ | |
165 | static inline void ast_write##x(struct ast_private *ast, u32 reg, u##x val) {\ | |
166 | iowrite##x(val, ast->regs + reg);\ | |
167 | } | |
168 | ||
169 | __ast_write(8); | |
170 | __ast_write(16); | |
171 | __ast_write(32); | |
172 | ||
173 | #define __ast_io_write(x) \ | |
174 | static inline void ast_io_write##x(struct ast_private *ast, u32 reg, u##x val) {\ | |
175 | iowrite##x(val, ast->ioregs + reg);\ | |
176 | } | |
177 | ||
178 | __ast_io_write(8); | |
179 | __ast_io_write(16); | |
180 | #undef __ast_io_write | |
181 | ||
182 | static inline void ast_set_index_reg(struct ast_private *ast, | |
183 | uint32_t base, uint8_t index, | |
184 | uint8_t val) | |
185 | { | |
186 | ast_io_write16(ast, base, ((u16)val << 8) | index); | |
187 | } | |
188 | ||
189 | void ast_set_index_reg_mask(struct ast_private *ast, | |
190 | uint32_t base, uint8_t index, | |
191 | uint8_t mask, uint8_t val); | |
192 | uint8_t ast_get_index_reg(struct ast_private *ast, | |
193 | uint32_t base, uint8_t index); | |
194 | uint8_t ast_get_index_reg_mask(struct ast_private *ast, | |
195 | uint32_t base, uint8_t index, uint8_t mask); | |
196 | ||
197 | static inline void ast_open_key(struct ast_private *ast) | |
198 | { | |
2e837813 | 199 | ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); |
312fec14 DA |
200 | } |
201 | ||
202 | #define AST_VIDMEM_SIZE_8M 0x00800000 | |
203 | #define AST_VIDMEM_SIZE_16M 0x01000000 | |
204 | #define AST_VIDMEM_SIZE_32M 0x02000000 | |
205 | #define AST_VIDMEM_SIZE_64M 0x04000000 | |
206 | #define AST_VIDMEM_SIZE_128M 0x08000000 | |
207 | ||
208 | #define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M | |
209 | ||
210 | #define AST_MAX_HWC_WIDTH 64 | |
211 | #define AST_MAX_HWC_HEIGHT 64 | |
212 | ||
213 | #define AST_HWC_SIZE (AST_MAX_HWC_WIDTH*AST_MAX_HWC_HEIGHT*2) | |
214 | #define AST_HWC_SIGNATURE_SIZE 32 | |
215 | ||
216 | #define AST_DEFAULT_HWC_NUM 2 | |
217 | /* define for signature structure */ | |
218 | #define AST_HWC_SIGNATURE_CHECKSUM 0x00 | |
219 | #define AST_HWC_SIGNATURE_SizeX 0x04 | |
220 | #define AST_HWC_SIGNATURE_SizeY 0x08 | |
221 | #define AST_HWC_SIGNATURE_X 0x0C | |
222 | #define AST_HWC_SIGNATURE_Y 0x10 | |
223 | #define AST_HWC_SIGNATURE_HOTSPOTX 0x14 | |
224 | #define AST_HWC_SIGNATURE_HOTSPOTY 0x18 | |
225 | ||
226 | ||
227 | struct ast_i2c_chan { | |
228 | struct i2c_adapter adapter; | |
229 | struct drm_device *dev; | |
230 | struct i2c_algo_bit_data bit; | |
231 | }; | |
232 | ||
233 | struct ast_connector { | |
234 | struct drm_connector base; | |
235 | struct ast_i2c_chan *i2c; | |
236 | }; | |
237 | ||
238 | struct ast_crtc { | |
239 | struct drm_crtc base; | |
240 | u8 lut_r[256], lut_g[256], lut_b[256]; | |
241 | struct drm_gem_object *cursor_bo; | |
242 | uint64_t cursor_addr; | |
243 | int cursor_width, cursor_height; | |
244 | u8 offset_x, offset_y; | |
245 | }; | |
246 | ||
247 | struct ast_encoder { | |
248 | struct drm_encoder base; | |
249 | }; | |
250 | ||
251 | struct ast_framebuffer { | |
252 | struct drm_framebuffer base; | |
253 | struct drm_gem_object *obj; | |
254 | }; | |
255 | ||
256 | struct ast_fbdev { | |
257 | struct drm_fb_helper helper; | |
258 | struct ast_framebuffer afb; | |
312fec14 DA |
259 | void *sysram; |
260 | int size; | |
261 | struct ttm_bo_kmap_obj mapping; | |
306373b6 DA |
262 | int x1, y1, x2, y2; /* dirty rect */ |
263 | spinlock_t dirty_lock; | |
312fec14 DA |
264 | }; |
265 | ||
266 | #define to_ast_crtc(x) container_of(x, struct ast_crtc, base) | |
267 | #define to_ast_connector(x) container_of(x, struct ast_connector, base) | |
268 | #define to_ast_encoder(x) container_of(x, struct ast_encoder, base) | |
269 | #define to_ast_framebuffer(x) container_of(x, struct ast_framebuffer, base) | |
270 | ||
271 | struct ast_vbios_stdtable { | |
272 | u8 misc; | |
273 | u8 seq[4]; | |
274 | u8 crtc[25]; | |
275 | u8 ar[20]; | |
276 | u8 gr[9]; | |
277 | }; | |
278 | ||
279 | struct ast_vbios_enhtable { | |
280 | u32 ht; | |
281 | u32 hde; | |
282 | u32 hfp; | |
283 | u32 hsync; | |
284 | u32 vt; | |
285 | u32 vde; | |
286 | u32 vfp; | |
287 | u32 vsync; | |
288 | u32 dclk_index; | |
289 | u32 flags; | |
290 | u32 refresh_rate; | |
291 | u32 refresh_rate_index; | |
292 | u32 mode_id; | |
293 | }; | |
294 | ||
295 | struct ast_vbios_dclk_info { | |
296 | u8 param1; | |
297 | u8 param2; | |
298 | u8 param3; | |
299 | }; | |
300 | ||
301 | struct ast_vbios_mode_info { | |
302 | struct ast_vbios_stdtable *std_table; | |
303 | struct ast_vbios_enhtable *enh_table; | |
304 | }; | |
305 | ||
306 | extern int ast_mode_init(struct drm_device *dev); | |
307 | extern void ast_mode_fini(struct drm_device *dev); | |
308 | ||
309 | int ast_framebuffer_init(struct drm_device *dev, | |
310 | struct ast_framebuffer *ast_fb, | |
1eb83451 | 311 | const struct drm_mode_fb_cmd2 *mode_cmd, |
312fec14 DA |
312 | struct drm_gem_object *obj); |
313 | ||
314 | int ast_fbdev_init(struct drm_device *dev); | |
315 | void ast_fbdev_fini(struct drm_device *dev); | |
316 | void ast_fbdev_set_suspend(struct drm_device *dev, int state); | |
28fb4cb7 | 317 | void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr); |
312fec14 DA |
318 | |
319 | struct ast_bo { | |
320 | struct ttm_buffer_object bo; | |
321 | struct ttm_placement placement; | |
322 | struct ttm_bo_kmap_obj kmap; | |
323 | struct drm_gem_object gem; | |
f1217ed0 | 324 | struct ttm_place placements[3]; |
312fec14 DA |
325 | int pin_count; |
326 | }; | |
327 | #define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem) | |
328 | ||
329 | static inline struct ast_bo * | |
330 | ast_bo(struct ttm_buffer_object *bo) | |
331 | { | |
332 | return container_of(bo, struct ast_bo, bo); | |
333 | } | |
334 | ||
335 | ||
336 | #define to_ast_obj(x) container_of(x, struct ast_gem_object, base) | |
337 | ||
338 | #define AST_MM_ALIGN_SHIFT 4 | |
339 | #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) | |
340 | ||
341 | extern int ast_dumb_create(struct drm_file *file, | |
342 | struct drm_device *dev, | |
343 | struct drm_mode_create_dumb *args); | |
312fec14 | 344 | |
312fec14 DA |
345 | extern void ast_gem_free_object(struct drm_gem_object *obj); |
346 | extern int ast_dumb_mmap_offset(struct drm_file *file, | |
347 | struct drm_device *dev, | |
348 | uint32_t handle, | |
349 | uint64_t *offset); | |
350 | ||
351 | #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) | |
352 | ||
353 | int ast_mm_init(struct ast_private *ast); | |
354 | void ast_mm_fini(struct ast_private *ast); | |
355 | ||
356 | int ast_bo_create(struct drm_device *dev, int size, int align, | |
357 | uint32_t flags, struct ast_bo **pastbo); | |
358 | ||
359 | int ast_gem_create(struct drm_device *dev, | |
360 | u32 size, bool iskernel, | |
361 | struct drm_gem_object **obj); | |
362 | ||
363 | int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr); | |
364 | int ast_bo_unpin(struct ast_bo *bo); | |
365 | ||
4094dc2a ML |
366 | static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait) |
367 | { | |
368 | int ret; | |
369 | ||
dfd5e50e | 370 | ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL); |
4094dc2a ML |
371 | if (ret) { |
372 | if (ret != -ERESTARTSYS && ret != -EBUSY) | |
373 | DRM_ERROR("reserve failed %p\n", bo); | |
374 | return ret; | |
375 | } | |
376 | return 0; | |
377 | } | |
378 | ||
379 | static inline void ast_bo_unreserve(struct ast_bo *bo) | |
380 | { | |
381 | ttm_bo_unreserve(&bo->bo); | |
382 | } | |
383 | ||
312fec14 DA |
384 | void ast_ttm_placement(struct ast_bo *bo, int domain); |
385 | int ast_bo_push_sysram(struct ast_bo *bo); | |
386 | int ast_mmap(struct file *filp, struct vm_area_struct *vma); | |
387 | ||
388 | /* ast post */ | |
d1b98557 BH |
389 | void ast_enable_vga(struct drm_device *dev); |
390 | void ast_enable_mmio(struct drm_device *dev); | |
391 | bool ast_is_vga_enabled(struct drm_device *dev); | |
312fec14 | 392 | void ast_post_gpu(struct drm_device *dev); |
83c6620b DA |
393 | u32 ast_mindwm(struct ast_private *ast, u32 r); |
394 | void ast_moutdwm(struct ast_private *ast, u32 r, u32 v); | |
395 | /* ast dp501 */ | |
396 | int ast_load_dp501_microcode(struct drm_device *dev); | |
397 | void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); | |
398 | bool ast_launch_m68k(struct drm_device *dev); | |
399 | bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); | |
400 | bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata); | |
401 | u8 ast_get_dp501_max_clk(struct drm_device *dev); | |
402 | void ast_init_3rdtx(struct drm_device *dev); | |
312fec14 | 403 | #endif |