Subversion Repositories Kolibri OS

Rev

Rev 1126 | Rev 1179 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1126 Rev 1128
1
/*
1
/*
2
 * Copyright © 2007 David Airlie
2
 * Copyright © 2007 David Airlie
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice (including the next
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
13
 * Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
21
 * DEALINGS IN THE SOFTWARE.
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *     David Airlie
24
 *     David Airlie
25
 */
25
 */
26
    /*
26
    /*
27
     *  Modularization
27
     *  Modularization
28
     */
28
     */
29
 
29
 
30
//#include 
30
//#include 
31
//#include 
31
//#include 
32
//#include 
32
//#include 
33
//#include 
33
//#include 
34
//#include 
34
//#include 
35
//#include 
35
//#include 
36
//#include 
36
//#include 
37
//#include 
37
//#include 
38
//#include 
38
//#include 
39
//#include 
39
//#include 
40
 
40
 
41
#include "drmP.h"
41
#include "drmP.h"
42
#include "drm.h"
42
#include "drm.h"
43
#include "drm_crtc.h"
43
#include "drm_crtc.h"
44
#include "drm_crtc_helper.h"
44
#include "drm_crtc_helper.h"
45
#include "radeon_drm.h"
45
#include "radeon_drm.h"
46
#include "radeon.h"
46
#include "radeon.h"
47
 
47
 
48
#include 
48
#include 
49
#include "radeon_object.h"
49
#include "radeon_object.h"
50
 
50
 
51
 
51
 
52
#define FB_TYPE_PACKED_PIXELS       0   /* Packed Pixels    */
52
#define FB_TYPE_PACKED_PIXELS       0   /* Packed Pixels    */
53
#define FB_VISUAL_TRUECOLOR     2   /* True color   */
53
#define FB_VISUAL_TRUECOLOR     2   /* True color   */
54
 
54
 
55
struct fb_fix_screeninfo {
55
struct fb_fix_screeninfo {
56
    char id[16];            /* identification string eg "TT Builtin" */
56
    char id[16];            /* identification string eg "TT Builtin" */
57
    unsigned long smem_start;   /* Start of frame buffer mem */
57
    unsigned long smem_start;   /* Start of frame buffer mem */
58
                    /* (physical address) */
58
                    /* (physical address) */
59
    __u32 smem_len;         /* Length of frame buffer mem */
59
    __u32 smem_len;         /* Length of frame buffer mem */
60
    __u32 type;         /* see FB_TYPE_*        */
60
    __u32 type;         /* see FB_TYPE_*        */
61
    __u32 type_aux;         /* Interleave for interleaved Planes */
61
    __u32 type_aux;         /* Interleave for interleaved Planes */
62
    __u32 visual;           /* see FB_VISUAL_*      */
62
    __u32 visual;           /* see FB_VISUAL_*      */
63
    __u16 xpanstep;         /* zero if no hardware panning  */
63
    __u16 xpanstep;         /* zero if no hardware panning  */
64
    __u16 ypanstep;         /* zero if no hardware panning  */
64
    __u16 ypanstep;         /* zero if no hardware panning  */
65
    __u16 ywrapstep;        /* zero if no hardware ywrap    */
65
    __u16 ywrapstep;        /* zero if no hardware ywrap    */
66
    __u32 line_length;      /* length of a line in bytes    */
66
    __u32 line_length;      /* length of a line in bytes    */
67
    unsigned long mmio_start;   /* Start of Memory Mapped I/O   */
67
    unsigned long mmio_start;   /* Start of Memory Mapped I/O   */
68
                    /* (physical address) */
68
                    /* (physical address) */
69
    __u32 mmio_len;         /* Length of Memory Mapped I/O  */
69
    __u32 mmio_len;         /* Length of Memory Mapped I/O  */
70
    __u32 accel;            /* Indicate to driver which */
70
    __u32 accel;            /* Indicate to driver which */
71
                    /*  specific chip/card we have  */
71
                    /*  specific chip/card we have  */
72
    __u16 reserved[3];      /* Reserved for future compatibility */
72
    __u16 reserved[3];      /* Reserved for future compatibility */
73
};
73
};
74
 
74
 
75
 
75
 
76
 
76
 
77
 
77
 
78
struct fb_bitfield {
78
struct fb_bitfield {
79
    __u32 offset;           /* beginning of bitfield    */
79
    __u32 offset;           /* beginning of bitfield    */
80
    __u32 length;           /* length of bitfield       */
80
    __u32 length;           /* length of bitfield       */
81
    __u32 msb_right;        /* != 0 : Most significant bit is */
81
    __u32 msb_right;        /* != 0 : Most significant bit is */
82
                    /* right */
82
                    /* right */
83
};
83
};
84
 
84
 
85
 
85
 
86
struct fb_var_screeninfo {
86
struct fb_var_screeninfo {
87
    __u32 xres;         /* visible resolution       */
87
    __u32 xres;         /* visible resolution       */
88
    __u32 yres;
88
    __u32 yres;
89
    __u32 xres_virtual;     /* virtual resolution       */
89
    __u32 xres_virtual;     /* virtual resolution       */
90
    __u32 yres_virtual;
90
    __u32 yres_virtual;
91
    __u32 xoffset;          /* offset from virtual to visible */
91
    __u32 xoffset;          /* offset from virtual to visible */
92
    __u32 yoffset;          /* resolution           */
92
    __u32 yoffset;          /* resolution           */
93
 
93
 
94
    __u32 bits_per_pixel;       /* guess what           */
94
    __u32 bits_per_pixel;       /* guess what           */
95
    __u32 grayscale;        /* != 0 Graylevels instead of colors */
95
    __u32 grayscale;        /* != 0 Graylevels instead of colors */
96
 
96
 
97
    struct fb_bitfield red;     /* bitfield in fb mem if true color, */
97
    struct fb_bitfield red;     /* bitfield in fb mem if true color, */
98
    struct fb_bitfield green;   /* else only length is significant */
98
    struct fb_bitfield green;   /* else only length is significant */
99
    struct fb_bitfield blue;
99
    struct fb_bitfield blue;
100
    struct fb_bitfield transp;  /* transparency         */
100
    struct fb_bitfield transp;  /* transparency         */
101
 
101
 
102
    __u32 nonstd;           /* != 0 Non standard pixel format */
102
    __u32 nonstd;           /* != 0 Non standard pixel format */
103
 
103
 
104
    __u32 activate;         /* see FB_ACTIVATE_*        */
104
    __u32 activate;         /* see FB_ACTIVATE_*        */
105
 
105
 
106
    __u32 height;           /* height of picture in mm    */
106
    __u32 height;           /* height of picture in mm    */
107
    __u32 width;            /* width of picture in mm     */
107
    __u32 width;            /* width of picture in mm     */
108
 
108
 
109
    __u32 accel_flags;      /* (OBSOLETE) see fb_info.flags */
109
    __u32 accel_flags;      /* (OBSOLETE) see fb_info.flags */
110
 
110
 
111
    /* Timing: All values in pixclocks, except pixclock (of course) */
111
    /* Timing: All values in pixclocks, except pixclock (of course) */
112
    __u32 pixclock;         /* pixel clock in ps (pico seconds) */
112
    __u32 pixclock;         /* pixel clock in ps (pico seconds) */
113
    __u32 left_margin;      /* time from sync to picture    */
113
    __u32 left_margin;      /* time from sync to picture    */
114
    __u32 right_margin;     /* time from picture to sync    */
114
    __u32 right_margin;     /* time from picture to sync    */
115
    __u32 upper_margin;     /* time from sync to picture    */
115
    __u32 upper_margin;     /* time from sync to picture    */
116
    __u32 lower_margin;
116
    __u32 lower_margin;
117
    __u32 hsync_len;        /* length of horizontal sync    */
117
    __u32 hsync_len;        /* length of horizontal sync    */
118
    __u32 vsync_len;        /* length of vertical sync  */
118
    __u32 vsync_len;        /* length of vertical sync  */
119
    __u32 sync;         /* see FB_SYNC_*        */
119
    __u32 sync;         /* see FB_SYNC_*        */
120
    __u32 vmode;            /* see FB_VMODE_*       */
120
    __u32 vmode;            /* see FB_VMODE_*       */
121
    __u32 rotate;           /* angle we rotate counter clockwise */
121
    __u32 rotate;           /* angle we rotate counter clockwise */
122
    __u32 reserved[5];      /* Reserved for future compatibility */
122
    __u32 reserved[5];      /* Reserved for future compatibility */
123
};
123
};
124
 
124
 
125
 
125
 
126
 
126
 
127
struct fb_chroma {
127
struct fb_chroma {
128
    __u32 redx; /* in fraction of 1024 */
128
    __u32 redx; /* in fraction of 1024 */
129
    __u32 greenx;
129
    __u32 greenx;
130
    __u32 bluex;
130
    __u32 bluex;
131
    __u32 whitex;
131
    __u32 whitex;
132
    __u32 redy;
132
    __u32 redy;
133
    __u32 greeny;
133
    __u32 greeny;
134
    __u32 bluey;
134
    __u32 bluey;
135
    __u32 whitey;
135
    __u32 whitey;
136
};
136
};
137
 
137
 
138
struct fb_videomode {
138
struct fb_videomode {
139
    const char *name;   /* optional */
139
    const char *name;   /* optional */
140
    u32 refresh;        /* optional */
140
    u32 refresh;        /* optional */
141
    u32 xres;
141
    u32 xres;
142
    u32 yres;
142
    u32 yres;
143
    u32 pixclock;
143
    u32 pixclock;
144
    u32 left_margin;
144
    u32 left_margin;
145
    u32 right_margin;
145
    u32 right_margin;
146
    u32 upper_margin;
146
    u32 upper_margin;
147
    u32 lower_margin;
147
    u32 lower_margin;
148
    u32 hsync_len;
148
    u32 hsync_len;
149
    u32 vsync_len;
149
    u32 vsync_len;
150
    u32 sync;
150
    u32 sync;
151
    u32 vmode;
151
    u32 vmode;
152
    u32 flag;
152
    u32 flag;
153
};
153
};
154
 
154
 
155
 
155
 
