2 * Frame buffer driver for the Carmine GPU.
4 * The driver configures the GPU as follows
5 * - FB0 is display 0 with unique memory area
6 * - FB1 is display 1 with unique memory area
7 * - both display use 32 bit colors
9 #include <linux/delay.h>
10 #include <linux/errno.h>
12 #include <linux/interrupt.h>
13 #include <linux/pci.h>
15 #include "carminefb.h"
16 #include "carminefb_regs.h"
18 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
19 #error "The endianness of the target host has not been defined."
23 * The initial video mode can be supplied via two different ways:
24 * - as a string that is passed to fb_find_mode() (module option fb_mode_str)
25 * - as an integer that picks the video mode from carmine_modedb[] (module
28 * If nothing is used than the initial video mode will be the
29 * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[].
31 #define CARMINEFB_DEFAULT_VIDEO_MODE 1
33 static unsigned int fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
34 module_param(fb_mode
, uint
, 444);
35 MODULE_PARM_DESC(fb_mode
, "Initial video mode as integer.");
37 static char *fb_mode_str
;
38 module_param(fb_mode_str
, charp
, 444);
39 MODULE_PARM_DESC(fb_mode_str
, "Initial video mode in characters.");
47 static int fb_displays
= CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
;
48 module_param(fb_displays
, int, 444);
49 MODULE_PARM_DESC(fb_displays
, "Bit mode, which displays are used");
53 void __iomem
*screen_mem
;
54 struct fb_info
*fb
[MAX_DISPLAY
];
57 struct carmine_resolution
{
70 void __iomem
*display_reg
;
71 void __iomem
*screen_base
;
75 struct carmine_resolution
*res
;
76 u32 pseudo_palette
[16];
79 static struct fb_fix_screeninfo carminefb_fix __devinitdata
= {
81 .type
= FB_TYPE_PACKED_PIXELS
,
82 .visual
= FB_VISUAL_TRUECOLOR
,
83 .accel
= FB_ACCEL_NONE
,
86 static const struct fb_videomode carmine_modedb
[] = {
98 static struct carmine_resolution car_modes
[] = {
125 static int carmine_find_mode(const struct fb_var_screeninfo
*var
)
129 for (i
= 0; i
< ARRAY_SIZE(car_modes
); i
++)
130 if (car_modes
[i
].hdp
== var
->xres
&&
131 car_modes
[i
].vdp
== var
->yres
)
136 static void c_set_disp_reg(const struct carmine_fb
*par
,
139 writel(val
, par
->display_reg
+ offset
);
142 static u32
c_get_disp_reg(const struct carmine_fb
*par
,
145 return readl(par
->display_reg
+ offset
);
148 static void c_set_hw_reg(const struct carmine_hw
*hw
,
151 writel(val
, hw
->v_regs
+ offset
);
154 static u32
c_get_hw_reg(const struct carmine_hw
*hw
,
157 return readl(hw
->v_regs
+ offset
);
160 static int carmine_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
161 unsigned blue
, unsigned transp
, struct fb_info
*info
)
171 ((__be32
*)info
->pseudo_palette
)[regno
] = cpu_to_be32(transp
<< 24 |
172 red
<< 0 | green
<< 8 | blue
<< 16);
176 static int carmine_check_var(struct fb_var_screeninfo
*var
,
177 struct fb_info
*info
)
181 ret
= carmine_find_mode(var
);
185 if (var
->grayscale
|| var
->rotate
|| var
->nonstd
)
188 var
->xres_virtual
= var
->xres
;
189 var
->yres_virtual
= var
->yres
;
191 var
->bits_per_pixel
= 32;
194 var
->transp
.offset
= 24;
196 var
->green
.offset
= 8;
197 var
->blue
.offset
= 16;
199 var
->transp
.offset
= 24;
200 var
->red
.offset
= 16;
201 var
->green
.offset
= 8;
202 var
->blue
.offset
= 0;
206 var
->green
.length
= 8;
207 var
->blue
.length
= 8;
208 var
->transp
.length
= 8;
210 var
->red
.msb_right
= 0;
211 var
->green
.msb_right
= 0;
212 var
->blue
.msb_right
= 0;
213 var
->transp
.msb_right
= 0;
217 static void carmine_init_display_param(struct carmine_fb
*par
)
223 u32 soffset
= par
->smem_offset
;
225 c_set_disp_reg(par
, CARMINE_DISP_REG_C_TRANS
, 0);
226 c_set_disp_reg(par
, CARMINE_DISP_REG_MLMR_TRANS
, 0);
227 c_set_disp_reg(par
, CARMINE_DISP_REG_CURSOR_MODE
,
228 CARMINE_CURSOR0_PRIORITY_MASK
|
229 CARMINE_CURSOR1_PRIORITY_MASK
|
230 CARMINE_CURSOR_CUTZ_MASK
);
232 /* Set default cursor position */
233 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR1_POS
, 0 << 16 | 0);
234 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR2_POS
, 0 << 16 | 0);
236 /* Set default display mode */
237 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_EXT_MODE
, CARMINE_WINDOW_MODE
|
238 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
239 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_EXT_MODE
,
240 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
241 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_EXT_MODE
, CARMINE_EXTEND_MODE
|
242 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
243 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_EXT_MODE
, CARMINE_EXTEND_MODE
|
244 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
245 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_EXT_MODE
, CARMINE_EXTEND_MODE
|
246 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
247 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_EXT_MODE
, CARMINE_EXTEND_MODE
|
248 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
249 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_EXT_MODE
, CARMINE_EXTEND_MODE
|
250 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
251 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_EXT_MODE
, CARMINE_EXTEND_MODE
|
252 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
254 /* Set default frame size to layer mode register */
255 width
= par
->res
->hdp
* 4 / CARMINE_DISP_WIDTH_UNIT
;
256 width
= width
<< CARMINE_DISP_WIDTH_SHIFT
;
258 height
= par
->res
->vdp
- 1;
259 param
= width
| height
;
261 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_MODE_W_H
, param
);
262 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIDTH
, width
);
263 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_MODE_W_H
, param
);
264 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_MODE_W_H
, param
);
265 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_MODE_W_H
, param
);
266 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_MODE_W_H
, param
);
267 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_MODE_W_H
, param
);
268 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_MODE_W_H
, param
);
270 /* Set default pos and size */
271 window_size
= (par
->res
->vdp
- 1) << CARMINE_DISP_WIN_H_SHIFT
;
272 window_size
|= par
->res
->hdp
;
274 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_POS
, 0);
275 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_SIZE
, window_size
);
276 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_POS
, 0);
277 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_SIZE
, window_size
);
278 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_POS
, 0);
279 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_SIZE
, window_size
);
280 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_POS
, 0);
281 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_SIZE
, window_size
);
282 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_POS
, 0);
283 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_SIZE
, window_size
);
284 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_POS
, 0);
285 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_SIZE
, window_size
);
286 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_POS
, 0);
287 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_SIZE
, window_size
);
288 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_POS
, 0);
289 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_SIZE
, window_size
);
291 /* Set default origin address */
292 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_ORG_ADR
, soffset
);
293 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_ORG_ADR
, soffset
);
294 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_ORG_ADR1
, soffset
);
295 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_ORG_ADR1
, soffset
);
296 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_ORG_ADR1
, soffset
);
297 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_ORG_ADR1
, soffset
);
298 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_ORG_ADR1
, soffset
);
299 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_ORG_ADR1
, soffset
);
301 /* Set default display address */
302 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_ADR
, soffset
);
303 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_ADR1
, soffset
);
304 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_ADR1
, soffset
);
305 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_ADR1
, soffset
);
306 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_ADR1
, soffset
);
307 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_ADR0
, soffset
);
308 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_ADR0
, soffset
);
310 /* Set default display position */
311 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_POS
, 0);
312 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_POS
, 0);
313 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_POS
, 0);
314 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_POS
, 0);
315 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_POS
, 0);
316 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_POS
, 0);
317 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_POS
, 0);
319 /* Set default blend mode */
320 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L0
, 0);
321 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L1
, 0);
322 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L2
, 0);
323 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L3
, 0);
324 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L4
, 0);
325 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L5
, 0);
326 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L6
, 0);
327 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L7
, 0);
329 /* default transparency mode */
330 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_TRANS
, 0);
331 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_TRANS
, 0);
332 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_TRANS
, 0);
333 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_TRANS
, 0);
334 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_TRANS
, 0);
335 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_TRANS
, 0);
336 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_TRANS
, 0);
337 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_TRANS
, 0);
339 /* Set default read skip parameter */
340 c_set_disp_reg(par
, CARMINE_DISP_REG_L0RM
, 0);
341 c_set_disp_reg(par
, CARMINE_DISP_REG_L2RM
, 0);
342 c_set_disp_reg(par
, CARMINE_DISP_REG_L3RM
, 0);
343 c_set_disp_reg(par
, CARMINE_DISP_REG_L4RM
, 0);
344 c_set_disp_reg(par
, CARMINE_DISP_REG_L5RM
, 0);
345 c_set_disp_reg(par
, CARMINE_DISP_REG_L6RM
, 0);
346 c_set_disp_reg(par
, CARMINE_DISP_REG_L7RM
, 0);
348 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PX
, 0);
349 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PX
, 0);
350 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PX
, 0);
351 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PX
, 0);
352 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PX
, 0);
353 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PX
, 0);
354 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PX
, 0);
356 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PY
, 0);
357 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PY
, 0);
358 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PY
, 0);
359 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PY
, 0);
360 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PY
, 0);
361 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PY
, 0);
362 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PY
, 0);
365 static void set_display_parameters(struct carmine_fb
*par
)
368 u32 hdp
, vdp
, htp
, hsp
, hsw
, vtr
, vsp
, vsw
;
371 * display timing. Parameters are decreased by one because hardware
372 * spec is 0 to (n - 1)
374 hdp
= par
->res
->hdp
- 1;
375 vdp
= par
->res
->vdp
- 1;
376 htp
= par
->res
->htp
- 1;
377 hsp
= par
->res
->hsp
- 1;
378 hsw
= par
->res
->hsw
- 1;
379 vtr
= par
->res
->vtr
- 1;
380 vsp
= par
->res
->vsp
- 1;
381 vsw
= par
->res
->vsw
- 1;
383 c_set_disp_reg(par
, CARMINE_DISP_REG_H_TOTAL
,
384 htp
<< CARMINE_DISP_HTP_SHIFT
);
385 c_set_disp_reg(par
, CARMINE_DISP_REG_H_PERIOD
,
386 (hdp
<< CARMINE_DISP_HDB_SHIFT
) | hdp
);
387 c_set_disp_reg(par
, CARMINE_DISP_REG_V_H_W_H_POS
,
388 (vsw
<< CARMINE_DISP_VSW_SHIFT
) |
389 (hsw
<< CARMINE_DISP_HSW_SHIFT
) |
391 c_set_disp_reg(par
, CARMINE_DISP_REG_V_TOTAL
,
392 vtr
<< CARMINE_DISP_VTR_SHIFT
);
393 c_set_disp_reg(par
, CARMINE_DISP_REG_V_PERIOD_POS
,
394 (vdp
<< CARMINE_DISP_VDP_SHIFT
) | vsp
);
397 mode
= c_get_disp_reg(par
, CARMINE_DISP_REG_DCM1
);
398 mode
= (mode
& ~CARMINE_DISP_DCM_MASK
) |
399 (par
->res
->disp_mode
& CARMINE_DISP_DCM_MASK
);
400 /* enable video output and layer 0 */
401 mode
|= CARMINE_DEN
| CARMINE_L0E
;
402 c_set_disp_reg(par
, CARMINE_DISP_REG_DCM1
, mode
);
405 static int carmine_set_par(struct fb_info
*info
)
407 struct carmine_fb
*par
= info
->par
;
410 ret
= carmine_find_mode(&info
->var
);
415 if (par
->cur_mode
!= par
->new_mode
) {
417 par
->cur_mode
= par
->new_mode
;
418 par
->res
= &car_modes
[par
->new_mode
];
420 carmine_init_display_param(par
);
421 set_display_parameters(par
);
424 info
->fix
.line_length
= info
->var
.xres
* info
->var
.bits_per_pixel
/ 8;
428 static int init_hardware(struct carmine_hw
*hw
)
434 /* Initalize Carmine */
435 /* Sets internal clock */
436 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
,
437 CARMINE_DFLT_IP_CLOCK_ENABLE
);
439 /* Video signal output is turned off */
440 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
441 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
444 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 1);
445 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 0);
447 /* I/O mode settings */
448 flags
= CARMINE_DFLT_IP_DCTL_IO_CONT1
<< 16 |
449 CARMINE_DFLT_IP_DCTL_IO_CONT0
;
450 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_IOCONT1_IOCONT0
,
453 /* DRAM initial sequence */
454 flags
= CARMINE_DFLT_IP_DCTL_MODE
<< 16 | CARMINE_DFLT_IP_DCTL_ADD
;
455 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
,
458 flags
= CARMINE_DFLT_IP_DCTL_SET_TIME1
<< 16 |
459 CARMINE_DFLT_IP_DCTL_EMODE
;
460 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_SETTIME1_EMODE
,
463 flags
= CARMINE_DFLT_IP_DCTL_REFRESH
<< 16 |
464 CARMINE_DFLT_IP_DCTL_SET_TIME2
;
465 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_REFRESH_SETTIME2
,
468 flags
= CARMINE_DFLT_IP_DCTL_RESERVE2
<< 16 |
469 CARMINE_DFLT_IP_DCTL_FIFO_DEPTH
;
470 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV2_RSV1
, flags
);
472 flags
= CARMINE_DFLT_IP_DCTL_DDRIF2
<< 16 | CARMINE_DFLT_IP_DCTL_DDRIF1
;
473 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_DDRIF2_DDRIF1
,
476 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
477 CARMINE_DFLT_IP_DCTL_STATES
;
478 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
481 /* Executes DLL reset */
482 if (CARMINE_DCTL_DLL_RESET
) {
483 for (loops
= 0; loops
< CARMINE_DCTL_INIT_WAIT_LIMIT
; loops
++) {
485 ret
= c_get_hw_reg(hw
, CARMINE_DCTL_REG
+
486 CARMINE_DCTL_REG_RSV0_STATES
);
487 ret
&= CARMINE_DCTL_REG_STATES_MASK
;
491 mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL
);
494 if (loops
>= CARMINE_DCTL_INIT_WAIT_LIMIT
) {
495 printk(KERN_ERR
"DRAM init failed\n");
500 flags
= CARMINE_DFLT_IP_DCTL_MODE_AFT_RST
<< 16 |
501 CARMINE_DFLT_IP_DCTL_ADD
;
502 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
, flags
);
504 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
505 CARMINE_DFLT_IP_DCTL_STATES_AFT_RST
;
506 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
509 /* Initialize the write back register */
510 c_set_hw_reg(hw
, CARMINE_WB_REG
+ CARMINE_WB_REG_WBM
,
511 CARMINE_WB_REG_WBM_DEFAULT
);
513 /* Initialize the Kottos registers */
514 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRINTM
, 0);
515 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRERRM
, 0);
518 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PX
, 0);
519 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PY
, 0);
520 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LX
, 0);
521 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LY
, 0);
522 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TX
, 0);
523 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TY
, 0);
527 static struct fb_ops carminefb_ops
= {
528 .owner
= THIS_MODULE
,
529 .fb_fillrect
= cfb_fillrect
,
530 .fb_copyarea
= cfb_copyarea
,
531 .fb_imageblit
= cfb_imageblit
,
533 .fb_check_var
= carmine_check_var
,
534 .fb_set_par
= carmine_set_par
,
535 .fb_setcolreg
= carmine_setcolreg
,
538 static int __devinit
alloc_carmine_fb(void __iomem
*regs
, void __iomem
*smem_base
,
539 int smem_offset
, struct device
*device
, struct fb_info
**rinfo
)
542 struct fb_info
*info
;
543 struct carmine_fb
*par
;
545 info
= framebuffer_alloc(sizeof *par
, device
);
550 par
->display_reg
= regs
;
551 par
->smem_offset
= smem_offset
;
553 info
->screen_base
= smem_base
+ smem_offset
;
554 info
->screen_size
= CARMINE_DISPLAY_MEM
;
555 info
->fbops
= &carminefb_ops
;
557 info
->fix
= carminefb_fix
;
558 info
->pseudo_palette
= par
->pseudo_palette
;
559 info
->flags
= FBINFO_DEFAULT
;
561 ret
= fb_alloc_cmap(&info
->cmap
, 256, 1);
565 if (fb_mode
> ARRAY_SIZE(carmine_modedb
))
566 fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
568 par
->cur_mode
= par
->new_mode
= ~0;
570 ret
= fb_find_mode(&info
->var
, info
, fb_mode_str
, carmine_modedb
,
571 ARRAY_SIZE(carmine_modedb
),
572 &carmine_modedb
[fb_mode
], 32);
573 if (!ret
|| ret
== 4) {
575 goto err_dealloc_cmap
;
578 fb_videomode_to_modelist(carmine_modedb
, ARRAY_SIZE(carmine_modedb
),
581 ret
= register_framebuffer(info
);
583 goto err_dealloc_cmap
;
585 printk(KERN_INFO
"fb%d: %s frame buffer device\n", info
->node
,
592 fb_dealloc_cmap(&info
->cmap
);
594 framebuffer_release(info
);
598 static void cleanup_fb_device(struct fb_info
*info
)
601 unregister_framebuffer(info
);
602 fb_dealloc_cmap(&info
->cmap
);
603 framebuffer_release(info
);
607 static int __devinit
carminefb_probe(struct pci_dev
*dev
,
608 const struct pci_device_id
*ent
)
610 struct carmine_hw
*hw
;
611 struct device
*device
= &dev
->dev
;
612 struct fb_info
*info
;
615 ret
= pci_enable_device(dev
);
620 hw
= kzalloc(sizeof *hw
, GFP_KERNEL
);
624 carminefb_fix
.mmio_start
= pci_resource_start(dev
, CARMINE_CONFIG_BAR
);
625 carminefb_fix
.mmio_len
= pci_resource_len(dev
, CARMINE_CONFIG_BAR
);
627 if (!request_mem_region(carminefb_fix
.mmio_start
,
628 carminefb_fix
.mmio_len
,
629 "carminefb regbase")) {
630 printk(KERN_ERR
"carminefb: Can't reserve regbase.\n");
634 hw
->v_regs
= ioremap_nocache(carminefb_fix
.mmio_start
,
635 carminefb_fix
.mmio_len
);
637 printk(KERN_ERR
"carminefb: Can't remap %s register.\n",
639 goto err_free_reg_mmio
;
642 carminefb_fix
.smem_start
= pci_resource_start(dev
, CARMINE_MEMORY_BAR
);
643 carminefb_fix
.smem_len
= pci_resource_len(dev
, CARMINE_MEMORY_BAR
);
645 /* The memory area tends to be very large (256 MiB). Remap only what
646 * is required for that largest resolution to avoid remaps at run
649 if (carminefb_fix
.smem_len
> CARMINE_TOTAL_DIPLAY_MEM
)
650 carminefb_fix
.smem_len
= CARMINE_TOTAL_DIPLAY_MEM
;
652 else if (carminefb_fix
.smem_len
< CARMINE_TOTAL_DIPLAY_MEM
) {
653 printk(KERN_ERR
"carminefb: Memory bar is only %d bytes, %d "
654 "are required.", carminefb_fix
.smem_len
,
655 CARMINE_TOTAL_DIPLAY_MEM
);
656 goto err_free_reg_mmio
;
659 if (!request_mem_region(carminefb_fix
.smem_start
,
660 carminefb_fix
.smem_len
, "carminefb smem")) {
661 printk(KERN_ERR
"carminefb: Can't reserve smem.\n");
662 goto err_unmap_vregs
;
665 hw
->screen_mem
= ioremap_nocache(carminefb_fix
.smem_start
,
666 carminefb_fix
.smem_len
);
667 if (!hw
->screen_mem
) {
668 printk(KERN_ERR
"carmine: Can't ioremap smem area.\n");
669 release_mem_region(carminefb_fix
.smem_start
,
670 carminefb_fix
.smem_len
);
674 ret
= init_hardware(hw
);
676 goto err_unmap_screen
;
679 if (fb_displays
& CARMINE_USE_DISPLAY0
) {
680 ret
= alloc_carmine_fb(hw
->v_regs
+ CARMINE_DISP0_REG
,
681 hw
->screen_mem
, CARMINE_DISPLAY_MEM
* 0,
690 if (fb_displays
& CARMINE_USE_DISPLAY1
) {
691 ret
= alloc_carmine_fb(hw
->v_regs
+ CARMINE_DISP1_REG
,
692 hw
->screen_mem
, CARMINE_DISPLAY_MEM
* 1,
695 goto err_cleanup_fb0
;
701 pci_set_drvdata(dev
, hw
);
705 cleanup_fb_device(hw
->fb
[0]);
707 /* disable clock, etc */
708 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
, 0);
710 iounmap(hw
->screen_mem
);
712 release_mem_region(carminefb_fix
.mmio_start
, carminefb_fix
.mmio_len
);
716 release_mem_region(carminefb_fix
.mmio_start
, carminefb_fix
.mmio_len
);
720 pci_disable_device(dev
);
724 static void __devexit
carminefb_remove(struct pci_dev
*dev
)
726 struct carmine_hw
*hw
= pci_get_drvdata(dev
);
727 struct fb_fix_screeninfo fix
;
730 /* in case we use only fb1 and not fb1 */
732 fix
= hw
->fb
[0]->fix
;
734 fix
= hw
->fb
[1]->fix
;
736 /* deactivate display(s) and switch clocks */
737 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
738 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
739 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
, 0);
741 for (i
= 0; i
< MAX_DISPLAY
; i
++)
742 cleanup_fb_device(hw
->fb
[i
]);
744 iounmap(hw
->screen_mem
);
745 release_mem_region(fix
.smem_start
, fix
.smem_len
);
747 release_mem_region(fix
.mmio_start
, fix
.mmio_len
);
749 pci_set_drvdata(dev
, NULL
);
750 pci_disable_device(dev
);
754 #define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
755 static struct pci_device_id carmine_devices
[] __devinitdata
= {
757 PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED
, 0x202b)},
758 {0, 0, 0, 0, 0, 0, 0}
761 MODULE_DEVICE_TABLE(pci
, carmine_devices
);
763 static struct pci_driver carmine_pci_driver
= {
765 .id_table
= carmine_devices
,
766 .probe
= carminefb_probe
,
767 .remove
= __devexit_p(carminefb_remove
),
770 static int __init
carminefb_init(void)
773 (CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
))) {
774 printk(KERN_ERR
"If you disable both displays than you don't "
775 "need the driver at all\n");
778 return pci_register_driver(&carmine_pci_driver
);
780 module_init(carminefb_init
);
782 static void __exit
carminefb_cleanup(void)
784 pci_unregister_driver(&carmine_pci_driver
);
786 module_exit(carminefb_cleanup
);
788 MODULE_AUTHOR("Sebastian Siewior <bigeasy@linutronix.de>");
789 MODULE_DESCRIPTION("Framebuffer driver for Fujitsu Carmine based devices");
790 MODULE_LICENSE("GPL v2");