GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / gpu / drm / mgag200 / mgag200_drv.h
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_shmem_helper.h>
22 #include <drm/drm_simple_kms_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 RREG8(reg) ioread8(((void __iomem *)mdev->rmmio) + (reg))
37 #define WREG8(reg, v) iowrite8(v, ((void __iomem *)mdev->rmmio) + (reg))
38 #define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg))
39 #define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg))
40
41 #define MGA_BIOS_OFFSET         0x7ffc
42
43 #define ATTR_INDEX 0x1fc0
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)
61
62 #define WREG_ATTR(reg, v)                                       \
63         do {                                                    \
64                 RREG8(0x1fda);                                  \
65                 WREG8(ATTR_INDEX, reg);                         \
66                 WREG8(ATTR_DATA, v);                            \
67         } while (0)                                             \
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
75 #define WREG_SEQ(reg, v)                                        \
76         do {                                                    \
77                 WREG8(MGAREG_SEQ_INDEX, reg);                   \
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);                    \
85         } while (0)                                             \
86
87 #define WREG_CRT(reg, v)                                        \
88         do {                                                    \
89                 WREG8(MGAREG_CRTC_INDEX, reg);                  \
90                 WREG8(MGAREG_CRTC_DATA, v);                     \
91         } while (0)                                             \
92
93 #define RREG_ECRT(reg, v)                                       \
94         do {                                                    \
95                 WREG8(MGAREG_CRTCEXT_INDEX, reg);               \
96                 v = RREG8(MGAREG_CRTCEXT_DATA);                 \
97         } while (0)                                             \
98
99 #define WREG_ECRT(reg, v)                                       \
100         do {                                                    \
101                 WREG8(MGAREG_CRTCEXT_INDEX, reg);                               \
102                 WREG8(MGAREG_CRTCEXT_DATA, v);                          \
103         } while (0)                                             \
104
105 #define GFX_INDEX 0x1fce
106 #define GFX_DATA 0x1fcf
107
108 #define WREG_GFX(reg, v)                                        \
109         do {                                                    \
110                 WREG8(GFX_INDEX, reg);                          \
111                 WREG8(GFX_DATA, v);                             \
112         } while (0)                                             \
113
114 #define DAC_INDEX 0x3c00
115 #define DAC_DATA 0x3c0a
116
117 #define WREG_DAC(reg, v)                                        \
118         do {                                                    \
119                 WREG8(DAC_INDEX, reg);                          \
120                 WREG8(DAC_DATA, v);                             \
121         } while (0)                                             \
122
123 #define MGA_MISC_OUT 0x1fc2
124 #define MGA_MISC_IN 0x1fcc
125
126 #define MGAG200_MAX_FB_HEIGHT 4096
127 #define MGAG200_MAX_FB_WIDTH 4096
128
129 #define to_mga_connector(x) container_of(x, struct mga_connector, base)
130
131 struct mga_i2c_chan {
132         struct i2c_adapter adapter;
133         struct drm_device *dev;
134         struct i2c_algo_bit_data bit;
135         int data, clock;
136 };
137
138 struct mga_connector {
139         struct drm_connector base;
140         struct mga_i2c_chan *i2c;
141 };
142
143 struct mga_mc {
144         resource_size_t                 vram_size;
145         resource_size_t                 vram_base;
146         resource_size_t                 vram_window;
147 };
148
149 enum mga_type {
150         G200_PCI,
151         G200_AGP,
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 /* 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
168 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
169
170 struct mga_device {
171         struct drm_device               base;
172         unsigned long                   flags;
173
174         resource_size_t                 rmmio_base;
175         resource_size_t                 rmmio_size;
176         void __iomem                    *rmmio;
177
178         struct mga_mc                   mc;
179
180         void __iomem                    *vram;
181         size_t                          vram_fb_available;
182
183         enum mga_type                   type;
184
185         int bpp_shifts[4];
186
187         int fb_mtrr;
188
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;
200
201
202         struct mga_connector connector;
203         struct drm_simple_display_pipe display_pipe;
204 };
205
206 static inline struct mga_device *to_mga_device(struct drm_device *dev)
207 {
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;
221 }
222
223                                 /* mgag200_mode.c */
224 int mgag200_modeset_init(struct mga_device *mdev);
225
226                                 /* mgag200_i2c.c */
227 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
228 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
229
230                                 /* mgag200_mm.c */
231 int mgag200_mm_init(struct mga_device *mdev);
232
233 #endif                          /* __MGAG200_DRV_H__ */