156
struct fb_monspecs {
156
struct fb_monspecs {
157
    struct fb_chroma chroma;
157
    struct fb_chroma chroma;
158
    struct fb_videomode *modedb;    /* mode database */
158
    struct fb_videomode *modedb;    /* mode database */
159
    __u8  manufacturer[4];      /* Manufacturer */
159
    __u8  manufacturer[4];      /* Manufacturer */
160
    __u8  monitor[14];      /* Monitor String */
160
    __u8  monitor[14];      /* Monitor String */
161
    __u8  serial_no[14];        /* Serial Number */
161
    __u8  serial_no[14];        /* Serial Number */
162
    __u8  ascii[14];        /* ? */
162
    __u8  ascii[14];        /* ? */
163
    __u32 modedb_len;       /* mode database length */
163
    __u32 modedb_len;       /* mode database length */
164
    __u32 model;            /* Monitor Model */
164
    __u32 model;            /* Monitor Model */
165
    __u32 serial;           /* Serial Number - Integer */
165
    __u32 serial;           /* Serial Number - Integer */
166
    __u32 year;         /* Year manufactured */
166
    __u32 year;         /* Year manufactured */
167
    __u32 week;         /* Week Manufactured */
167
    __u32 week;         /* Week Manufactured */
168
    __u32 hfmin;            /* hfreq lower limit (Hz) */
168
    __u32 hfmin;            /* hfreq lower limit (Hz) */
169
    __u32 hfmax;            /* hfreq upper limit (Hz) */
169
    __u32 hfmax;            /* hfreq upper limit (Hz) */
170
    __u32 dclkmin;          /* pixelclock lower limit (Hz) */
170
    __u32 dclkmin;          /* pixelclock lower limit (Hz) */
171
    __u32 dclkmax;          /* pixelclock upper limit (Hz) */
171
    __u32 dclkmax;          /* pixelclock upper limit (Hz) */
172
    __u16 input;            /* display type - see FB_DISP_* */
172
    __u16 input;            /* display type - see FB_DISP_* */
173
    __u16 dpms;         /* DPMS support - see FB_DPMS_ */
173
    __u16 dpms;         /* DPMS support - see FB_DPMS_ */
174
    __u16 signal;           /* Signal Type - see FB_SIGNAL_* */
174
    __u16 signal;           /* Signal Type - see FB_SIGNAL_* */
175
    __u16 vfmin;            /* vfreq lower limit (Hz) */
175
    __u16 vfmin;            /* vfreq lower limit (Hz) */
176
    __u16 vfmax;            /* vfreq upper limit (Hz) */
176
    __u16 vfmax;            /* vfreq upper limit (Hz) */
177
    __u16 gamma;            /* Gamma - in fractions of 100 */
177
    __u16 gamma;            /* Gamma - in fractions of 100 */
178
    __u16 gtf   : 1;        /* supports GTF */
178
    __u16 gtf   : 1;        /* supports GTF */
179
    __u16 misc;         /* Misc flags - see FB_MISC_* */
179
    __u16 misc;         /* Misc flags - see FB_MISC_* */
180
    __u8  version;          /* EDID version... */
180
    __u8  version;          /* EDID version... */
181
    __u8  revision;         /* ...and revision */
181
    __u8  revision;         /* ...and revision */
182
    __u8  max_x;            /* Maximum horizontal size (cm) */
182
    __u8  max_x;            /* Maximum horizontal size (cm) */
183
    __u8  max_y;            /* Maximum vertical size (cm) */
183
    __u8  max_y;            /* Maximum vertical size (cm) */
184
};
184
};
185
 
185
 
186
 
186
 
187
struct fb_info {
187
struct fb_info {
188
    int node;
188
    int node;
189
    int flags;
189
    int flags;
190
//    struct mutex lock;      /* Lock for open/release/ioctl funcs */
190
//    struct mutex lock;      /* Lock for open/release/ioctl funcs */
191
//    struct mutex mm_lock;       /* Lock for fb_mmap and smem_* fields */
191
//    struct mutex mm_lock;       /* Lock for fb_mmap and smem_* fields */
192
    struct fb_var_screeninfo var;   /* Current var */
192
    struct fb_var_screeninfo var;   /* Current var */
193
    struct fb_fix_screeninfo fix;   /* Current fix */
193
    struct fb_fix_screeninfo fix;   /* Current fix */
194
    struct fb_monspecs monspecs;    /* Current Monitor specs */
194
    struct fb_monspecs monspecs;    /* Current Monitor specs */
195
//    struct work_struct queue;   /* Framebuffer event queue */
195
//    struct work_struct queue;   /* Framebuffer event queue */
196
//    struct fb_pixmap pixmap;    /* Image hardware mapper */
196
//    struct fb_pixmap pixmap;    /* Image hardware mapper */
197
//    struct fb_pixmap sprite;    /* Cursor hardware mapper */
197
//    struct fb_pixmap sprite;    /* Cursor hardware mapper */
198
//    struct fb_cmap cmap;        /* Current cmap */
198
//    struct fb_cmap cmap;        /* Current cmap */
199
    struct list_head modelist;      /* mode list */
199
    struct list_head modelist;      /* mode list */
200
    struct fb_videomode *mode;  /* current mode */
200
    struct fb_videomode *mode;  /* current mode */
201
 
201
 
202
#ifdef CONFIG_FB_BACKLIGHT
202
#ifdef CONFIG_FB_BACKLIGHT
203
    /* assigned backlight device */
203
    /* assigned backlight device */
204
    /* set before framebuffer registration,
204
    /* set before framebuffer registration,
205
       remove after unregister */
205
       remove after unregister */
206
    struct backlight_device *bl_dev;
206
    struct backlight_device *bl_dev;
207
 
207
 
208
    /* Backlight level curve */
208
    /* Backlight level curve */
209
    struct mutex bl_curve_mutex;
209
    struct mutex bl_curve_mutex;
210
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
210
    u8 bl_curve[FB_BACKLIGHT_LEVELS];
211
#endif
211
#endif
212
#ifdef CONFIG_FB_DEFERRED_IO
212
#ifdef CONFIG_FB_DEFERRED_IO
213
    struct delayed_work deferred_work;
213
    struct delayed_work deferred_work;
214
    struct fb_deferred_io *fbdefio;
214
    struct fb_deferred_io *fbdefio;
215
#endif
215
#endif
216
 
216
 
217
    struct fb_ops *fbops;
217
    struct fb_ops *fbops;
218
//    struct device *device;      /* This is the parent */
218
//    struct device *device;      /* This is the parent */
219
//   struct device *dev;     /* This is this fb device */
219
//   struct device *dev;     /* This is this fb device */
220
    int class_flag;                    /* private sysfs flags */
220
    int class_flag;                    /* private sysfs flags */
221
#ifdef CONFIG_FB_TILEBLITTING
221
#ifdef CONFIG_FB_TILEBLITTING
222
    struct fb_tile_ops *tileops;    /* Tile Blitting */
222
    struct fb_tile_ops *tileops;    /* Tile Blitting */
223
#endif
223
#endif
224
    char __iomem *screen_base;  /* Virtual address */
224
    char __iomem *screen_base;  /* Virtual address */
225
    unsigned long screen_size;  /* Amount of ioremapped VRAM or 0 */
225
    unsigned long screen_size;  /* Amount of ioremapped VRAM or 0 */
226
    void *pseudo_palette;       /* Fake palette of 16 colors */
226
    void *pseudo_palette;       /* Fake palette of 16 colors */
227
#define FBINFO_STATE_RUNNING    0
227
#define FBINFO_STATE_RUNNING    0
228
#define FBINFO_STATE_SUSPENDED  1
228
#define FBINFO_STATE_SUSPENDED  1
229
    u32 state;          /* Hardware state i.e suspend */
229
    u32 state;          /* Hardware state i.e suspend */
230
    void *fbcon_par;                /* fbcon use-only private area */
230
    void *fbcon_par;                /* fbcon use-only private area */
231
    /* From here on everything is device dependent */
231
    /* From here on everything is device dependent */
232
    void *par;
232
    void *par;
233
    /* we need the PCI or similiar aperture base/size not
233
    /* we need the PCI or similiar aperture base/size not
234
       smem_start/size as smem_start may just be an object
234
       smem_start/size as smem_start may just be an object
235
       allocated inside the aperture so may not actually overlap */
235
       allocated inside the aperture so may not actually overlap */
236
    resource_size_t aperture_base;
236
    resource_size_t aperture_base;
237
    resource_size_t aperture_size;
237
    resource_size_t aperture_size;
238
};
238
};
239
 
239
 
240
 
240
 
241
 
241
 
242
struct radeon_fb_device {
242
struct radeon_fb_device {
243
	struct radeon_device		*rdev;
243
	struct radeon_device		*rdev;
244
	struct drm_display_mode		*mode;
244
	struct drm_display_mode		*mode;
245
	struct radeon_framebuffer	*rfb;
245
	struct radeon_framebuffer	*rfb;
246
    int                         crtc_count;
246
    int                         crtc_count;
247
	/* crtc currently bound to this */
247
	/* crtc currently bound to this */
248
	uint32_t			crtc_ids[2];
248
	uint32_t			crtc_ids[2];
249
};
249
};
250
 
250
 
251
int radeon_gem_fb_object_create(struct radeon_device *rdev, int size,
251
int radeon_gem_fb_object_create(struct radeon_device *rdev, int size,
252
                 int alignment, int initial_domain,
252
                 int alignment, int initial_domain,
253
                 bool discardable, bool kernel,
253
                 bool discardable, bool kernel,
254
                 bool interruptible,
254
                 bool interruptible,
255
                 struct drm_gem_object **obj);
255
                 struct drm_gem_object **obj);
256
 
256
 
257
struct fb_info *framebuffer_alloc(size_t size);
257
struct fb_info *framebuffer_alloc(size_t size);
258
 
258
 
259
#if 0
259
#if 0
260
static int radeonfb_setcolreg(unsigned regno,
260
static int radeonfb_setcolreg(unsigned regno,
261
			      unsigned red,
261
			      unsigned red,
262
			      unsigned green,
262
			      unsigned green,
263
			      unsigned blue,
263
			      unsigned blue,
264
			      unsigned transp,
264
			      unsigned transp,
265
			      struct fb_info *info)
265
			      struct fb_info *info)
266
{
266
{
267
	struct radeon_fb_device *rfbdev = info->par;
267
	struct radeon_fb_device *rfbdev = info->par;
268
	struct drm_device *dev = rfbdev->rdev->ddev;
268
	struct drm_device *dev = rfbdev->rdev->ddev;
269
	struct drm_crtc *crtc;
269
	struct drm_crtc *crtc;
270
	int i;
270
	int i;
271
 
271
 
272
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
272
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
273
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
273
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
274
		struct drm_mode_set *modeset = &radeon_crtc->mode_set;
274
		struct drm_mode_set *modeset = &radeon_crtc->mode_set;
275
		struct drm_framebuffer *fb = modeset->fb;
275
		struct drm_framebuffer *fb = modeset->fb;
276
 
276
 
277
		for (i = 0; i < rfbdev->crtc_count; i++) {
277
		for (i = 0; i < rfbdev->crtc_count; i++) {
278
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
278
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
279
				break;
279
				break;
280
			}
280
			}
281
		}
281
		}
282
		if (i == rfbdev->crtc_count) {
282
		if (i == rfbdev->crtc_count) {
283
			continue;
283
			continue;
284
		}
284
		}
