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>
14 #include <linux/slab.h>
16 #include "carminefb.h"
17 #include "carminefb_regs.h"
19 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
20 #error "The endianness of the target host has not been defined."
24 * The initial video mode can be supplied via two different ways:
25 * - as a string that is passed to fb_find_mode() (module option fb_mode_str)
26 * - as an integer that picks the video mode from carmine_modedb[] (module
29 * If nothing is used than the initial video mode will be the
30 * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[].
32 #define CARMINEFB_DEFAULT_VIDEO_MODE 1
34 static unsigned int fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
35 module_param(fb_mode
, uint
, 444);
36 MODULE_PARM_DESC(fb_mode
, "Initial video mode as integer.");
38 static char *fb_mode_str
;
39 module_param(fb_mode_str
, charp
, 444);
40 MODULE_PARM_DESC(fb_mode_str
, "Initial video mode in characters.");
48 static int fb_displays
= CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
;
49 module_param(fb_displays
, int, 444);
50 MODULE_PARM_DESC(fb_displays
, "Bit mode, which displays are used");
54 void __iomem
*screen_mem
;
55 struct fb_info
*fb
[MAX_DISPLAY
];
58 struct carmine_resolution
{
71 void __iomem
*display_reg
;
72 void __iomem
*screen_base
;
76 struct carmine_resolution
*res
;
77 u32 pseudo_palette
[16];
80 static struct fb_fix_screeninfo carminefb_fix __devinitdata
= {
82 .type
= FB_TYPE_PACKED_PIXELS
,
83 .visual
= FB_VISUAL_TRUECOLOR
,
84 .accel
= FB_ACCEL_NONE
,
87 static const struct fb_videomode carmine_modedb
[] = {
99 static struct carmine_resolution car_modes
[] = {
126 static int carmine_find_mode(const struct fb_var_screeninfo
*var
)
130 for (i
= 0; i
< ARRAY_SIZE(car_modes
); i
++)
131 if (car_modes
[i
].hdp
== var
->xres
&&
132 car_modes
[i
].vdp
== var
->yres
)
137 static void c_set_disp_reg(const struct carmine_fb
*par
,
140 writel(val
, par
->display_reg
+ offset
);
143 static u32
c_get_disp_reg(const struct carmine_fb
*par
,
146 return readl(par
->display_reg
+ offset
);
149 static void c_set_hw_reg(const struct carmine_hw
*hw
,
152 writel(val
, hw
->v_regs
+ offset
);
155 static u32
c_get_hw_reg(const struct carmine_hw
*hw
,
158 return readl(hw
->v_regs
+ offset
);
161 static int carmine_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
162 unsigned blue
, unsigned transp
, struct fb_info
*info
)
172 ((__be32
*)info
->pseudo_palette
)[regno
] = cpu_to_be32(transp
<< 24 |
173 red
<< 0 | green
<< 8 | blue
<< 16);
177 static int carmine_check_var(struct fb_var_screeninfo
*var
,
178 struct fb_info
*info
)
182 ret
= carmine_find_mode(var
);
186 if (var
->grayscale
|| var
->rotate
|| var
->nonstd
)
189 var
->xres_virtual
= var
->xres
;
190 var
->yres_virtual
= var
->yres
;
192 var
->bits_per_pixel
= 32;
195 var
->transp
.offset
= 24;
197 var
->green
.offset
= 8;
198 var
->blue
.offset
= 16;
200 var
->transp
.offset
= 24;
201 var
->red
.offset
= 16;
202 var
->green
.offset
= 8;
203 var
->blue
.offset
= 0;
207 var
->green
.length
= 8;
208 var
->blue
.length
= 8;
209 var
->transp
.length
= 8;
211 var
->red
.msb_right
= 0;
212 var
->green
.msb_right
= 0;
213 var
->blue
.msb_right
= 0;
214 var
->transp
.msb_right
= 0;
218 static void carmine_init_display_param(struct carmine_fb
*par
)
224 u32 soffset
= par
->smem_offset
;
226 c_set_disp_reg(par
, CARMINE_DISP_REG_C_TRANS
, 0);
227 c_set_disp_reg(par
, CARMINE_DISP_REG_MLMR_TRANS
, 0);
228 c_set_disp_reg(par
, CARMINE_DISP_REG_CURSOR_MODE
,
229 CARMINE_CURSOR0_PRIORITY_MASK
|
230 CARMINE_CURSOR1_PRIORITY_MASK
|
231 CARMINE_CURSOR_CUTZ_MASK
);
233 /* Set default cursor position */
234 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR1_POS
, 0 << 16 | 0);
235 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR2_POS
, 0 << 16 | 0);
237 /* Set default display mode */
238 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_EXT_MODE
, CARMINE_WINDOW_MODE
|
239 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
240 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_EXT_MODE
,
241 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
242 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_EXT_MODE
, CARMINE_EXTEND_MODE
|
243 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
244 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_EXT_MODE
, CARMINE_EXTEND_MODE
|
245 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
246 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_EXT_MODE
, CARMINE_EXTEND_MODE
|
247 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
248 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_EXT_MODE
, CARMINE_EXTEND_MODE
|
249 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
250 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_EXT_MODE
, CARMINE_EXTEND_MODE
|
251 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
252 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_EXT_MODE
, CARMINE_EXTEND_MODE
|
253 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
255 /* Set default frame size to layer mode register */
256 width
= par
->res
->hdp
* 4 / CARMINE_DISP_WIDTH_UNIT
;
257 width
= width
<< CARMINE_DISP_WIDTH_SHIFT
;
259 height
= par
->res
->vdp
- 1;
260 param
= width
| height
;
262 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_MODE_W_H
, param
);
263 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIDTH
, width
);
264 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_MODE_W_H
, param
);
265 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_MODE_W_H
, param
);
266 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_MODE_W_H
, param
);
267 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_MODE_W_H
, param
);
268 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_MODE_W_H
, param
);
269 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_MODE_W_H
, param
);
271 /* Set default pos and size */
272 window_size
= (par
->res
->vdp
- 1) << CARMINE_DISP_WIN_H_SHIFT
;
273 window_size
|= par
->res
->hdp
;
275 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_POS
, 0);
276 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_SIZE
, window_size
);
277 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_POS
, 0);
278 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_SIZE
, window_size
);
279 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_POS
, 0);
280 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_SIZE
, window_size
);
281 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_POS
, 0);
282 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_SIZE
, window_size
);
283 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_POS
, 0);
284 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_SIZE
, window_size
);
285 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_POS
, 0);
286 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_SIZE
, window_size
);
287 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_POS
, 0);
288 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_SIZE
, window_size
);
289 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_POS
, 0);
290 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_SIZE
, window_size
);
292 /* Set default origin address */
293 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_ORG_ADR
, soffset
);
294 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_ORG_ADR
, soffset
);
295 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_ORG_ADR1
, soffset
);
296 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_ORG_ADR1
, soffset
);
297 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_ORG_ADR1
, soffset
);
298 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_ORG_ADR1
, soffset
);
299 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_ORG_ADR1
, soffset
);
300 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_ORG_ADR1
, soffset
);
302 /* Set default display address */
303 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_ADR
, soffset
);
304 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_ADR1
, soffset
);
305 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_ADR1
, soffset
);
306 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_ADR1
, soffset
);
307 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_ADR1
, soffset
);
308 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_ADR0
, soffset
);
309 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_ADR0
, soffset
);
311 /* Set default display position */
312 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_POS
, 0);
313 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_POS
, 0);
314 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_POS
, 0);
315 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_POS
, 0);
316 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_POS
, 0);
317 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_POS
, 0);
318 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_POS
, 0);
320 /* Set default blend mode */
321 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L0
, 0);
322 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L1
, 0);
323 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L2
, 0);
324 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L3
, 0);
325 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L4
, 0);
326 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L5
, 0);
327 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L6
, 0);
328 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L7
, 0);
330 /* default transparency mode */
331 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_TRANS
, 0);
332 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_TRANS
, 0);
333 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_TRANS
, 0);
334 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_TRANS
, 0);
335 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_TRANS
, 0);
336 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_TRANS
, 0);
337 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_TRANS
, 0);
338 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_TRANS
, 0);
340 /* Set default read skip parameter */
341 c_set_disp_reg(par
, CARMINE_DISP_REG_L0RM
, 0);
342 c_set_disp_reg(par
, CARMINE_DISP_REG_L2RM
, 0);
343 c_set_disp_reg(par
, CARMINE_DISP_REG_L3RM
, 0);
344 c_set_disp_reg(par
, CARMINE_DISP_REG_L4RM
, 0);
345 c_set_disp_reg(par
, CARMINE_DISP_REG_L5RM
, 0);
346 c_set_disp_reg(par
, CARMINE_DISP_REG_L6RM
, 0);
347 c_set_disp_reg(par
, CARMINE_DISP_REG_L7RM
, 0);
349 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PX
, 0);
350 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PX
, 0);
351 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PX
, 0);
352 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PX
, 0);
353 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PX
, 0);
354 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PX
, 0);
355 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PX
, 0);
357 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PY
, 0);
358 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PY
, 0);
359 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PY
, 0);
360 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PY
, 0);
361 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PY
, 0);
362 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PY
, 0);
363 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PY
, 0);
366 static void set_display_parameters(struct carmine_fb
*par
)
369 u32 hdp
, vdp
, htp
, hsp
, hsw
, vtr
, vsp
, vsw
;
372 * display timing. Parameters are decreased by one because hardware
373 * spec is 0 to (n - 1)
375 hdp
= par
->res
->hdp
- 1;
376 vdp
= par
->res
->vdp
- 1;
377 htp
= par
->res
->htp
- 1;
378 hsp
= par
->res
->hsp
- 1;
379 hsw
= par
->res
->hsw
- 1;
380 vtr
= par
->res
->vtr
- 1;
381 vsp
= par
->res
->vsp
- 1;
382 vsw
= par
->res
->vsw
- 1;
384 c_set_disp_reg(par
, CARMINE_DISP_REG_H_TOTAL
,
385 htp
<< CARMINE_DISP_HTP_SHIFT
);
386 c_set_disp_reg(par
, CARMINE_DISP_REG_H_PERIOD
,
387 (hdp
<< CARMINE_DISP_HDB_SHIFT
) | hdp
);
388 c_set_disp_reg(par
, CARMINE_DISP_REG_V_H_W_H_POS
,
389 (vsw
<< CARMINE_DISP_VSW_SHIFT
) |
390 (hsw
<< CARMINE_DISP_HSW_SHIFT
) |
392 c_set_disp_reg(par
, CARMINE_DISP_REG_V_TOTAL
,
393 vtr
<< CARMINE_DISP_VTR_SHIFT
);
394 c_set_disp_reg(par
, CARMINE_DISP_REG_V_PERIOD_POS
,
395 (vdp
<< CARMINE_DISP_VDP_SHIFT
) | vsp
);
398 mode
= c_get_disp_reg(par
, CARMINE_DISP_REG_DCM1
);
399 mode
= (mode
& ~CARMINE_DISP_DCM_MASK
) |
400 (par
->res
->disp_mode
& CARMINE_DISP_DCM_MASK
);
401 /* enable video output and layer 0 */
402 mode
|= CARMINE_DEN
| CARMINE_L0E
;
403 c_set_disp_reg(par
, CARMINE_DISP_REG_DCM1
, mode
);
406 static int carmine_set_par(struct fb_info
*info
)
408 struct carmine_fb
*par
= info
->par
;
411 ret
= carmine_find_mode(&info
->var
);
416 if (par
->cur_mode
!= par
->new_mode
) {
418 par
->cur_mode
= par
->new_mode
;
419 par
->res
= &car_modes
[par
->new_mode
];
421 carmine_init_display_param(par
);
422 set_display_parameters(par
);
425 info
->fix
.line_length
= info
->var
.xres
* info
->var
.bits_per_pixel
/ 8;
429 static int init_hardware(struct carmine_hw
*hw
)
435 /* Initialize Carmine */
436 /* Sets internal clock */
437 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
,
438 CARMINE_DFLT_IP_CLOCK_ENABLE
);
440 /* Video signal output is turned off */
441 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
442 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
445 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 1);
446 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 0);
448 /* I/O mode settings */
449 flags
= CARMINE_DFLT_IP_DCTL_IO_CONT1
<< 16 |
450 CARMINE_DFLT_IP_DCTL_IO_CONT0
;
451 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_IOCONT1_IOCONT0
,
454 /* DRAM initial sequence */
455 flags
= CARMINE_DFLT_IP_DCTL_MODE
<< 16 | CARMINE_DFLT_IP_DCTL_ADD
;
456 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
,
459 flags
= CARMINE_DFLT_IP_DCTL_SET_TIME1
<< 16 |
460 CARMINE_DFLT_IP_DCTL_EMODE
;
461 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_SETTIME1_EMODE
,
464 flags
= CARMINE_DFLT_IP_DCTL_REFRESH
<< 16 |
465 CARMINE_DFLT_IP_DCTL_SET_TIME2
;
466 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_REFRESH_SETTIME2
,
469 flags
= CARMINE_DFLT_IP_DCTL_RESERVE2
<< 16 |
470 CARMINE_DFLT_IP_DCTL_FIFO_DEPTH
;
471 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV2_RSV1
, flags
);
473 flags
= CARMINE_DFLT_IP_DCTL_DDRIF2
<< 16 | CARMINE_DFLT_IP_DCTL_DDRIF1
;
474 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_DDRIF2_DDRIF1
,
477 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
478 CARMINE_DFLT_IP_DCTL_STATES
;
479 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
482 /* Executes DLL reset */
483 if (CARMINE_DCTL_DLL_RESET
) {
484 for (loops
= 0; loops
< CARMINE_DCTL_INIT_WAIT_LIMIT
; loops
++) {
486 ret
= c_get_hw_reg(hw
, CARMINE_DCTL_REG
+
487 CARMINE_DCTL_REG_RSV0_STATES
);
488 ret
&= CARMINE_DCTL_REG_STATES_MASK
;
492 mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL
);
495 if (loops
>= CARMINE_DCTL_INIT_WAIT_LIMIT
) {
496 printk(KERN_ERR
"DRAM init failed\n");
501 flags
= CARMINE_DFLT_IP_DCTL_MODE_AFT_RST
<< 16 |
502 CARMINE_DFLT_IP_DCTL_ADD
;
503 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
, flags
);
505 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
506 CARMINE_DFLT_IP_DCTL_STATES_AFT_RST
;
507 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
510 /* Initialize the write back register */
511 c_set_hw_reg(hw
, CARMINE_WB_REG
+ CARMINE_WB_REG_WBM
,
512 CARMINE_WB_REG_WBM_DEFAULT
);
514 /* Initialize the Kottos registers */
515 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRINTM
, 0);
516 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRERRM
, 0);
519 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PX
, 0);
520 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PY
, 0);
521 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LX
, 0);
522 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LY
, 0);
523 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TX
, 0);
524 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TY
, 0);
528 static struct fb_ops carminefb_ops
= {
529 .owner
= THIS_MODULE
,
530 .fb_fillrect
= cfb_fillrect
,
531 .fb_copyarea
= cfb_copyarea
,
532 .fb_imageblit
= cfb_imageblit
,
534 .fb_check_var
= carmine_check_var
,
535 .fb_set_par
= carmine_set_par
,
536 .fb_setcolreg
= carmine_setcolreg
,
539 static int __devinit
alloc_carmine_fb(void __iomem
*regs
, void __iomem
*smem_base
,
540 int smem_offset
, struct device
*device
, struct fb_info
**rinfo
)
543 struct fb_info
*info
;
544 struct carmine_fb
*par
;
546 info
= framebuffer_alloc(sizeof *par
, device
);
551 par
->display_reg
= regs
;
552 par
->smem_offset
= smem_offset
;
554 info
->screen_base
= smem_base
+ smem_offset
;
555 info
->screen_size
= CARMINE_DISPLAY_MEM
;
556 info
->fbops
= &carminefb_ops
;
558 info
->fix
= carminefb_fix
;
559 info
->pseudo_palette
= par
->pseudo_palette
;
560 info
->flags
= FBINFO_DEFAULT
;
562 ret
= fb_alloc_cmap(&info
->cmap
, 256, 1);
566 if (fb_mode
>= ARRAY_SIZE(carmine_modedb
))
567 fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
569 par
->cur_mode
= par
->new_mode
= ~0;
571 ret
= fb_find_mode(&info
->var
, info
, fb_mode_str
, carmine_modedb
,
572 ARRAY_SIZE(carmine_modedb
),
573 &carmine_modedb
[fb_mode
], 32);
574 if (!ret
|| ret
== 4) {
576 goto err_dealloc_cmap
;
579 fb_videomode_to_modelist(carmine_modedb
, ARRAY_SIZE(carmine_modedb
),
582 ret
= register_framebuffer(info
);
584 goto err_dealloc_cmap
;
586 printk(KERN_INFO
"fb%d: %s frame buffer device\n", info
->node
,
593 fb_dealloc_cmap(&info
->cmap
);
595 framebuffer_release(info
);
599 static void cleanup_fb_device(struct fb_info
*info
)
602 unregister_framebuffer(info
);
603 fb_dealloc_cmap(&info
->cmap
);
604 framebuffer_release(info
);
608 static int __devinit
carminefb_probe(struct pci_dev
*dev
,
609 const struct pci_device_id
*ent
)
611 struct carmine_hw
*hw
;
612 struct device
*device
= &dev
->dev
;
613 struct fb_info
*info
;
616 ret
= pci_enable_device(dev
);
621 hw
= kzalloc(sizeof *hw
, GFP_KERNEL
);
625 carminefb_fix
.mmio_start
= pci_resource_start(dev
, CARMINE_CONFIG_BAR
);
626 carminefb_fix
.mmio_len
= pci_resource_len(dev
, CARMINE_CONFIG_BAR
);
628 if (!request_mem_region(carminefb_fix
.mmio_start
,
629 carminefb_fix
.mmio_len
,
630 "carminefb regbase")) {
631 printk(KERN_ERR
"carminefb: Can't reserve regbase.\n");
635 hw
->v_regs
= ioremap_nocache(carminefb_fix
.mmio_start
,
636 carminefb_fix
.mmio_len
);
638 printk(KERN_ERR
"carminefb: Can't remap %s register.\n",
640 goto err_free_reg_mmio
;
643 carminefb_fix
.smem_start
= pci_resource_start(dev
, CARMINE_MEMORY_BAR
);
644 carminefb_fix
.smem_len
= pci_resource_len(dev
, CARMINE_MEMORY_BAR
);
646 /* The memory area tends to be very large (256 MiB). Remap only what
647 * is required for that largest resolution to avoid remaps at run
650 if (carminefb_fix
.smem_len
> CARMINE_TOTAL_DIPLAY_MEM
)
651 carminefb_fix
.smem_len
= CARMINE_TOTAL_DIPLAY_MEM
;
653 else if (carminefb_fix
.smem_len
< CARMINE_TOTAL_DIPLAY_MEM
) {
654 printk(KERN_ERR
"carminefb: Memory bar is only %d bytes, %d "
655 "are required.", carminefb_fix
.smem_len
,
656 CARMINE_TOTAL_DIPLAY_MEM
);
657 goto err_unmap_vregs
;
660 if (!request_mem_region(carminefb_fix
.smem_start
,
661 carminefb_fix
.smem_len
, "carminefb smem")) {
662 printk(KERN_ERR
"carminefb: Can't reserve smem.\n");
663 goto err_unmap_vregs
;
666 hw
->screen_mem
= ioremap_nocache(carminefb_fix
.smem_start
,
667 carminefb_fix
.smem_len
);
668 if (!hw
->screen_mem
) {
669 printk(KERN_ERR
"carmine: Can't ioremap smem area.\n");
673 ret
= init_hardware(hw
);
675 goto err_unmap_screen
;
678 if (fb_displays
& CARMINE_USE_DISPLAY0
) {
679 ret
= alloc_carmine_fb(hw
->v_regs
+ CARMINE_DISP0_REG
,
680 hw
->screen_mem
, CARMINE_DISPLAY_MEM
* 0,
689 if (fb_displays
& CARMINE_USE_DISPLAY1
) {
690 ret
= alloc_carmine_fb(hw
->v_regs
+ CARMINE_DISP1_REG
,
691 hw
->screen_mem
, CARMINE_DISPLAY_MEM
* 1,
694 goto err_cleanup_fb0
;
700 pci_set_drvdata(dev
, hw
);
704 cleanup_fb_device(hw
->fb
[0]);
706 /* disable clock, etc */
707 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
, 0);
709 iounmap(hw
->screen_mem
);
711 release_mem_region(carminefb_fix
.smem_start
, carminefb_fix
.smem_len
);
715 release_mem_region(carminefb_fix
.mmio_start
, carminefb_fix
.mmio_len
);
719 pci_disable_device(dev
);
723 static void __devexit
carminefb_remove(struct pci_dev
*dev
)
725 struct carmine_hw
*hw
= pci_get_drvdata(dev
);
726 struct fb_fix_screeninfo fix
;
729 /* in case we use only fb1 and not fb1 */
731 fix
= hw
->fb
[0]->fix
;
733 fix
= hw
->fb
[1]->fix
;
735 /* deactivate display(s) and switch clocks */
736 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
737 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
738 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
, 0);
740 for (i
= 0; i
< MAX_DISPLAY
; i
++)
741 cleanup_fb_device(hw
->fb
[i
]);
743 iounmap(hw
->screen_mem
);
744 release_mem_region(fix
.smem_start
, fix
.smem_len
);
746 release_mem_region(fix
.mmio_start
, fix
.mmio_len
);
748 pci_set_drvdata(dev
, NULL
);
749 pci_disable_device(dev
);
753 #define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
754 static struct pci_device_id carmine_devices
[] __devinitdata
= {
756 PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED
, 0x202b)},
757 {0, 0, 0, 0, 0, 0, 0}
760 MODULE_DEVICE_TABLE(pci
, carmine_devices
);
762 static struct pci_driver carmine_pci_driver
= {
764 .id_table
= carmine_devices
,
765 .probe
= carminefb_probe
,
766 .remove
= __devexit_p(carminefb_remove
),
769 static int __init
carminefb_init(void)
772 (CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
))) {
773 printk(KERN_ERR
"If you disable both displays than you don't "
774 "need the driver at all\n");
777 return pci_register_driver(&carmine_pci_driver
);
779 module_init(carminefb_init
);
781 static void __exit
carminefb_cleanup(void)
783 pci_unregister_driver(&carmine_pci_driver
);
785 module_exit(carminefb_cleanup
);
787 MODULE_AUTHOR("Sebastian Siewior <bigeasy@linutronix.de>");
788 MODULE_DESCRIPTION("Framebuffer driver for Fujitsu Carmine based devices");
789 MODULE_LICENSE("GPL v2");