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 | |
31 | #include <linux/i2c.h> |
32 | #include <linux/i2c-algo-bit.h> |
33 | #include <linux/io.h> |
34 | #include <linux/types.h> |
35 | |
36 | #include <drm/drm_connector.h> |
37 | #include <drm/drm_crtc.h> |
38 | #include <drm/drm_encoder.h> |
39 | #include <drm/drm_mode.h> |
40 | #include <drm/drm_framebuffer.h> |
41 | |
42 | #include "ast_reg.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 | |
57 | #define __AST_CHIP(__gen, __index) ((__gen) << 16 | (__index)) |
58 | |
59 | enum ast_chip { |
60 | /* 1st gen */ |
61 | AST1000 = __AST_CHIP(1, 0), // unused |
62 | AST2000 = __AST_CHIP(1, 1), |
63 | /* 2nd gen */ |
64 | AST1100 = __AST_CHIP(2, 0), |
65 | AST2100 = __AST_CHIP(2, 1), |
66 | AST2050 = __AST_CHIP(2, 2), // unused |
67 | /* 3rd gen */ |
68 | AST2200 = __AST_CHIP(3, 0), |
69 | AST2150 = __AST_CHIP(3, 1), |
70 | /* 4th gen */ |
71 | AST2300 = __AST_CHIP(4, 0), |
72 | AST1300 = __AST_CHIP(4, 1), |
73 | AST1050 = __AST_CHIP(4, 2), // unused |
74 | /* 5th gen */ |
75 | AST2400 = __AST_CHIP(5, 0), |
76 | AST1400 = __AST_CHIP(5, 1), |
77 | AST1250 = __AST_CHIP(5, 2), // unused |
78 | /* 6th gen */ |
79 | AST2500 = __AST_CHIP(6, 0), |
80 | AST2510 = __AST_CHIP(6, 1), |
81 | AST2520 = __AST_CHIP(6, 2), // unused |
82 | /* 7th gen */ |
83 | AST2600 = __AST_CHIP(7, 0), |
84 | AST2620 = __AST_CHIP(7, 1), // unused |
85 | }; |
86 | |
87 | #define __AST_CHIP_GEN(__chip) (((unsigned long)(__chip)) >> 16) |
88 | |
89 | enum ast_tx_chip { |
90 | AST_TX_NONE, |
91 | AST_TX_SIL164, |
92 | AST_TX_DP501, |
93 | AST_TX_ASTDP, |
94 | }; |
95 | |
96 | #define AST_TX_NONE_BIT BIT(AST_TX_NONE) |
97 | #define AST_TX_SIL164_BIT BIT(AST_TX_SIL164) |
98 | #define AST_TX_DP501_BIT BIT(AST_TX_DP501) |
99 | #define AST_TX_ASTDP_BIT BIT(AST_TX_ASTDP) |
100 | |
101 | enum ast_config_mode { |
102 | ast_use_p2a, |
103 | ast_use_dt, |
104 | ast_use_defaults |
105 | }; |
106 | |
107 | #define AST_DRAM_512Mx16 0 |
108 | #define AST_DRAM_1Gx16 1 |
109 | #define AST_DRAM_512Mx32 2 |
110 | #define AST_DRAM_1Gx32 3 |
111 | #define AST_DRAM_2Gx16 6 |
112 | #define AST_DRAM_4Gx16 7 |
113 | #define AST_DRAM_8Gx16 8 |
114 | |
115 | /* |
116 | * Hardware cursor |
117 | */ |
118 | |
119 | #define AST_MAX_HWC_WIDTH 64 |
120 | #define AST_MAX_HWC_HEIGHT 64 |
121 | |
122 | #define AST_HWC_SIZE (AST_MAX_HWC_WIDTH * AST_MAX_HWC_HEIGHT * 2) |
123 | #define AST_HWC_SIGNATURE_SIZE 32 |
124 | |
125 | /* define for signature structure */ |
126 | #define AST_HWC_SIGNATURE_CHECKSUM 0x00 |
127 | #define AST_HWC_SIGNATURE_SizeX 0x04 |
128 | #define AST_HWC_SIGNATURE_SizeY 0x08 |
129 | #define AST_HWC_SIGNATURE_X 0x0C |
130 | #define AST_HWC_SIGNATURE_Y 0x10 |
131 | #define AST_HWC_SIGNATURE_HOTSPOTX 0x14 |
132 | #define AST_HWC_SIGNATURE_HOTSPOTY 0x18 |
133 | |
134 | /* |
135 | * Planes |
136 | */ |
137 | |
138 | struct ast_plane { |
139 | struct drm_plane base; |
140 | |
141 | void __iomem *vaddr; |
142 | u64 offset; |
143 | unsigned long size; |
144 | }; |
145 | |
146 | static inline struct ast_plane *to_ast_plane(struct drm_plane *plane) |
147 | { |
148 | return container_of(plane, struct ast_plane, base); |
149 | } |
150 | |
151 | /* |
152 | * Connector with i2c channel |
153 | */ |
154 | |
155 | struct ast_i2c_chan { |
156 | struct i2c_adapter adapter; |
157 | struct drm_device *dev; |
158 | struct i2c_algo_bit_data bit; |
159 | }; |
160 | |
161 | struct ast_vga_connector { |
162 | struct drm_connector base; |
163 | struct ast_i2c_chan *i2c; |
164 | }; |
165 | |
166 | static inline struct ast_vga_connector * |
167 | to_ast_vga_connector(struct drm_connector *connector) |
168 | { |
169 | return container_of(connector, struct ast_vga_connector, base); |
170 | } |
171 | |
172 | struct ast_sil164_connector { |
173 | struct drm_connector base; |
174 | struct ast_i2c_chan *i2c; |
175 | }; |
176 | |
177 | static inline struct ast_sil164_connector * |
178 | to_ast_sil164_connector(struct drm_connector *connector) |
179 | { |
180 | return container_of(connector, struct ast_sil164_connector, base); |
181 | } |
182 | |
183 | struct ast_bmc_connector { |
184 | struct drm_connector base; |
185 | struct drm_connector *physical_connector; |
186 | }; |
187 | |
188 | static inline struct ast_bmc_connector * |
189 | to_ast_bmc_connector(struct drm_connector *connector) |
190 | { |
191 | return container_of(connector, struct ast_bmc_connector, base); |
192 | } |
193 | |
194 | /* |
195 | * Device |
196 | */ |
197 | |
198 | struct ast_device { |
199 | struct drm_device base; |
200 | |
201 | void __iomem *regs; |
202 | void __iomem *ioregs; |
203 | void __iomem *dp501_fw_buf; |
204 | |
205 | enum ast_config_mode config_mode; |
206 | enum ast_chip chip; |
207 | |
208 | uint32_t dram_bus_width; |
209 | uint32_t dram_type; |
210 | uint32_t mclk; |
211 | |
212 | void __iomem *vram; |
213 | unsigned long vram_base; |
214 | unsigned long vram_size; |
215 | unsigned long vram_fb_available; |
216 | |
217 | struct mutex modeset_lock; /* Protects access to modeset I/O registers in ioregs */ |
218 | |
219 | struct ast_plane primary_plane; |
220 | struct ast_plane cursor_plane; |
221 | struct drm_crtc crtc; |
222 | struct { |
223 | struct { |
224 | struct drm_encoder encoder; |
225 | struct ast_vga_connector vga_connector; |
226 | } vga; |
227 | struct { |
228 | struct drm_encoder encoder; |
229 | struct ast_sil164_connector sil164_connector; |
230 | } sil164; |
231 | struct { |
232 | struct drm_encoder encoder; |
233 | struct drm_connector connector; |
234 | } dp501; |
235 | struct { |
236 | struct drm_encoder encoder; |
237 | struct drm_connector connector; |
238 | } astdp; |
239 | struct { |
240 | struct drm_encoder encoder; |
241 | struct ast_bmc_connector bmc_connector; |
242 | } bmc; |
243 | } output; |
244 | |
245 | bool support_wide_screen; |
246 | |
247 | unsigned long tx_chip_types; /* bitfield of enum ast_chip_type */ |
248 | u8 *dp501_fw_addr; |
249 | const struct firmware *dp501_fw; /* dp501 fw */ |
250 | }; |
251 | |
252 | static inline struct ast_device *to_ast_device(struct drm_device *dev) |
253 | { |
254 | return container_of(dev, struct ast_device, base); |
255 | } |
256 | |
257 | struct drm_device *ast_device_create(struct pci_dev *pdev, |
258 | const struct drm_driver *drv, |
259 | enum ast_chip chip, |
260 | enum ast_config_mode config_mode, |
261 | void __iomem *regs, |
262 | void __iomem *ioregs, |
263 | bool need_post); |
264 | |
265 | static inline unsigned long __ast_gen(struct ast_device *ast) |
266 | { |
267 | return __AST_CHIP_GEN(ast->chip); |
268 | } |
269 | #define AST_GEN(__ast) __ast_gen(__ast) |
270 | |
271 | static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) |
272 | { |
273 | return __ast_gen(ast) == gen; |
274 | } |
275 | #define IS_AST_GEN1(__ast) __ast_gen_is_eq(__ast, 1) |
276 | #define IS_AST_GEN2(__ast) __ast_gen_is_eq(__ast, 2) |
277 | #define IS_AST_GEN3(__ast) __ast_gen_is_eq(__ast, 3) |
278 | #define IS_AST_GEN4(__ast) __ast_gen_is_eq(__ast, 4) |
279 | #define IS_AST_GEN5(__ast) __ast_gen_is_eq(__ast, 5) |
280 | #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) |
281 | #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) |
282 | |
283 | static inline u8 __ast_read8(const void __iomem *addr, u32 reg) |
284 | { |
285 | return ioread8(addr + reg); |
286 | } |
287 | |
288 | static inline u32 __ast_read32(const void __iomem *addr, u32 reg) |
289 | { |
290 | return ioread32(addr + reg); |
291 | } |
292 | |
293 | static inline void __ast_write8(void __iomem *addr, u32 reg, u8 val) |
294 | { |
295 | iowrite8(val, addr + reg); |
296 | } |
297 | |
298 | static inline void __ast_write32(void __iomem *addr, u32 reg, u32 val) |
299 | { |
300 | iowrite32(val, addr + reg); |
301 | } |
302 | |
303 | static inline u8 __ast_read8_i(void __iomem *addr, u32 reg, u8 index) |
304 | { |
305 | __ast_write8(addr, reg, val: index); |
306 | return __ast_read8(addr, reg: reg + 1); |
307 | } |
308 | |
309 | static inline u8 __ast_read8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask) |
310 | { |
311 | u8 val = __ast_read8_i(addr, reg, index); |
312 | |
313 | return val & read_mask; |
314 | } |
315 | |
316 | static inline void __ast_write8_i(void __iomem *addr, u32 reg, u8 index, u8 val) |
317 | { |
318 | __ast_write8(addr, reg, val: index); |
319 | __ast_write8(addr, reg: reg + 1, val); |
320 | } |
321 | |
322 | static inline void __ast_write8_i_masked(void __iomem *addr, u32 reg, u8 index, u8 read_mask, |
323 | u8 val) |
324 | { |
325 | u8 tmp = __ast_read8_i_masked(addr, reg, index, read_mask); |
326 | |
327 | tmp |= val; |
328 | __ast_write8_i(addr, reg, index, val: tmp); |
329 | } |
330 | |
331 | static inline u32 ast_read32(struct ast_device *ast, u32 reg) |
332 | { |
333 | return __ast_read32(addr: ast->regs, reg); |
334 | } |
335 | |
336 | static inline void ast_write32(struct ast_device *ast, u32 reg, u32 val) |
337 | { |
338 | __ast_write32(addr: ast->regs, reg, val); |
339 | } |
340 | |
341 | static inline u8 ast_io_read8(struct ast_device *ast, u32 reg) |
342 | { |
343 | return __ast_read8(addr: ast->ioregs, reg); |
344 | } |
345 | |
346 | static inline void ast_io_write8(struct ast_device *ast, u32 reg, u8 val) |
347 | { |
348 | __ast_write8(addr: ast->ioregs, reg, val); |
349 | } |
350 | |
351 | static inline u8 ast_get_index_reg(struct ast_device *ast, u32 base, u8 index) |
352 | { |
353 | return __ast_read8_i(addr: ast->ioregs, reg: base, index); |
354 | } |
355 | |
356 | static inline u8 ast_get_index_reg_mask(struct ast_device *ast, u32 base, u8 index, |
357 | u8 preserve_mask) |
358 | { |
359 | return __ast_read8_i_masked(addr: ast->ioregs, reg: base, index, read_mask: preserve_mask); |
360 | } |
361 | |
362 | static inline void ast_set_index_reg(struct ast_device *ast, u32 base, u8 index, u8 val) |
363 | { |
364 | __ast_write8_i(addr: ast->ioregs, reg: base, index, val); |
365 | } |
366 | |
367 | static inline void ast_set_index_reg_mask(struct ast_device *ast, u32 base, u8 index, |
368 | u8 preserve_mask, u8 val) |
369 | { |
370 | __ast_write8_i_masked(addr: ast->ioregs, reg: base, index, read_mask: preserve_mask, val); |
371 | } |
372 | |
373 | #define AST_VIDMEM_SIZE_8M 0x00800000 |
374 | #define AST_VIDMEM_SIZE_16M 0x01000000 |
375 | #define AST_VIDMEM_SIZE_32M 0x02000000 |
376 | #define AST_VIDMEM_SIZE_64M 0x04000000 |
377 | #define AST_VIDMEM_SIZE_128M 0x08000000 |
378 | |
379 | #define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M |
380 | |
381 | struct ast_vbios_stdtable { |
382 | u8 misc; |
383 | u8 seq[4]; |
384 | u8 crtc[25]; |
385 | u8 ar[20]; |
386 | u8 gr[9]; |
387 | }; |
388 | |
389 | struct ast_vbios_enhtable { |
390 | u32 ht; |
391 | u32 hde; |
392 | u32 hfp; |
393 | u32 hsync; |
394 | u32 vt; |
395 | u32 vde; |
396 | u32 vfp; |
397 | u32 vsync; |
398 | u32 dclk_index; |
399 | u32 flags; |
400 | u32 refresh_rate; |
401 | u32 refresh_rate_index; |
402 | u32 mode_id; |
403 | }; |
404 | |
405 | struct ast_vbios_dclk_info { |
406 | u8 param1; |
407 | u8 param2; |
408 | u8 param3; |
409 | }; |
410 | |
411 | struct ast_vbios_mode_info { |
412 | const struct ast_vbios_stdtable *std_table; |
413 | const struct ast_vbios_enhtable *enh_table; |
414 | }; |
415 | |
416 | struct ast_crtc_state { |
417 | struct drm_crtc_state base; |
418 | |
419 | /* Last known format of primary plane */ |
420 | const struct drm_format_info *format; |
421 | |
422 | struct ast_vbios_mode_info vbios_mode_info; |
423 | }; |
424 | |
425 | #define to_ast_crtc_state(state) container_of(state, struct ast_crtc_state, base) |
426 | |
427 | int ast_mode_config_init(struct ast_device *ast); |
428 | |
429 | #define AST_MM_ALIGN_SHIFT 4 |
430 | #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) |
431 | |
432 | #define AST_DP501_FW_VERSION_MASK GENMASK(7, 4) |
433 | #define AST_DP501_FW_VERSION_1 BIT(4) |
434 | #define AST_DP501_PNP_CONNECTED BIT(1) |
435 | |
436 | #define AST_DP501_DEFAULT_DCLK 65 |
437 | |
438 | #define AST_DP501_GBL_VERSION 0xf000 |
439 | #define AST_DP501_PNPMONITOR 0xf010 |
440 | #define AST_DP501_LINKRATE 0xf014 |
441 | #define AST_DP501_EDID_DATA 0xf020 |
442 | |
443 | #define AST_DP_POWER_ON true |
444 | #define AST_DP_POWER_OFF false |
445 | |
446 | /* |
447 | * ASTDP resoultion table: |
448 | * EX: ASTDP_A_B_C: |
449 | * A: Resolution |
450 | * B: Refresh Rate |
451 | * C: Misc information, such as CVT, Reduce Blanked |
452 | */ |
453 | #define ASTDP_640x480_60 0x00 |
454 | #define ASTDP_640x480_72 0x01 |
455 | #define ASTDP_640x480_75 0x02 |
456 | #define ASTDP_640x480_85 0x03 |
457 | #define ASTDP_800x600_56 0x04 |
458 | #define ASTDP_800x600_60 0x05 |
459 | #define ASTDP_800x600_72 0x06 |
460 | #define ASTDP_800x600_75 0x07 |
461 | #define ASTDP_800x600_85 0x08 |
462 | #define ASTDP_1024x768_60 0x09 |
463 | #define ASTDP_1024x768_70 0x0A |
464 | #define ASTDP_1024x768_75 0x0B |
465 | #define ASTDP_1024x768_85 0x0C |
466 | #define ASTDP_1280x1024_60 0x0D |
467 | #define ASTDP_1280x1024_75 0x0E |
468 | #define ASTDP_1280x1024_85 0x0F |
469 | #define ASTDP_1600x1200_60 0x10 |
470 | #define ASTDP_320x240_60 0x11 |
471 | #define ASTDP_400x300_60 0x12 |
472 | #define ASTDP_512x384_60 0x13 |
473 | #define ASTDP_1920x1200_60 0x14 |
474 | #define ASTDP_1920x1080_60 0x15 |
475 | #define ASTDP_1280x800_60 0x16 |
476 | #define ASTDP_1280x800_60_RB 0x17 |
477 | #define ASTDP_1440x900_60 0x18 |
478 | #define ASTDP_1440x900_60_RB 0x19 |
479 | #define ASTDP_1680x1050_60 0x1A |
480 | #define ASTDP_1680x1050_60_RB 0x1B |
481 | #define ASTDP_1600x900_60 0x1C |
482 | #define ASTDP_1600x900_60_RB 0x1D |
483 | #define ASTDP_1366x768_60 0x1E |
484 | #define ASTDP_1152x864_75 0x1F |
485 | |
486 | int ast_mm_init(struct ast_device *ast); |
487 | |
488 | /* ast post */ |
489 | void ast_post_gpu(struct drm_device *dev); |
490 | u32 ast_mindwm(struct ast_device *ast, u32 r); |
491 | void ast_moutdwm(struct ast_device *ast, u32 r, u32 v); |
492 | void ast_patch_ahb_2500(void __iomem *regs); |
493 | /* ast dp501 */ |
494 | void ast_set_dp501_video_output(struct drm_device *dev, u8 mode); |
495 | bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); |
496 | bool ast_dp501_is_connected(struct ast_device *ast); |
497 | bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata); |
498 | u8 ast_get_dp501_max_clk(struct drm_device *dev); |
499 | void ast_init_3rdtx(struct drm_device *dev); |
500 | |
501 | /* ast_i2c.c */ |
502 | struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); |
503 | |
504 | /* aspeed DP */ |
505 | bool ast_astdp_is_connected(struct ast_device *ast); |
506 | int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata); |
507 | void ast_dp_launch(struct drm_device *dev); |
508 | void ast_dp_power_on_off(struct drm_device *dev, bool no); |
509 | void ast_dp_set_on_off(struct drm_device *dev, bool no); |
510 | void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode); |
511 | |
512 | #endif |
513 | |