285
		if (regno > 255) {
285
		if (regno > 255) {
286
			return 1;
286
			return 1;
287
		}
287
		}
288
		if (fb->depth == 8) {
288
		if (fb->depth == 8) {
289
			radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno);
289
			radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno);
290
			return 0;
290
			return 0;
291
		}
291
		}
292
 
292
 
293
		if (regno < 16) {
293
		if (regno < 16) {
294
			switch (fb->depth) {
294
			switch (fb->depth) {
295
			case 15:
295
			case 15:
296
				fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
296
				fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
297
					((green & 0xf800) >>  6) |
297
					((green & 0xf800) >>  6) |
298
					((blue & 0xf800) >> 11);
298
					((blue & 0xf800) >> 11);
299
				break;
299
				break;
300
			case 16:
300
			case 16:
301
				fb->pseudo_palette[regno] = (red & 0xf800) |
301
				fb->pseudo_palette[regno] = (red & 0xf800) |
302
					((green & 0xfc00) >>  5) |
302
					((green & 0xfc00) >>  5) |
303
					((blue  & 0xf800) >> 11);
303
					((blue  & 0xf800) >> 11);
304
				break;
304
				break;
305
			case 24:
305
			case 24:
306
			case 32:
306
			case 32:
307
				fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
307
				fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
308
					(green & 0xff00) |
308
					(green & 0xff00) |
309
					((blue  & 0xff00) >> 8);
309
					((blue  & 0xff00) >> 8);
310
				break;
310
				break;
311
			}
311
			}
312
		}
312
		}
313
	}
313
	}
314
	return 0;
314
	return 0;
315
}
315
}
316
 
316
 
317
static int radeonfb_check_var(struct fb_var_screeninfo *var,
317
static int radeonfb_check_var(struct fb_var_screeninfo *var,
318
			      struct fb_info *info)
318
			      struct fb_info *info)
319
{
319
{
320
	struct radeon_fb_device *rfbdev = info->par;
320
	struct radeon_fb_device *rfbdev = info->par;
321
	struct radeon_framebuffer *rfb = rfbdev->rfb;
321
	struct radeon_framebuffer *rfb = rfbdev->rfb;
322
	struct drm_framebuffer *fb = &rfb->base;
322
	struct drm_framebuffer *fb = &rfb->base;
323
	int depth;
323
	int depth;
324
 
324
 
325
	if (var->pixclock == -1 || !var->pixclock) {
325
	if (var->pixclock == -1 || !var->pixclock) {
326
		return -EINVAL;
326
		return -EINVAL;
327
	}
327
	}
328
	/* Need to resize the fb object !!! */
328
	/* Need to resize the fb object !!! */
329
	if (var->xres > fb->width || var->yres > fb->height) {
329
	if (var->xres > fb->width || var->yres > fb->height) {
330
		DRM_ERROR("Requested width/height is greater than current fb "
330
		DRM_ERROR("Requested width/height is greater than current fb "
331
			   "object %dx%d > %dx%d\n", var->xres, var->yres,
331
			   "object %dx%d > %dx%d\n", var->xres, var->yres,
332
			   fb->width, fb->height);
332
			   fb->width, fb->height);
333
		DRM_ERROR("Need resizing code.\n");
333
		DRM_ERROR("Need resizing code.\n");
334
		return -EINVAL;
334
		return -EINVAL;
335
	}
335
	}
336
 
336
 
337
	switch (var->bits_per_pixel) {
337
	switch (var->bits_per_pixel) {
338
	case 16:
338
	case 16:
339
		depth = (var->green.length == 6) ? 16 : 15;
339
		depth = (var->green.length == 6) ? 16 : 15;
340
		break;
340
		break;
341
	case 32:
341
	case 32:
342
		depth = (var->transp.length > 0) ? 32 : 24;
342
		depth = (var->transp.length > 0) ? 32 : 24;
343
		break;
343
		break;
344
	default:
344
	default:
345
		depth = var->bits_per_pixel;
345
		depth = var->bits_per_pixel;
346
		break;
346
		break;
347
	}
347
	}
348
 
348
 
349
	switch (depth) {
349
	switch (depth) {
350
	case 8:
350
	case 8:
351
		var->red.offset = 0;
351
		var->red.offset = 0;
352
		var->green.offset = 0;
352
		var->green.offset = 0;
353
		var->blue.offset = 0;
353
		var->blue.offset = 0;
354
		var->red.length = 8;
354
		var->red.length = 8;
355
		var->green.length = 8;
355
		var->green.length = 8;
356
		var->blue.length = 8;
356
		var->blue.length = 8;
357
		var->transp.length = 0;
357
		var->transp.length = 0;
358
		var->transp.offset = 0;
358
		var->transp.offset = 0;
359
		break;
359
		break;
360
	case 15:
360
	case 15:
361
		var->red.offset = 10;
361
		var->red.offset = 10;
362
		var->green.offset = 5;
362
		var->green.offset = 5;
363
		var->blue.offset = 0;
363
		var->blue.offset = 0;
364
		var->red.length = 5;
364
		var->red.length = 5;
365
		var->green.length = 5;
365
		var->green.length = 5;
366
		var->blue.length = 5;
366
		var->blue.length = 5;
367
		var->transp.length = 1;
367
		var->transp.length = 1;
368
		var->transp.offset = 15;
368
		var->transp.offset = 15;
369
		break;
369
		break;
370
	case 16:
370
	case 16:
371
		var->red.offset = 11;
371
		var->red.offset = 11;
372
		var->green.offset = 5;
372
		var->green.offset = 5;
373
		var->blue.offset = 0;
373
		var->blue.offset = 0;
374
		var->red.length = 5;
374
		var->red.length = 5;
375
		var->green.length = 6;
375
		var->green.length = 6;
376
		var->blue.length = 5;
376
		var->blue.length = 5;
377
		var->transp.length = 0;
377
		var->transp.length = 0;
378
		var->transp.offset = 0;
378
		var->transp.offset = 0;
379
		break;
379
		break;
380
	case 24:
380
	case 24:
381
		var->red.offset = 16;
381
		var->red.offset = 16;
382
		var->green.offset = 8;
382
		var->green.offset = 8;
383
		var->blue.offset = 0;
383
		var->blue.offset = 0;
384
		var->red.length = 8;
384
		var->red.length = 8;
385
		var->green.length = 8;
385
		var->green.length = 8;
386
		var->blue.length = 8;
386
		var->blue.length = 8;
387
		var->transp.length = 0;
387
		var->transp.length = 0;
388
		var->transp.offset = 0;
388
		var->transp.offset = 0;
389
		break;
389
		break;
390
	case 32:
390
	case 32:
391
		var->red.offset = 16;
391
		var->red.offset = 16;
392
		var->green.offset = 8;
392
		var->green.offset = 8;
393
		var->blue.offset = 0;
393
		var->blue.offset = 0;
394
		var->red.length = 8;
394
		var->red.length = 8;
395
		var->green.length = 8;
395
		var->green.length = 8;
396
		var->blue.length = 8;
396
		var->blue.length = 8;
397
		var->transp.length = 8;
397
		var->transp.length = 8;
398
		var->transp.offset = 24;
398
		var->transp.offset = 24;
399
		break;
399
		break;
400
	default:
400
	default:
401
		return -EINVAL;
401
		return -EINVAL;
402
	}
402
	}
403
	return 0;
403
	return 0;
404
}
404
}
405
 
405
 
406
#endif
406
#endif
407
 
407
 
408
 
408
 
409
/* this will let fbcon do the mode init */
409
/* this will let fbcon do the mode init */
410
static int radeonfb_set_par(struct fb_info *info)
410
static int radeonfb_set_par(struct fb_info *info)
411
{
411
{
412
	struct radeon_fb_device *rfbdev = info->par;
412
	struct radeon_fb_device *rfbdev = info->par;
413
	struct drm_device *dev = rfbdev->rdev->ddev;
413
	struct drm_device *dev = rfbdev->rdev->ddev;
414
	struct fb_var_screeninfo *var = &info->var;
414
	struct fb_var_screeninfo *var = &info->var;
415
	struct drm_crtc *crtc;
415
	struct drm_crtc *crtc;
416
	int ret;
416
	int ret;
417
	int i;
417
	int i;
418
 
418
 
419
	if (var->pixclock != -1) {
419
	if (var->pixclock != -1) {
420
		DRM_ERROR("PIXEL CLCOK SET\n");
420
		DRM_ERROR("PIXEL CLCOK SET\n");
421
		return -EINVAL;
421
		return -EINVAL;
422
	}
422
	}
423
 
423
 
424
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
424
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
425
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
425
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
426
 
426
 
427
		for (i = 0; i < rfbdev->crtc_count; i++) {
427
		for (i = 0; i < rfbdev->crtc_count; i++) {
428
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
428
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
429
				break;
429
				break;
430
			}
430
			}
431
		}
431
		}
432
		if (i == rfbdev->crtc_count) {
432
		if (i == rfbdev->crtc_count) {
433
			continue;
433
			continue;
434
		}
434
		}
435
		if (crtc->fb == radeon_crtc->mode_set.fb) {
435
		if (crtc->fb == radeon_crtc->mode_set.fb) {
436
//           mutex_lock(&dev->mode_config.mutex);
436
//           mutex_lock(&dev->mode_config.mutex);
437
			ret = crtc->funcs->set_config(&radeon_crtc->mode_set);
437
			ret = crtc->funcs->set_config(&radeon_crtc->mode_set);
438
//           mutex_unlock(&dev->mode_config.mutex);
438
//           mutex_unlock(&dev->mode_config.mutex);
439
			if (ret) {
439
			if (ret) {
440
				return ret;
440
				return ret;
441
			}
441
			}
442
		}
442
		}
443
	}
443
	}
444
	return 0;
444
	return 0;
445
}
445
}
446
 
446
 
447
#if 0
447
#if 0
448
 
448
 
449
static int radeonfb_pan_display(struct fb_var_screeninfo *var,
449
static int radeonfb_pan_display(struct fb_var_screeninfo *var,
450
				struct fb_info *info)
450
				struct fb_info *info)
451
{
451
{
452
	struct radeon_fb_device *rfbdev = info->par;
452
	struct radeon_fb_device *rfbdev = info->par;
453
	struct drm_device *dev = rfbdev->rdev->ddev;
453
	struct drm_device *dev = rfbdev->rdev->ddev;
454
	struct drm_mode_set *modeset;
454
	struct drm_mode_set *modeset;
455
	struct drm_crtc *crtc;
455
	struct drm_crtc *crtc;
456
	struct radeon_crtc *radeon_crtc;
456
	struct radeon_crtc *radeon_crtc;
457
	int ret = 0;
457
	int ret = 0;
458
	int i;
458
	int i;
459
 
459
 
460
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
460
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
461
		for (i = 0; i < rfbdev->crtc_count; i++) {
461
		for (i = 0; i < rfbdev->crtc_count; i++) {
462
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
462
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
463
				break;
463
				break;
464
			}
464
			}
465
		}
465
		}
