a18384c41fc4fd10b8dc6a55546afd67c360d08e
[linux-2.6-microblaze.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 struct mga_device;
130 struct mgag200_pll;
131
132 /*
133  * Stores parameters for programming the PLLs
134  *
135  * Fref: reference frequency (A: 25.175 Mhz, B: 28.361, C: XX Mhz)
136  * Fo: output frequency
137  * Fvco = Fref * (N / M)
138  * Fo = Fvco / P
139  *
140  * S = [0..3]
141  */
142 struct mgag200_pll_values {
143         unsigned int m;
144         unsigned int n;
145         unsigned int p;
146         unsigned int s;
147 };
148
149 struct mgag200_pll_funcs {
150         int (*compute)(struct mgag200_pll *pll, long clock, struct mgag200_pll_values *pllc);
151         void (*update)(struct mgag200_pll *pll, const struct mgag200_pll_values *pllc);
152 };
153
154 struct mgag200_pll {
155         struct mga_device *mdev;
156
157         const struct mgag200_pll_funcs *funcs;
158 };
159
160 struct mgag200_crtc_state {
161         struct drm_crtc_state base;
162
163         struct mgag200_pll_values pixpllc;
164 };
165
166 static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_state *base)
167 {
168         return container_of(base, struct mgag200_crtc_state, base);
169 }
170
171 #define to_mga_connector(x) container_of(x, struct mga_connector, base)
172
173 struct mga_i2c_chan {
174         struct i2c_adapter adapter;
175         struct drm_device *dev;
176         struct i2c_algo_bit_data bit;
177         int data, clock;
178 };
179
180 struct mga_connector {
181         struct drm_connector base;
182         struct mga_i2c_chan *i2c;
183 };
184
185 struct mga_mc {
186         resource_size_t                 vram_size;
187         resource_size_t                 vram_base;
188         resource_size_t                 vram_window;
189 };
190
191 enum mga_type {
192         G200_PCI,
193         G200_AGP,
194         G200_SE_A,
195         G200_SE_B,
196         G200_WB,
197         G200_EV,
198         G200_EH,
199         G200_EH3,
200         G200_ER,
201         G200_EW3,
202 };
203
204 /* HW does not handle 'startadd' field correct. */
205 #define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8)
206
207 #define MGAG200_TYPE_MASK       (0x000000ff)
208 #define MGAG200_FLAG_MASK       (0x00ffff00)
209
210 #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B)
211
212 struct mga_device {
213         struct drm_device               base;
214         unsigned long                   flags;
215
216         struct mutex                    rmmio_lock; /* Protects access to rmmio */
217         resource_size_t                 rmmio_base;
218         resource_size_t                 rmmio_size;
219         void __iomem                    *rmmio;
220
221         struct mga_mc                   mc;
222
223         void __iomem                    *vram;
224         size_t                          vram_fb_available;
225
226         enum mga_type                   type;
227
228         union {
229                 struct {
230                         long ref_clk;
231                         long pclk_min;
232                         long pclk_max;
233                 } g200;
234                 struct {
235                         /* SE model number stored in reg 0x1e24 */
236                         u32 unique_rev_id;
237                 } g200se;
238         } model;
239
240         struct mga_connector connector;
241         struct mgag200_pll pixpll;
242         struct drm_simple_display_pipe display_pipe;
243 };
244
245 static inline struct mga_device *to_mga_device(struct drm_device *dev)
246 {
247         return container_of(dev, struct mga_device, base);
248 }
249
250                                 /* mgag200_mode.c */
251 int mgag200_modeset_init(struct mga_device *mdev);
252
253                                 /* mgag200_i2c.c */
254 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
255 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
256
257                                 /* mgag200_mm.c */
258 int mgag200_mm_init(struct mga_device *mdev);
259
260                                 /* mgag200_pll.c */
261 int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev);
262
263 #endif                          /* __MGAG200_DRV_H__ */