1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright 2010 Matt Turner.
4  * Copyright 2012 Red Hat
5  *
6  * Authors: Matthew Garrett
7  * 	    Matt Turner
8  *	    Dave Airlie
9  */
10 #ifndef __MGAG200_DRV_H__
11 #define __MGAG200_DRV_H__
12 
13 #include <linux/i2c-algo-bit.h>
14 #include <linux/i2c.h>
15 
16 #include <video/vga.h>
17 
18 #include <drm/drm_encoder.h>
19 #include <drm/drm_fb_helper.h>
20 #include <drm/drm_gem.h>
21 #include <drm/drm_gem_vram_helper.h>
22 #include <drm/drm_vram_mm_helper.h>
23 
24 #include "mgag200_reg.h"
25 
26 #define DRIVER_AUTHOR		"Matthew Garrett"
27 
28 #define DRIVER_NAME		"mgag200"
29 #define DRIVER_DESC		"MGA G200 SE"
30 #define DRIVER_DATE		"20110418"
31 
32 #define DRIVER_MAJOR		1
33 #define DRIVER_MINOR		0
34 #define DRIVER_PATCHLEVEL	0
35 
36 #define MGAG200FB_CONN_LIMIT 1
37 
38 #define RREG8(reg) ioread8(((void __iomem *)mdev->rmmio) + (reg))
39 #define WREG8(reg, v) iowrite8(v, ((void __iomem *)mdev->rmmio) + (reg))
40 #define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg))
41 #define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg))
42 
43 #define ATTR_INDEX 0x1fc0
44 #define ATTR_DATA 0x1fc1
45 
46 #define WREG_ATTR(reg, v)					\
47 	do {							\
48 		RREG8(0x1fda);					\
49 		WREG8(ATTR_INDEX, reg);				\
50 		WREG8(ATTR_DATA, v);				\
51 	} while (0)						\
52 
53 #define WREG_SEQ(reg, v)					\
54 	do {							\
55 		WREG8(MGAREG_SEQ_INDEX, reg);			\
56 		WREG8(MGAREG_SEQ_DATA, v);			\
57 	} while (0)						\
58 
59 #define WREG_CRT(reg, v)					\
60 	do {							\
61 		WREG8(MGAREG_CRTC_INDEX, reg);			\
62 		WREG8(MGAREG_CRTC_DATA, v);			\
63 	} while (0)						\
64 
65 
66 #define WREG_ECRT(reg, v)					\
67 	do {							\
68 		WREG8(MGAREG_CRTCEXT_INDEX, reg);				\
69 		WREG8(MGAREG_CRTCEXT_DATA, v);				\
70 	} while (0)						\
71 
72 #define GFX_INDEX 0x1fce
73 #define GFX_DATA 0x1fcf
74 
75 #define WREG_GFX(reg, v)					\
76 	do {							\
77 		WREG8(GFX_INDEX, reg);				\
78 		WREG8(GFX_DATA, v);				\
79 	} while (0)						\
80 
81 #define DAC_INDEX 0x3c00
82 #define DAC_DATA 0x3c0a
83 
84 #define WREG_DAC(reg, v)					\
85 	do {							\
86 		WREG8(DAC_INDEX, reg);				\
87 		WREG8(DAC_DATA, v);				\
88 	} while (0)						\
89 
90 #define MGA_MISC_OUT 0x1fc2
91 #define MGA_MISC_IN 0x1fcc
92 
93 #define MGAG200_MAX_FB_HEIGHT 4096
94 #define MGAG200_MAX_FB_WIDTH 4096
95 
96 #define MATROX_DPMS_CLEARED (-1)
97 
98 #define to_mga_crtc(x) container_of(x, struct mga_crtc, base)
99 #define to_mga_encoder(x) container_of(x, struct mga_encoder, base)
100 #define to_mga_connector(x) container_of(x, struct mga_connector, base)
101 
102 struct mga_crtc {
103 	struct drm_crtc base;
104 	u8 lut_r[256], lut_g[256], lut_b[256];
105 	int last_dpms;
106 	bool enabled;
107 };
108 
109 struct mga_mode_info {
110 	bool mode_config_initialized;
111 	struct mga_crtc *crtc;
112 };
113 
114 struct mga_encoder {
115 	struct drm_encoder base;
116 	int last_dpms;
117 };
118 
119 
120 struct mga_i2c_chan {
121 	struct i2c_adapter adapter;
122 	struct drm_device *dev;
123 	struct i2c_algo_bit_data bit;
124 	int data, clock;
125 };
126 
127 struct mga_connector {
128 	struct drm_connector base;
129 	struct mga_i2c_chan *i2c;
130 };
131 
132 struct mga_cursor {
133 	/*
134 	   We have to have 2 buffers for the cursor to avoid occasional
135 	   corruption while switching cursor icons.
136 	   If either of these is NULL, then don't do hardware cursors, and
137 	   fall back to software.
138 	*/
139 	struct drm_gem_vram_object *pixels_1;
140 	struct drm_gem_vram_object *pixels_2;
141 	/* The currently displayed icon, this points to one of pixels_1, or pixels_2 */
142 	struct drm_gem_vram_object *pixels_current;
143 };
144 
145 struct mga_mc {
146 	resource_size_t			vram_size;
147 	resource_size_t			vram_base;
148 	resource_size_t			vram_window;
149 };
150 
151 enum mga_type {
152 	G200_SE_A,
153 	G200_SE_B,
154 	G200_WB,
155 	G200_EV,
156 	G200_EH,
157 	G200_EH3,
158 	G200_ER,
159 	G200_EW3,
160 };
161 
162 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
163 
164 struct mga_device {
165 	struct drm_device		*dev;
166 	unsigned long			flags;
167 
168 	resource_size_t			rmmio_base;
169 	resource_size_t			rmmio_size;
170 	void __iomem			*rmmio;
171 
172 	struct mga_mc			mc;
173 	struct mga_mode_info		mode_info;
174 
175 	struct mga_cursor cursor;
176 
177 	bool				suspended;
178 	int				num_crtc;
179 	enum mga_type			type;
180 	int				has_sdram;
181 	struct drm_display_mode		mode;
182 
183 	int bpp_shifts[4];
184 
185 	int fb_mtrr;
186 
187 	/* SE model number stored in reg 0x1e24 */
188 	u32 unique_rev_id;
189 };
190 
191 				/* mgag200_mode.c */
192 int mgag200_modeset_init(struct mga_device *mdev);
193 void mgag200_modeset_fini(struct mga_device *mdev);
194 
195 				/* mgag200_main.c */
196 int mgag200_driver_load(struct drm_device *dev, unsigned long flags);
197 void mgag200_driver_unload(struct drm_device *dev);
198 
199 				/* mgag200_i2c.c */
200 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
201 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
202 
203 int mgag200_mm_init(struct mga_device *mdev);
204 void mgag200_mm_fini(struct mga_device *mdev);
205 int mgag200_mmap(struct file *filp, struct vm_area_struct *vma);
206 
207 int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
208 						uint32_t handle, uint32_t width, uint32_t height);
209 int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
210 
211 #endif				/* __MGAG200_DRV_H__ */
212