466
 
466
 
467
		if (i == rfbdev->crtc_count) {
467
		if (i == rfbdev->crtc_count) {
468
			continue;
468
			continue;
469
		}
469
		}
470
 
470
 
471
		radeon_crtc = to_radeon_crtc(crtc);
471
		radeon_crtc = to_radeon_crtc(crtc);
472
		modeset = &radeon_crtc->mode_set;
472
		modeset = &radeon_crtc->mode_set;
473
 
473
 
474
		modeset->x = var->xoffset;
474
		modeset->x = var->xoffset;
475
		modeset->y = var->yoffset;
475
		modeset->y = var->yoffset;
476
 
476
 
477
		if (modeset->num_connectors) {
477
		if (modeset->num_connectors) {
478
			mutex_lock(&dev->mode_config.mutex);
478
			mutex_lock(&dev->mode_config.mutex);
479
			ret = crtc->funcs->set_config(modeset);
479
			ret = crtc->funcs->set_config(modeset);
480
			mutex_unlock(&dev->mode_config.mutex);
480
			mutex_unlock(&dev->mode_config.mutex);
481
			if (!ret) {
481
			if (!ret) {
482
				info->var.xoffset = var->xoffset;
482
				info->var.xoffset = var->xoffset;
483
				info->var.yoffset = var->yoffset;
483
				info->var.yoffset = var->yoffset;
484
			}
484
			}
485
		}
485
		}
486
	}
486
	}
487
	return ret;
487
	return ret;
488
}
488
}
489
 
489
 
490
static void radeonfb_on(struct fb_info *info)
490
static void radeonfb_on(struct fb_info *info)
491
{
491
{
492
	struct radeon_fb_device *rfbdev = info->par;
492
	struct radeon_fb_device *rfbdev = info->par;
493
	struct drm_device *dev = rfbdev->rdev->ddev;
493
	struct drm_device *dev = rfbdev->rdev->ddev;
494
	struct drm_crtc *crtc;
494
	struct drm_crtc *crtc;
495
	struct drm_encoder *encoder;
495
	struct drm_encoder *encoder;
496
	int i;
496
	int i;
497
 
497
 
498
	/*
498
	/*
499
	 * For each CRTC in this fb, find all associated encoders
499
	 * For each CRTC in this fb, find all associated encoders
500
	 * and turn them off, then turn off the CRTC.
500
	 * and turn them off, then turn off the CRTC.
501
	 */
501
	 */
502
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
502
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
503
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
503
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
504
 
504
 
505
		for (i = 0; i < rfbdev->crtc_count; i++) {
505
		for (i = 0; i < rfbdev->crtc_count; i++) {
506
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
506
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
507
				break;
507
				break;
508
			}
508
			}
509
		}
509
		}
510
 
510
 
511
		mutex_lock(&dev->mode_config.mutex);
511
		mutex_lock(&dev->mode_config.mutex);
512
		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
512
		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
513
		mutex_unlock(&dev->mode_config.mutex);
513
		mutex_unlock(&dev->mode_config.mutex);
514
 
514
 
515
		/* Found a CRTC on this fb, now find encoders */
515
		/* Found a CRTC on this fb, now find encoders */
516
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
516
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
517
			if (encoder->crtc == crtc) {
517
			if (encoder->crtc == crtc) {
518
				struct drm_encoder_helper_funcs *encoder_funcs;
518
				struct drm_encoder_helper_funcs *encoder_funcs;
519
 
519
 
520
				encoder_funcs = encoder->helper_private;
520
				encoder_funcs = encoder->helper_private;
521
				mutex_lock(&dev->mode_config.mutex);
521
				mutex_lock(&dev->mode_config.mutex);
522
				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
522
				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
523
				mutex_unlock(&dev->mode_config.mutex);
523
				mutex_unlock(&dev->mode_config.mutex);
524
			}
524
			}
525
		}
525
		}
526
	}
526
	}
527
}
527
}
528
 
528
 
529
static void radeonfb_off(struct fb_info *info, int dpms_mode)
529
static void radeonfb_off(struct fb_info *info, int dpms_mode)
530
{
530
{
531
	struct radeon_fb_device *rfbdev = info->par;
531
	struct radeon_fb_device *rfbdev = info->par;
532
	struct drm_device *dev = rfbdev->rdev->ddev;
532
	struct drm_device *dev = rfbdev->rdev->ddev;
533
	struct drm_crtc *crtc;
533
	struct drm_crtc *crtc;
534
	struct drm_encoder *encoder;
534
	struct drm_encoder *encoder;
535
	int i;
535
	int i;
536
 
536
 
537
	/*
537
	/*
538
	 * For each CRTC in this fb, find all associated encoders
538
	 * For each CRTC in this fb, find all associated encoders
539
	 * and turn them off, then turn off the CRTC.
539
	 * and turn them off, then turn off the CRTC.
540
	 */
540
	 */
541
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
541
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
542
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
542
		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
543
 
543
 
544
		for (i = 0; i < rfbdev->crtc_count; i++) {
544
		for (i = 0; i < rfbdev->crtc_count; i++) {
545
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
545
			if (crtc->base.id == rfbdev->crtc_ids[i]) {
546
				break;
546
				break;
547
			}
547
			}
548
		}
548
		}
549
 
549
 
550
		/* Found a CRTC on this fb, now find encoders */
550
		/* Found a CRTC on this fb, now find encoders */
551
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
551
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
552
			if (encoder->crtc == crtc) {
552
			if (encoder->crtc == crtc) {
553
				struct drm_encoder_helper_funcs *encoder_funcs;
553
				struct drm_encoder_helper_funcs *encoder_funcs;
554
 
554
 
555
				encoder_funcs = encoder->helper_private;
555
				encoder_funcs = encoder->helper_private;
556
				mutex_lock(&dev->mode_config.mutex);
556
				mutex_lock(&dev->mode_config.mutex);
557
				encoder_funcs->dpms(encoder, dpms_mode);
557
				encoder_funcs->dpms(encoder, dpms_mode);
558
				mutex_unlock(&dev->mode_config.mutex);
558
				mutex_unlock(&dev->mode_config.mutex);
559
			}
559
			}
560
		}
560
		}
561
		if (dpms_mode == DRM_MODE_DPMS_OFF) {
561
		if (dpms_mode == DRM_MODE_DPMS_OFF) {
562
			mutex_lock(&dev->mode_config.mutex);
562
			mutex_lock(&dev->mode_config.mutex);
563
			crtc_funcs->dpms(crtc, dpms_mode);
563
			crtc_funcs->dpms(crtc, dpms_mode);
564
			mutex_unlock(&dev->mode_config.mutex);
564
			mutex_unlock(&dev->mode_config.mutex);
565
		}
565
		}
566
	}
566
	}
567
}
567
}
568
 
568
 
569
int radeonfb_blank(int blank, struct fb_info *info)
569
int radeonfb_blank(int blank, struct fb_info *info)
570
{
570
{
571
	switch (blank) {
571
	switch (blank) {
572
	case FB_BLANK_UNBLANK:
572
	case FB_BLANK_UNBLANK:
573
		radeonfb_on(info);
573
		radeonfb_on(info);
574
		break;
574
		break;
575
	case FB_BLANK_NORMAL:
575
	case FB_BLANK_NORMAL:
576
		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
576
		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
577
		break;
577
		break;
578
	case FB_BLANK_HSYNC_SUSPEND:
578
	case FB_BLANK_HSYNC_SUSPEND:
579
		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
579
		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
580
		break;
580
		break;
581
	case FB_BLANK_VSYNC_SUSPEND:
581
	case FB_BLANK_VSYNC_SUSPEND:
582
		radeonfb_off(info, DRM_MODE_DPMS_SUSPEND);
582
		radeonfb_off(info, DRM_MODE_DPMS_SUSPEND);
583
		break;
583
		break;
584
	case FB_BLANK_POWERDOWN:
584
	case FB_BLANK_POWERDOWN:
585
		radeonfb_off(info, DRM_MODE_DPMS_OFF);
585
		radeonfb_off(info, DRM_MODE_DPMS_OFF);
586
		break;
586
		break;
587
	}
587
	}
588
	return 0;
588
	return 0;
589
}
589
}
590
 
590
 
591
static struct fb_ops radeonfb_ops = {
591
static struct fb_ops radeonfb_ops = {
592
	.owner = THIS_MODULE,
592
	.owner = THIS_MODULE,
593
	.fb_check_var = radeonfb_check_var,
593
	.fb_check_var = radeonfb_check_var,
594
	.fb_set_par = radeonfb_set_par,
594
	.fb_set_par = radeonfb_set_par,
595
	.fb_setcolreg = radeonfb_setcolreg,
595
	.fb_setcolreg = radeonfb_setcolreg,
596
	.fb_fillrect = cfb_fillrect,
596
	.fb_fillrect = cfb_fillrect,
597
	.fb_copyarea = cfb_copyarea,
597
	.fb_copyarea = cfb_copyarea,
598
	.fb_imageblit = cfb_imageblit,
598
	.fb_imageblit = cfb_imageblit,
599
	.fb_pan_display = radeonfb_pan_display,
599
	.fb_pan_display = radeonfb_pan_display,
600
	.fb_blank = radeonfb_blank,
600
	.fb_blank = radeonfb_blank,
601
};
601
};
602
 
602
 
603
/**
603
/**
604
 * Curretly it is assumed that the old framebuffer is reused.
604
 * Curretly it is assumed that the old framebuffer is reused.
605
 *
605
 *
606
 * LOCKING
606
 * LOCKING
607
 * caller should hold the mode config lock.
607
 * caller should hold the mode config lock.
608
 *
608
 *
609
 */
609
 */
610
int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
610
int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
611
{
611
{
612
	struct fb_info *info;
612
	struct fb_info *info;
613
	struct drm_framebuffer *fb;
613
	struct drm_framebuffer *fb;
614
	struct drm_display_mode *mode = crtc->desired_mode;
614
	struct drm_display_mode *mode = crtc->desired_mode;
615
 
615
 
616
	fb = crtc->fb;
616
	fb = crtc->fb;
617
	if (fb == NULL) {
617
	if (fb == NULL) {
618
		return 1;
618
		return 1;
619
	}
619
	}
620
	info = fb->fbdev;
620
	info = fb->fbdev;
621
	if (info == NULL) {
621
	if (info == NULL) {
622
		return 1;
622
		return 1;
623
	}
623
	}
624
	if (mode == NULL) {
624
	if (mode == NULL) {
625
		return 1;
625
		return 1;
626
	}
626
	}
627
	info->var.xres = mode->hdisplay;
627
	info->var.xres = mode->hdisplay;
628
	info->var.right_margin = mode->hsync_start - mode->hdisplay;
628
	info->var.right_margin = mode->hsync_start - mode->hdisplay;
629
	info->var.hsync_len = mode->hsync_end - mode->hsync_start;
629
	info->var.hsync_len = mode->hsync_end - mode->hsync_start;
630
	info->var.left_margin = mode->htotal - mode->hsync_end;
630
	info->var.left_margin = mode->htotal - mode->hsync_end;
631
	info->var.yres = mode->vdisplay;
631
	info->var.yres = mode->vdisplay;
632
	info->var.lower_margin = mode->vsync_start - mode->vdisplay;
632
	info->var.lower_margin = mode->vsync_start - mode->vdisplay;
633
	info->var.vsync_len = mode->vsync_end - mode->vsync_start;
633
	info->var.vsync_len = mode->vsync_end - mode->vsync_start;
634
	info->var.upper_margin = mode->vtotal - mode->vsync_end;
634
	info->var.upper_margin = mode->vtotal - mode->vsync_end;
635
	info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
635
	info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
636
	/* avoid overflow */
636
	/* avoid overflow */
637
	info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
637
	info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
638
 
638
 
639
	return 0;
639
	return 0;
640
}
640
}
641
EXPORT_SYMBOL(radeonfb_resize);
641
EXPORT_SYMBOL(radeonfb_resize);
642
 
642
 
643
static struct drm_mode_set panic_mode;
643
static struct drm_mode_set panic_mode;
644
 
644
 
645
int radeonfb_panic(struct notifier_block *n, unsigned long ununsed,
645
int radeonfb_panic(struct notifier_block *n, unsigned long ununsed,
646
		  void *panic_str)
646
		  void *panic_str)
647
{
647
{
648
	DRM_ERROR("panic occurred, switching back to text console\n");
648
	DRM_ERROR("panic occurred, switching back to text console\n");
649
	drm_crtc_helper_set_config(&panic_mode);
649
	drm_crtc_helper_set_config(&panic_mode);
650
	return 0;
650
	return 0;
651
}
651
}
652
EXPORT_SYMBOL(radeonfb_panic);
652
EXPORT_SYMBOL(radeonfb_panic);
653
 
653
 
654
static struct notifier_block paniced = {
654
static struct notifier_block paniced = {
655
	.notifier_call = radeonfb_panic,
655
	.notifier_call = radeonfb_panic,
656
};
656
};
657
#endif
657
#endif
658
 
658
 
659
static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp)
659
static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp)
660
{
660
{
661
	int aligned = width;
661
	int aligned = width;
662
	int align_large = (ASIC_IS_AVIVO(rdev));
662
	int align_large = (ASIC_IS_AVIVO(rdev));
663
	int pitch_mask = 0;
663
	int pitch_mask = 0;
664
 
664
 
665
	switch (bpp / 8) {
665
	switch (bpp / 8) {
666
	case 1:
666
	case 1:
667
		pitch_mask = align_large ? 255 : 127;
667
		pitch_mask = align_large ? 255 : 127;
668
		break;
668
		break;
669
	case 2:
669
	case 2:
670
		pitch_mask = align_large ? 127 : 31;
670
		pitch_mask = align_large ? 127 : 31;
671
		break;
671
		break;
672
	case 3:
672
	case 3:
673
	case 4:
673
	case 4:
674
		pitch_mask = align_large ? 63 : 15;
674
		pitch_mask = align_large ? 63 : 15;
675
		break;
675
		break;
676
	}
676
	}
677
 
677
 
678
	aligned += pitch_mask;
678
	aligned += pitch_mask;
679
	aligned &= ~pitch_mask;
679
	aligned &= ~pitch_mask;
680
	return aligned;
680
	return aligned;
681
}
681
}
682
 
682
 
683
int radeonfb_create(struct radeon_device *rdev,
683
int radeonfb_create(struct radeon_device *rdev,
684
		    uint32_t fb_width, uint32_t fb_height,
684
		    uint32_t fb_width, uint32_t fb_height,
685
		    uint32_t surface_width, uint32_t surface_height,
685
		    uint32_t surface_width, uint32_t surface_height,
686
		    struct radeon_framebuffer **rfb_p)
686
		    struct radeon_framebuffer **rfb_p)
687
{
687
{
688
	struct fb_info *info;
688
	struct fb_info *info;
689
	struct radeon_fb_device *rfbdev;
689
	struct radeon_fb_device *rfbdev;
690
	struct drm_framebuffer *fb = NULL;
690
	struct drm_framebuffer *fb = NULL;
691
	struct radeon_framebuffer *rfb;
691
	struct radeon_framebuffer *rfb;
692
	struct drm_mode_fb_cmd mode_cmd;
692
	struct drm_mode_fb_cmd mode_cmd;
693
	struct drm_gem_object *gobj = NULL;
693
	struct drm_gem_object *gobj = NULL;
694
	struct radeon_object *robj = NULL;
694
	struct radeon_object *robj = NULL;
695
//   struct device *device = &rdev->pdev->dev;
695
//   struct device *device = &rdev->pdev->dev;
696
	int size, aligned_size, ret;
696
	int size, aligned_size, ret;
697
	u64 fb_gpuaddr;
697
	u64 fb_gpuaddr;
698
	void *fbptr = NULL;
698
	void *fbptr = NULL;
699
	unsigned long tmp;
699
	unsigned long tmp;
700
 
700
 
701
    ENTRY();
701
    ENTRY();
702
 
702
 
703
	mode_cmd.width = surface_width;
703
	mode_cmd.width = surface_width;
704
	mode_cmd.height = surface_height;
704
	mode_cmd.height = surface_height;
705
	mode_cmd.bpp = 32;
705
	mode_cmd.bpp = 32;
706
	/* need to align pitch with crtc limits */
706
	/* need to align pitch with crtc limits */
707
	mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8);
707
	mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8);
708
    mode_cmd.depth = 32;
708
    mode_cmd.depth = 32;
709
 
709
 
710
	size = mode_cmd.pitch * mode_cmd.height;
710
	size = mode_cmd.pitch * mode_cmd.height;
711
	aligned_size = ALIGN(size, PAGE_SIZE);
711
	aligned_size = ALIGN(size, PAGE_SIZE);
712
 
712
 
713
    ret = radeon_gem_fb_object_create(rdev, aligned_size, 0,
713
    ret = radeon_gem_fb_object_create(rdev, aligned_size, 0,
714
			RADEON_GEM_DOMAIN_VRAM,
714
			RADEON_GEM_DOMAIN_VRAM,
715
            false, 0,
715
            false, 0,
716
			false, &gobj);
716
			false, &gobj);
717
 
717
 
718
 
718
 
719
	if (ret) {
719
	if (ret) {
720
		printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
720
		printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n",
721
		       surface_width, surface_height);
721
		       surface_width, surface_height);
722
		ret = -ENOMEM;
722
		ret = -ENOMEM;
723
		goto out;
723
		goto out;
724
	}
724
	}
725
	robj = gobj->driver_private;
725
	robj = gobj->driver_private;
726
 
726
 
727
//   mutex_lock(&rdev->ddev->struct_mutex);
727
//   mutex_lock(&rdev->ddev->struct_mutex);
728
	fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
728
	fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
729
	if (fb == NULL) {
729
	if (fb == NULL) {
730
		DRM_ERROR("failed to allocate fb.\n");
730
		DRM_ERROR("failed to allocate fb.\n");
731
		ret = -ENOMEM;
731
		ret = -ENOMEM;
732
		goto out_unref;
732
		goto out_unref;
733
	}
733
	}
734
	ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
734
	ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr);
735
	if (ret) {
735
	if (ret) {
736
		printk(KERN_ERR "failed to pin framebuffer\n");
736
		printk(KERN_ERR "failed to pin framebuffer\n");
737
		ret = -ENOMEM;
737
		ret = -ENOMEM;
738
		goto out_unref;
738
		goto out_unref;
739
	}
739
	}
740
 
740
 
741
	list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list);
741
	list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list);
742
 
742
 
743
	rfb = to_radeon_framebuffer(fb);
743
	rfb = to_radeon_framebuffer(fb);
744
	*rfb_p = rfb;
744
	*rfb_p = rfb;
745
	rdev->fbdev_rfb = rfb;
745
	rdev->fbdev_rfb = rfb;
746
	rdev->fbdev_robj = robj;
746
	rdev->fbdev_robj = robj;
747
 
747
 
748
    info = framebuffer_alloc(sizeof(struct radeon_fb_device));
748
    info = framebuffer_alloc(sizeof(struct radeon_fb_device));
749
	if (info == NULL) {
749
	if (info == NULL) {
750
		ret = -ENOMEM;
750
		ret = -ENOMEM;
751
		goto out_unref;
751
		goto out_unref;
752
	}
752
	}
753
	rfbdev = info->par;
753
	rfbdev = info->par;
754
 
754
 
755
//   ret = radeon_object_kmap(robj, &fbptr);
755
//   ret = radeon_object_kmap(robj, &fbptr);
756
//   if (ret) {
756
//   if (ret) {
757
//       goto out_unref;
757
//       goto out_unref;
758
//   }
758
//   }
759
 
759
 
760
    fbptr = (void*)0xFE000000; // LFB_BASE
760
    fbptr = (void*)0xFE000000; // LFB_BASE
761
 
761
 
762
 
762
 
763
	strcpy(info->fix.id, "radeondrmfb");
763
	strcpy(info->fix.id, "radeondrmfb");
764
	info->fix.type = FB_TYPE_PACKED_PIXELS;
764
	info->fix.type = FB_TYPE_PACKED_PIXELS;
765
	info->fix.visual = FB_VISUAL_TRUECOLOR;
765
	info->fix.visual = FB_VISUAL_TRUECOLOR;
766
	info->fix.type_aux = 0;
766
	info->fix.type_aux = 0;
767
	info->fix.xpanstep = 1; /* doing it in hw */
767
	info->fix.xpanstep = 1; /* doing it in hw */
768
	info->fix.ypanstep = 1; /* doing it in hw */
768
	info->fix.ypanstep = 1; /* doing it in hw */
769
	info->fix.ywrapstep = 0;
769
	info->fix.ywrapstep = 0;
770
//   info->fix.accel = FB_ACCEL_NONE;
770
//   info->fix.accel = FB_ACCEL_NONE;
771
	info->fix.type_aux = 0;
771
	info->fix.type_aux = 0;
772
//   info->flags = FBINFO_DEFAULT;
772
//   info->flags = FBINFO_DEFAULT;
773
//   info->fbops = &radeonfb_ops;
773
//   info->fbops = &radeonfb_ops;
774
	info->fix.line_length = fb->pitch;
774
	info->fix.line_length = fb->pitch;
775
	tmp = fb_gpuaddr - rdev->mc.vram_location;
775
	tmp = fb_gpuaddr - rdev->mc.vram_location;
776
	info->fix.smem_start = rdev->mc.aper_base + tmp;
776
	info->fix.smem_start = rdev->mc.aper_base + tmp;
777
	info->fix.smem_len = size;
777
	info->fix.smem_len = size;
778
	info->screen_base = fbptr;
778
	info->screen_base = fbptr;
779
	info->screen_size = size;
779
	info->screen_size = size;
780
	info->pseudo_palette = fb->pseudo_palette;
780
	info->pseudo_palette = fb->pseudo_palette;
781
	info->var.xres_virtual = fb->width;
781
	info->var.xres_virtual = fb->width;
782
	info->var.yres_virtual = fb->height;
782
	info->var.yres_virtual = fb->height;
783
	info->var.bits_per_pixel = fb->bits_per_pixel;
783
	info->var.bits_per_pixel = fb->bits_per_pixel;
784
	info->var.xoffset = 0;
784
	info->var.xoffset = 0;
785
	info->var.yoffset = 0;
785
	info->var.yoffset = 0;
786
//   info->var.activate = FB_ACTIVATE_NOW;
786
//   info->var.activate = FB_ACTIVATE_NOW;
787
	info->var.height = -1;
787
	info->var.height = -1;
788
	info->var.width = -1;
788
	info->var.width = -1;
789
	info->var.xres = fb_width;
789
	info->var.xres = fb_width;
790
	info->var.yres = fb_height;
790
	info->var.yres = fb_height;
791
	info->fix.mmio_start = 0;
791
	info->fix.mmio_start = 0;
792
	info->fix.mmio_len = 0;
792
	info->fix.mmio_len = 0;
793
//   info->pixmap.size = 64*1024;
793
//   info->pixmap.size = 64*1024;
794
//   info->pixmap.buf_align = 8;
794
//   info->pixmap.buf_align = 8;
795
//   info->pixmap.access_align = 32;
795
//   info->pixmap.access_align = 32;
796
//   info->pixmap.flags = FB_PIXMAP_SYSTEM;
796
//   info->pixmap.flags = FB_PIXMAP_SYSTEM;
797
//   info->pixmap.scan_align = 1;
797
//   info->pixmap.scan_align = 1;
798
	if (info->screen_base == NULL) {
798
	if (info->screen_base == NULL) {
799
		ret = -ENOSPC;
799
		ret = -ENOSPC;
800
		goto out_unref;
800
		goto out_unref;
801
	}
801
	}
802
	DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
802
	DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
803
	DRM_INFO("vram apper at 0x%lX\n",  (unsigned long)rdev->mc.aper_base);
803
	DRM_INFO("vram apper at 0x%lX\n",  (unsigned long)rdev->mc.aper_base);
804
	DRM_INFO("size %lu\n", (unsigned long)size);
804
	DRM_INFO("size %lu\n", (unsigned long)size);
805
	DRM_INFO("fb depth is %d\n", fb->depth);
805
	DRM_INFO("fb depth is %d\n", fb->depth);
806
	DRM_INFO("   pitch is %d\n", fb->pitch);
806
	DRM_INFO("   pitch is %d\n", fb->pitch);
807
 
807
 
808
	switch (fb->depth) {
808
	switch (fb->depth) {
809
	case 8:
809
	case 8:
810
		info->var.red.offset = 0;
810
		info->var.red.offset = 0;
811
		info->var.green.offset = 0;
811
		info->var.green.offset = 0;
812
		info->var.blue.offset = 0;
812
		info->var.blue.offset = 0;
813
		info->var.red.length = 8; /* 8bit DAC */
813
		info->var.red.length = 8; /* 8bit DAC */
814
		info->var.green.length = 8;
814
		info->var.green.length = 8;
815
		info->var.blue.length = 8;
815
		info->var.blue.length = 8;
816
		info->var.transp.offset = 0;
816
		info->var.transp.offset = 0;
817
		info->var.transp.length = 0;
817
		info->var.transp.length = 0;
818
		break;
818
		break;
819
	case 15:
819
	case 15:
820
		info->var.red.offset = 10;
820
		info->var.red.offset = 10;
821
		info->var.green.offset = 5;
821
		info->var.green.offset = 5;
822
		info->var.blue.offset = 0;
822
		info->var.blue.offset = 0;
823
		info->var.red.length = 5;
823
		info->var.red.length = 5;
824
		info->var.green.length = 5;
824
		info->var.green.length = 5;
825
		info->var.blue.length = 5;
825
		info->var.blue.length = 5;
826
		info->var.transp.offset = 15;
826
		info->var.transp.offset = 15;
827
		info->var.transp.length = 1;
827
		info->var.transp.length = 1;
828
		break;
828
		break;
829
	case 16:
829
	case 16:
830
		info->var.red.offset = 11;
830
		info->var.red.offset = 11;
831
		info->var.green.offset = 5;
831
		info->var.green.offset = 5;
832
		info->var.blue.offset = 0;
832
		info->var.blue.offset = 0;
833
		info->var.red.length = 5;
833
		info->var.red.length = 5;
834
		info->var.green.length = 6;
834
		info->var.green.length = 6;
835
		info->var.blue.length = 5;
835
		info->var.blue.length = 5;
836
		info->var.transp.offset = 0;
836
		info->var.transp.offset = 0;
837
		break;
837
		break;
838
	case 24:
838
	case 24:
839
		info->var.red.offset = 16;
839
		info->var.red.offset = 16;
840
		info->var.green.offset = 8;
840
		info->var.green.offset = 8;
841
		info->var.blue.offset = 0;
841
		info->var.blue.offset = 0;
842
		info->var.red.length = 8;
842
		info->var.red.length = 8;
843
		info->var.green.length = 8;
843
		info->var.green.length = 8;
844
		info->var.blue.length = 8;
844
		info->var.blue.length = 8;
845
		info->var.transp.offset = 0;
845
		info->var.transp.offset = 0;
846
		info->var.transp.length = 0;
846
		info->var.transp.length = 0;
847
		break;
847
		break;
848
	case 32:
848
	case 32:
849
		info->var.red.offset = 16;
849
		info->var.red.offset = 16;
850
		info->var.green.offset = 8;
850
		info->var.green.offset = 8;
851
		info->var.blue.offset = 0;
851
		info->var.blue.offset = 0;
852
		info->var.red.length = 8;
852
		info->var.red.length = 8;
853
		info->var.green.length = 8;
853
		info->var.green.length = 8;
854
		info->var.blue.length = 8;
854
		info->var.blue.length = 8;
855
		info->var.transp.offset = 24;
855
		info->var.transp.offset = 24;
856
		info->var.transp.length = 8;
856
		info->var.transp.length = 8;
857
		break;
857
		break;
858
	default:
858
	default:
859
		break;
859
		break;
860
	}
860
	}
861
 
861
 
862
    dbgprintf("fb = %x\n", fb);
862
    dbgprintf("fb = %x\n", fb);
863
 
863
 
864
	fb->fbdev = info;
864
	fb->fbdev = info;
865
	rfbdev->rfb = rfb;
865
	rfbdev->rfb = rfb;
866
	rfbdev->rdev = rdev;
866
	rfbdev->rdev = rdev;
867
 
867
 
868
//   mutex_unlock(&rdev->ddev->struct_mutex);
868
//   mutex_unlock(&rdev->ddev->struct_mutex);
869
	return 0;
869
	return 0;
870
 
870
 
871
out_unref:
871
out_unref:
872
	if (robj) {
872
	if (robj) {
873
//       radeon_object_kunmap(robj);
873
//       radeon_object_kunmap(robj);
874
	}
874
	}
875
	if (fb && ret) {
875
	if (fb && ret) {
876
		list_del(&fb->filp_head);
876
		list_del(&fb->filp_head);
877
 //      drm_gem_object_unreference(gobj);
877
 //      drm_gem_object_unreference(gobj);
878
//       drm_framebuffer_cleanup(fb);
878
//       drm_framebuffer_cleanup(fb);
879
		kfree(fb);
879
		kfree(fb);
880
	}
880
	}
881
//   drm_gem_object_unreference(gobj);
881
//   drm_gem_object_unreference(gobj);
882
//   mutex_unlock(&rdev->ddev->struct_mutex);
882
//   mutex_unlock(&rdev->ddev->struct_mutex);
883
out:
883
out:
884
	return ret;
884
	return ret;
885
}
885
}
886
 
886
 
887
static int radeonfb_single_fb_probe(struct radeon_device *rdev)
887
static int radeonfb_single_fb_probe(struct radeon_device *rdev)
888
{
888
{
889
	struct drm_crtc *crtc;
889
	struct drm_crtc *crtc;
890
	struct drm_connector *connector;
890
	struct drm_connector *connector;
891
	unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
891
	unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
892
	unsigned int surface_width = 0, surface_height = 0;
892
	unsigned int surface_width = 0, surface_height = 0;
893
	int new_fb = 0;
893
	int new_fb = 0;
894
	int crtc_count = 0;
894
	int crtc_count = 0;
895
	int ret, i, conn_count = 0;
895
	int ret, i, conn_count = 0;
896
	struct radeon_framebuffer *rfb;
896
	struct radeon_framebuffer *rfb;
897
	struct fb_info *info;
897
	struct fb_info *info;
898
	struct radeon_fb_device *rfbdev;
898
	struct radeon_fb_device *rfbdev;
899
	struct drm_mode_set *modeset = NULL;
899
	struct drm_mode_set *modeset = NULL;
900
 
900
 
901
    ENTRY();
901
    ENTRY();
902
 
902
 
903
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
903
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
904
	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
904
	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
905
		if (drm_helper_crtc_in_use(crtc)) {
905
		if (drm_helper_crtc_in_use(crtc)) {
906
			if (crtc->desired_mode) {
906
			if (crtc->desired_mode) {
907
				if (crtc->desired_mode->hdisplay < fb_width)
907
				if (crtc->desired_mode->hdisplay < fb_width)
908
					fb_width = crtc->desired_mode->hdisplay;
908
					fb_width = crtc->desired_mode->hdisplay;
909
 
909
 
910
				if (crtc->desired_mode->vdisplay < fb_height)
910
				if (crtc->desired_mode->vdisplay < fb_height)
911
					fb_height = crtc->desired_mode->vdisplay;
911
					fb_height = crtc->desired_mode->vdisplay;
912
 
912
 
913
				if (crtc->desired_mode->hdisplay > surface_width)
913
				if (crtc->desired_mode->hdisplay > surface_width)
914
					surface_width = crtc->desired_mode->hdisplay;
914
					surface_width = crtc->desired_mode->hdisplay;
915
 
915
 
916
				if (crtc->desired_mode->vdisplay > surface_height)
916
				if (crtc->desired_mode->vdisplay > surface_height)
917
					surface_height = crtc->desired_mode->vdisplay;
917
					surface_height = crtc->desired_mode->vdisplay;
918
			}
918
			}
919
			crtc_count++;
919
			crtc_count++;
920
		}
920
		}
921
	}
921
	}
922
 
922
 
923
	if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
923
	if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
924
		/* hmm everyone went away - assume VGA cable just fell out
924
		/* hmm everyone went away - assume VGA cable just fell out
925
		   and will come back later. */
925
		   and will come back later. */
926
 
926
 
927
        dbgprintf("crtc count %x width %x height %x\n",
927
        dbgprintf("crtc count %x width %x height %x\n",
928
                   crtc_count, fb_width, fb_height);
928
                   crtc_count, fb_width, fb_height);
929
		return 0;
929
		return 0;
930
	}
930
	}
931
 
931
 
932
	/* do we have an fb already? */
932
	/* do we have an fb already? */
933
	if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) {
933
	if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) {
934
		/* create an fb if we don't have one */
934
		/* create an fb if we don't have one */
935
		ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb);
935
		ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb);
936
		if (ret) {
936
		if (ret) {
937
			return -EINVAL;
937
			return -EINVAL;
938
		}
938
		}
939
		new_fb = 1;
939
		new_fb = 1;
940
	} else {
940
	} else {
941
		struct drm_framebuffer *fb;
941
		struct drm_framebuffer *fb;
942
		fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head);
942
		fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head);
943
		rfb = to_radeon_framebuffer(fb);
943
		rfb = to_radeon_framebuffer(fb);
944
 
944
 
945
		/* if someone hotplugs something bigger than we have already allocated, we are pwned.
945
		/* if someone hotplugs something bigger than we have already allocated, we are pwned.
946
		   As really we can't resize an fbdev that is in the wild currently due to fbdev
946
		   As really we can't resize an fbdev that is in the wild currently due to fbdev
947
		   not really being designed for the lower layers moving stuff around under it.
947
		   not really being designed for the lower layers moving stuff around under it.
948
		   - so in the grand style of things - punt. */
948
		   - so in the grand style of things - punt. */
949
		if ((fb->width < surface_width) || (fb->height < surface_height)) {
949
		if ((fb->width < surface_width) || (fb->height < surface_height)) {
950
			DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
950
			DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
951
			return -EINVAL;
951
			return -EINVAL;
952
		}
952
		}
953
	}
953
	}
954
 
954
 
955
	info = rfb->base.fbdev;
955
	info = rfb->base.fbdev;
956
	rdev->fbdev_info = info;
956
	rdev->fbdev_info = info;
957
	rfbdev = info->par;
957
	rfbdev = info->par;
958
 
958
 
959
	crtc_count = 0;
959
	crtc_count = 0;
960
	/* okay we need to setup new connector sets in the crtcs */
960
	/* okay we need to setup new connector sets in the crtcs */
961
	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
961
	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
962
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
962
		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
963
		modeset = &radeon_crtc->mode_set;
963
		modeset = &radeon_crtc->mode_set;
964
		modeset->fb = &rfb->base;
964
		modeset->fb = &rfb->base;
965
		conn_count = 0;
965
		conn_count = 0;
966
		list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) {
966
		list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) {
967
			if (connector->encoder)
967
			if (connector->encoder)
968
				if (connector->encoder->crtc == modeset->crtc) {
968
				if (connector->encoder->crtc == modeset->crtc) {
969
					modeset->connectors[conn_count] = connector;
969
					modeset->connectors[conn_count] = connector;
970
					conn_count++;
970
					conn_count++;
971
					if (conn_count > RADEONFB_CONN_LIMIT)
971
					if (conn_count > RADEONFB_CONN_LIMIT)
972
						BUG();
972
						BUG();
973
				}
973
				}
974
		}
974
		}
975
 
975
 
976
		for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++)
976
		for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++)
977
			modeset->connectors[i] = NULL;
977
			modeset->connectors[i] = NULL;
978
 
978
 
979
 
979
 
980
		rfbdev->crtc_ids[crtc_count++] = crtc->base.id;
980
		rfbdev->crtc_ids[crtc_count++] = crtc->base.id;
981
 
981
 
982
		modeset->num_connectors = conn_count;
982
		modeset->num_connectors = conn_count;
983
		if (modeset->crtc->desired_mode) {
983
		if (modeset->crtc->desired_mode) {
984
			if (modeset->mode) {
984
			if (modeset->mode) {
985
				drm_mode_destroy(rdev->ddev, modeset->mode);
985
				drm_mode_destroy(rdev->ddev, modeset->mode);
986
			}
986
			}
987
			modeset->mode = drm_mode_duplicate(rdev->ddev,
987
			modeset->mode = drm_mode_duplicate(rdev->ddev,
988
							   modeset->crtc->desired_mode);
988
							   modeset->crtc->desired_mode);
989
		}
989
		}
990
	}
990
	}
991
	rfbdev->crtc_count = crtc_count;
991
	rfbdev->crtc_count = crtc_count;
992
 
992
 
993
	if (new_fb) {
993
	if (new_fb) {
994
		info->var.pixclock = -1;
994
		info->var.pixclock = -1;
995
//       if (register_framebuffer(info) < 0)
995
//       if (register_framebuffer(info) < 0)
996
//           return -EINVAL;
996
//           return -EINVAL;
997
	} else {
997
	} else {
998
		radeonfb_set_par(info);
998
		radeonfb_set_par(info);
999
	}
999
	}
1000
	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
1000
	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
1001
	       info->fix.id);
1001
	       info->fix.id);
1002
 
1002
 
1003
	/* Switch back to kernel console on panic */
1003
	/* Switch back to kernel console on panic */
1004
//   panic_mode = *modeset;
1004
//   panic_mode = *modeset;
1005
//   atomic_notifier_chain_register(&panic_notifier_list, &paniced);
1005
//   atomic_notifier_chain_register(&panic_notifier_list, &paniced);
1006
//   printk(KERN_INFO "registered panic notifier\n");
1006
//   printk(KERN_INFO "registered panic notifier\n");
1007
    LEAVE();
1007
    LEAVE();
1008
 
1008
 
1009
	return 0;
1009
	return 0;
1010
}
1010
}
1011
 
1011
 
1012
int radeonfb_probe(struct drm_device *dev)
1012
int radeonfb_probe(struct drm_device *dev)
1013
{
1013
{
1014
	int ret;
1014
	int ret;
1015
 
1015
 
1016
	/* something has changed in the lower levels of hell - deal with it
1016
	/* something has changed in the lower levels of hell - deal with it
1017
	   here */
1017
	   here */
1018
 
1018
 
1019
	/* two modes : a) 1 fb to rule all crtcs.
1019
	/* two modes : a) 1 fb to rule all crtcs.
1020
	               b) one fb per crtc.
1020
	               b) one fb per crtc.
1021
	   two actions 1) new connected device
1021
	   two actions 1) new connected device
1022
	               2) device removed.
1022
	               2) device removed.
1023
	   case a/1 : if the fb surface isn't big enough - resize the surface fb.
1023
	   case a/1 : if the fb surface isn't big enough - resize the surface fb.
1024
	              if the fb size isn't big enough - resize fb into surface.
1024
	              if the fb size isn't big enough - resize fb into surface.
1025
		      if everything big enough configure the new crtc/etc.
1025
		      if everything big enough configure the new crtc/etc.
1026
	   case a/2 : undo the configuration
1026
	   case a/2 : undo the configuration
1027
	              possibly resize down the fb to fit the new configuration.
1027
	              possibly resize down the fb to fit the new configuration.
1028
           case b/1 : see if it is on a new crtc - setup a new fb and add it.
1028
           case b/1 : see if it is on a new crtc - setup a new fb and add it.
1029
	   case b/2 : teardown the new fb.
1029
	   case b/2 : teardown the new fb.
1030
	*/
1030
	*/
1031
	ret = radeonfb_single_fb_probe(dev->dev_private);
1031
	ret = radeonfb_single_fb_probe(dev->dev_private);
1032
	return ret;
1032
	return ret;
1033
}
1033
}
1034
EXPORT_SYMBOL(radeonfb_probe);
1034
EXPORT_SYMBOL(radeonfb_probe);
1035
 
1035
 
1036
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
1036
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
1037
{
1037
{
1038
	struct fb_info *info;
1038
	struct fb_info *info;
1039
	struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
1039
	struct radeon_framebuffer *rfb = to_radeon_framebuffer(fb);
1040
	struct radeon_object *robj;
1040
	struct radeon_object *robj;
1041
 
1041
 
1042
	if (!fb) {
1042
	if (!fb) {
1043
		return -EINVAL;
1043
		return -EINVAL;
1044
	}
1044
	}
1045
	info = fb->fbdev;
1045
	info = fb->fbdev;
1046
	if (info) {
1046
	if (info) {
1047
		robj = rfb->obj->driver_private;
1047
		robj = rfb->obj->driver_private;
1048
//       unregister_framebuffer(info);
1048
//       unregister_framebuffer(info);
1049
//       radeon_object_kunmap(robj);
1049
//       radeon_object_kunmap(robj);
1050
//       radeon_object_unpin(robj);
1050
//       radeon_object_unpin(robj);
1051
//       framebuffer_release(info);
1051
//       framebuffer_release(info);
1052
	}
1052
	}
1053
 
1053
 
1054
	printk(KERN_INFO "unregistered panic notifier\n");
1054
	printk(KERN_INFO "unregistered panic notifier\n");
1055
//   atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
1055
//   atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
1056
//   memset(&panic_mode, 0, sizeof(struct drm_mode_set));
1056
//   memset(&panic_mode, 0, sizeof(struct drm_mode_set));
1057
	return 0;
1057
	return 0;
1058
}
1058
}
1059
EXPORT_SYMBOL(radeonfb_remove);
1059
EXPORT_SYMBOL(radeonfb_remove);
1060
 
1060
 
1061
 
1061
 
1062
/**
1062
/**
1063
 * Allocate a GEM object of the specified size with shmfs backing store
1063
 * Allocate a GEM object of the specified size with shmfs backing store
1064
 */
1064
 */
1065
struct drm_gem_object *
1065
struct drm_gem_object *
1066
drm_gem_object_alloc(struct drm_device *dev, size_t size)
1066
drm_gem_object_alloc(struct drm_device *dev, size_t size)
1067
{
1067
{
1068
    struct drm_gem_object *obj;
1068
    struct drm_gem_object *obj;
1069
 
1069
 
1070
    BUG_ON((size & (PAGE_SIZE - 1)) != 0);
1070
    BUG_ON((size & (PAGE_SIZE - 1)) != 0);
1071
 
1071
 
1072
    obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1072
    obj = kzalloc(sizeof(*obj), GFP_KERNEL);
1073
 
1073
 
1074
    obj->dev = dev;
1074
    obj->dev = dev;
1075
//    obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
1075
//    obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
1076
//    if (IS_ERR(obj->filp)) {
1076
//    if (IS_ERR(obj->filp)) {
1077
//        kfree(obj);
1077
//        kfree(obj);
1078
//        return NULL;
1078
//        return NULL;
1079
//    }
1079
//    }
1080
 
1080
 
1081
//    kref_init(&obj->refcount);
1081
//    kref_init(&obj->refcount);
1082
//    kref_init(&obj->handlecount);
1082
//    kref_init(&obj->handlecount);
1083
    obj->size = size;
1083
    obj->size = size;
1084
 
1084
 
1085
//    if (dev->driver->gem_init_object != NULL &&
1085
//    if (dev->driver->gem_init_object != NULL &&
1086
//        dev->driver->gem_init_object(obj) != 0) {
1086
//        dev->driver->gem_init_object(obj) != 0) {
1087
//        fput(obj->filp);
1087
//        fput(obj->filp);
1088
//        kfree(obj);
1088
//        kfree(obj);
1089
//        return NULL;
1089
//        return NULL;
1090
//    }
1090
//    }
1091
//    atomic_inc(&dev->object_count);
1091
//    atomic_inc(&dev->object_count);
1092
//    atomic_add(obj->size, &dev->object_memory);
1092
//    atomic_add(obj->size, &dev->object_memory);
1093
    return obj;
1093
    return obj;
1094
}
1094
}
1095
 
1095
 
1096
 
1096
 
1097
int radeon_gem_fb_object_create(struct radeon_device *rdev, int size,
1097
int radeon_gem_fb_object_create(struct radeon_device *rdev, int size,
1098
                 int alignment, int initial_domain,
1098
                 int alignment, int initial_domain,
1099
                 bool discardable, bool kernel,
1099
                 bool discardable, bool kernel,
1100
                 bool interruptible,
1100
                 bool interruptible,
1101
                 struct drm_gem_object **obj)
1101
                 struct drm_gem_object **obj)
1102
{
1102
{
1103
    struct drm_gem_object *gobj;
1103
    struct drm_gem_object *gobj;
1104
    struct radeon_object *robj;
1104
    struct radeon_object *robj;
1105
 
1105
 
1106
    *obj = NULL;
1106
    *obj = NULL;
1107
    gobj = drm_gem_object_alloc(rdev->ddev, size);
1107
    gobj = drm_gem_object_alloc(rdev->ddev, size);
1108
    if (!gobj) {
1108
    if (!gobj) {
1109
        return -ENOMEM;
1109
        return -ENOMEM;
1110
    }
1110
    }
1111
    /* At least align on page size */
1111
    /* At least align on page size */
1112
    if (alignment < PAGE_SIZE) {
1112
    if (alignment < PAGE_SIZE) {
1113
        alignment = PAGE_SIZE;
1113
        alignment = PAGE_SIZE;
1114
    }
1114
    }
1115
 
1115
 
1116
    robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL);
1116
    robj = kzalloc(sizeof(struct radeon_object), GFP_KERNEL);
1117
    if (!robj) {
1117
    if (!robj) {
1118
        DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
1118
        DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
1119
              size, initial_domain, alignment);
1119
              size, initial_domain, alignment);
1120
//       mutex_lock(&rdev->ddev->struct_mutex);
1120
//       mutex_lock(&rdev->ddev->struct_mutex);
1121
//       drm_gem_object_unreference(gobj);
1121
//       drm_gem_object_unreference(gobj);
1122
//       mutex_unlock(&rdev->ddev->struct_mutex);
1122
//       mutex_unlock(&rdev->ddev->struct_mutex);
1123
        return -ENOMEM;;
1123
        return -ENOMEM;;
1124
    }
1124
    }
1125
    robj->rdev = rdev;
1125
    robj->rdev = rdev;
1126
    robj->gobj = gobj;
1126
    robj->gobj = gobj;
1127
    INIT_LIST_HEAD(&robj->list);
1127
    INIT_LIST_HEAD(&robj->list);
1128
 
1128
 
1129
    robj->flags = TTM_PL_FLAG_VRAM;
1129
    robj->flags = TTM_PL_FLAG_VRAM;
1130
 
1130
 
1131
    struct drm_mm_node *vm_node;
1131
    struct drm_mm_node *vm_node;
1132
 
1132
 
1133
    vm_node = kzalloc(sizeof(*vm_node),0);
1133
    vm_node = kzalloc(sizeof(*vm_node),0);
1134
 
1134
 
1135
    vm_node->free = 0;
1135
    vm_node->free = 0;
1136
    vm_node->size = 0x800000 >> 12;
1136
    vm_node->size = 0x800000 >> 12;
1137
    vm_node->start = 0;
1137
    vm_node->start = 0;
1138
    vm_node->mm = NULL;
1138
    vm_node->mm = NULL;
1139
 
1139
 
1140
    robj->mm_node = vm_node;
1140
    robj->mm_node = vm_node;
1141
 
1141
 
1142
    robj->vm_addr = ((uint32_t)robj->mm_node->start);
1142
    robj->vm_addr = ((uint32_t)robj->mm_node->start);
1143
 
1143
 
1144
    gobj->driver_private = robj;
1144
    gobj->driver_private = robj;
1145
    *obj = gobj;
1145
    *obj = gobj;
1146
    return 0;
1146
    return 0;
1147
}
1147
}
1148
 
1148
 
1149
 
1149
 
1150
struct fb_info *framebuffer_alloc(size_t size)
1150
struct fb_info *framebuffer_alloc(size_t size)
1151
{
1151
{
1152
#define BYTES_PER_LONG (BITS_PER_LONG/8)
1152
#define BYTES_PER_LONG (BITS_PER_LONG/8)
1153
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
1153
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
1154
        int fb_info_size = sizeof(struct fb_info);
1154
        int fb_info_size = sizeof(struct fb_info);
1155
        struct fb_info *info;
1155
        struct fb_info *info;
1156
        char *p;
1156
        char *p;
1157
 
1157
 
1158
        if (size)
1158
        if (size)
1159
                fb_info_size += PADDING;
1159
                fb_info_size += PADDING;
1160
 
1160
 
1161
        p = kzalloc(fb_info_size + size, GFP_KERNEL);
1161
        p = kzalloc(fb_info_size + size, GFP_KERNEL);
1162
 
1162
 
1163
        if (!p)
1163
        if (!p)
1164
                return NULL;
1164
                return NULL;
1165
 
1165
 
1166
        info = (struct fb_info *) p;
1166
        info = (struct fb_info *) p;
1167
 
1167
 
1168
        if (size)
1168
        if (size)
1169
                info->par = p + fb_info_size;
1169
                info->par = p + fb_info_size;
1170
 
1170
 
1171
        return info;
1171
        return info;
1172
#undef PADDING
1172
#undef PADDING
1173
#undef BYTES_PER_LONG
1173
#undef BYTES_PER_LONG
1174
}
1174
}
-
 
1175
 
-
 
1176
static char *manufacturer_name(unsigned char *x)
-
 
1177
{
-
 
1178
    static char name[4];
-
 
1179
 
-
 
1180
    name[0] = ((x[0] & 0x7C) >> 2) + '@';
-
 
1181
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
-
 
1182
    name[2] = (x[1] & 0x1F) + '@';
-
 
1183
    name[3] = 0;
-
 
1184
 
-
 
1185
    return name;
-
 
1186
}
-
 
1187
 
-
 
1188
 
-
 
1189
bool set_mode(struct drm_device *dev, int width, int height)
-
 
1190
{
-
 
1191
    struct drm_connector *connector;
-
 
1192
 
-
 
1193
    bool   ret;
-
 
1194
 
-
 
1195
    ENTRY();
-
 
1196
 
-
 
1197
    list_for_each_entry(connector, &dev->mode_config.connector_list, head)
-
 
1198
    {
-
 
1199
        struct drm_display_mode *mode;
-
 
1200
 
-
 
1201
        struct drm_encoder  *encoder;
-
 
1202
        struct drm_crtc     *crtc;
-
 
1203
 
-
 
1204
        if( connector->status != connector_status_connected)
-
 
1205
            continue;
-
 
1206
 
-
 
1207
        encoder = connector->encoder;
-
 
1208
        if( encoder == NULL)
-
 
1209
            continue;
-
 
1210
 
-
 
1211
        crtc = encoder->crtc;
-
 
1212
 
-
 
1213
        if(crtc == NULL)
-
 
1214
            continue;
-
 
1215
 
-
 
1216
        list_for_each_entry(mode, &connector->modes, head)
-
 
1217
        {
-
 
1218
            char *con_name, *enc_name;
-
 
1219
 
-
 
1220
            struct drm_framebuffer *fb;
-
 
1221
 
-
 
1222
            if (drm_mode_width(mode) == width &&
-
 
1223
                drm_mode_height(mode) == height)
-
 
1224
            {
-
 
1225
                char con_edid[128];
-
 
1226
 
-
 
1227
                fb = list_first_entry(&dev->mode_config.fb_kernel_list,
-
 
1228
                                      struct drm_framebuffer, filp_head);
-
 
1229
 
-
 
1230
                memcpy(con_edid, connector->edid_blob_ptr->data, 128);
-
 
1231
 
-
 
1232
                dbgprintf("Manufacturer: %s Model %x Serial Number %u\n",
-
 
1233
                manufacturer_name(con_edid + 0x08),
-
 
1234
                (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
-
 
1235
                (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
-
 
1236
                    + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
-
 
1237
 
-
 
1238
 
-
 
1239
                con_name = drm_get_connector_name(connector);
-
 
1240
                enc_name = drm_get_encoder_name(encoder);
-
 
1241
 
-
 
1242
                dbgprintf("set mode %d %d connector %s encoder %s\n",
-
 
1243
                           width, height, con_name, enc_name);
-
 
1244
 
-
 
1245
                fb->width = width;
-
 
1246
                fb->height = height;
-
 
1247
                fb->pitch = radeon_align_pitch(dev->dev_private, width, 32)
-
 
1248
                            * ((32 + 1) / 8);
-
 
1249
 
-
 
1250
                crtc->fb = fb;
-
 
1251
 
-
 
1252
                ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
-
 
1253
 
-
 
1254
                sysSetScreen(width,height);
-
 
1255
 
-
 
1256
                if (ret == true)
-
 
1257
                {
-
 
1258
                }
-
 
1259
                else
-
 
1260
                {
-
 
1261
                    DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
-
 
1262
                               width, height, crtc);
-
 
1263
                };
-
 
1264
 
-
 
1265
                return ret;
-
 
1266
            };
-
 
1267
        }
-
 
1268
    };
-
 
1269
 
-
 
1270
    return false;
-
 
1271
};
-
 
1272