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>
15 #include <linux/module.h>
17 #include "carminefb.h"
18 #include "carminefb_regs.h"
20 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
21 #error "The endianness of the target host has not been defined."
25 * The initial video mode can be supplied via two different ways:
26 * - as a string that is passed to fb_find_mode() (module option fb_mode_str)
27 * - as an integer that picks the video mode from carmine_modedb[] (module
30 * If nothing is used than the initial video mode will be the
31 * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[].
33 #define CARMINEFB_DEFAULT_VIDEO_MODE 1
35 static unsigned int fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
36 module_param(fb_mode
, uint
, 0444);
37 MODULE_PARM_DESC(fb_mode
, "Initial video mode as integer.");
39 static char *fb_mode_str
;
40 module_param(fb_mode_str
, charp
, 0444);
41 MODULE_PARM_DESC(fb_mode_str
, "Initial video mode in characters.");
49 static int fb_displays
= CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
;
50 module_param(fb_displays
, int, 0444);
51 MODULE_PARM_DESC(fb_displays
, "Bit mode, which displays are used");
55 void __iomem
*screen_mem
;
56 struct fb_info
*fb
[MAX_DISPLAY
];
59 struct carmine_resolution
{
72 void __iomem
*display_reg
;
73 void __iomem
*screen_base
;
77 struct carmine_resolution
*res
;
78 u32 pseudo_palette
[16];
81 static struct fb_fix_screeninfo carminefb_fix
= {
83 .type
= FB_TYPE_PACKED_PIXELS
,
84 .visual
= FB_VISUAL_TRUECOLOR
,
85 .accel
= FB_ACCEL_NONE
,
88 static const struct fb_videomode carmine_modedb
[] = {
100 static struct carmine_resolution car_modes
[] = {
127 static int carmine_find_mode(const struct fb_var_screeninfo
*var
)
131 for (i
= 0; i
< ARRAY_SIZE(car_modes
); i
++)
132 if (car_modes
[i
].hdp
== var
->xres
&&
133 car_modes
[i
].vdp
== var
->yres
)
138 static void c_set_disp_reg(const struct carmine_fb
*par
,
141 writel(val
, par
->display_reg
+ offset
);
144 static u32
c_get_disp_reg(const struct carmine_fb
*par
,
147 return readl(par
->display_reg
+ offset
);
150 static void c_set_hw_reg(const struct carmine_hw
*hw
,
153 writel(val
, hw
->v_regs
+ offset
);
156 static u32
c_get_hw_reg(const struct carmine_hw
*hw
,
159 return readl(hw
->v_regs
+ offset
);
162 static int carmine_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
163 unsigned blue
, unsigned transp
, struct fb_info
*info
)
173 ((__be32
*)info
->pseudo_palette
)[regno
] = cpu_to_be32(transp
<< 24 |
174 red
<< 0 | green
<< 8 | blue
<< 16);
178 static int carmine_check_var(struct fb_var_screeninfo
*var
,
179 struct fb_info
*info
)
183 ret
= carmine_find_mode(var
);
187 if (var
->grayscale
|| var
->rotate
|| var
->nonstd
)
190 var
->xres_virtual
= var
->xres
;
191 var
->yres_virtual
= var
->yres
;
193 var
->bits_per_pixel
= 32;
196 var
->transp
.offset
= 24;
198 var
->green
.offset
= 8;
199 var
->blue
.offset
= 16;
201 var
->transp
.offset
= 24;
202 var
->red
.offset
= 16;
203 var
->green
.offset
= 8;
204 var
->blue
.offset
= 0;
208 var
->green
.length
= 8;
209 var
->blue
.length
= 8;
210 var
->transp
.length
= 8;
212 var
->red
.msb_right
= 0;
213 var
->green
.msb_right
= 0;
214 var
->blue
.msb_right
= 0;
215 var
->transp
.msb_right
= 0;
219 static void carmine_init_display_param(struct carmine_fb
*par
)
225 u32 soffset
= par
->smem_offset
;
227 c_set_disp_reg(par
, CARMINE_DISP_REG_C_TRANS
, 0);
228 c_set_disp_reg(par
, CARMINE_DISP_REG_MLMR_TRANS
, 0);
229 c_set_disp_reg(par
, CARMINE_DISP_REG_CURSOR_MODE
,
230 CARMINE_CURSOR0_PRIORITY_MASK
|
231 CARMINE_CURSOR1_PRIORITY_MASK
|
232 CARMINE_CURSOR_CUTZ_MASK
);
234 /* Set default cursor position */
235 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR1_POS
, 0 << 16 | 0);
236 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR2_POS
, 0 << 16 | 0);
238 /* Set default display mode */
239 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_EXT_MODE
, CARMINE_WINDOW_MODE
|
240 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
241 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_EXT_MODE
,
242 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
243 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_EXT_MODE
, CARMINE_EXTEND_MODE
|
244 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
245 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_EXT_MODE
, CARMINE_EXTEND_MODE
|
246 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
247 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_EXT_MODE
, CARMINE_EXTEND_MODE
|
248 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
249 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_EXT_MODE
, CARMINE_EXTEND_MODE
|
250 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
251 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_EXT_MODE
, CARMINE_EXTEND_MODE
|
252 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
253 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_EXT_MODE
, CARMINE_EXTEND_MODE
|
254 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
256 /* Set default frame size to layer mode register */
257 width
= par
->res
->hdp
* 4 / CARMINE_DISP_WIDTH_UNIT
;
258 width
= width
<< CARMINE_DISP_WIDTH_SHIFT
;
260 height
= par
->res
->vdp
- 1;
261 param
= width
| height
;
263 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_MODE_W_H
, param
);
264 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIDTH
, width
);
265 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_MODE_W_H
, param
);
266 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_MODE_W_H
, param
);
267 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_MODE_W_H
, param
);
268 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_MODE_W_H
, param
);
269 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_MODE_W_H
, param
);
270 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_MODE_W_H
, param
);
272 /* Set default pos and size */
273 window_size
= (par
->res
->vdp
- 1) << CARMINE_DISP_WIN_H_SHIFT
;
274 window_size
|= par
->res
->hdp
;
276 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_POS
, 0);
277 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_SIZE
, window_size
);
278 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_POS
, 0);
279 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_SIZE
, window_size
);
280 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_POS
, 0);
281 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_SIZE
, window_size
);
282 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_POS
, 0);
283 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_SIZE
, window_size
);
284 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_POS
, 0);
285 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_SIZE
, window_size
);
286 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_POS
, 0);
287 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_SIZE
, window_size
);
288 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_POS
, 0);
289 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_SIZE
, window_size
);
290 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_POS
, 0);
291 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_SIZE
, window_size
);
293 /* Set default origin address */
294 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_ORG_ADR
, soffset
);
295 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_ORG_ADR
, soffset
);
296 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_ORG_ADR1
, soffset
);
297 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_ORG_ADR1
, soffset
);
298 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_ORG_ADR1
, soffset
);
299 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_ORG_ADR1
, soffset
);
300 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_ORG_ADR1
, soffset
);
301 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_ORG_ADR1
, soffset
);
303 /* Set default display address */
304 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_ADR
, soffset
);
305 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_ADR1
, soffset
);
306 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_ADR1
, soffset
);
307 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_ADR1
, soffset
);
308 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_ADR1
, soffset
);
309 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_ADR0
, soffset
);
310 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_ADR0
, soffset
);
312 /* Set default display position */
313 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_POS
, 0);
314 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_POS
, 0);
315 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_POS
, 0);
316 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_POS
, 0);
317 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_POS
, 0);
318 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_POS
, 0);
319 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_POS
, 0);
321 /* Set default blend mode */
322 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L0
, 0);
323 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L1
, 0);
324 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L2
, 0);
325 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L3
, 0);
326 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L4
, 0);
327 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L5
, 0);
328 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L6
, 0);
329 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L7
, 0);
331 /* default transparency mode */
332 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_TRANS
, 0);
333 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_TRANS
, 0);
334 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_TRANS
, 0);
335 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_TRANS
, 0);
336 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_TRANS
, 0);
337 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_TRANS
, 0);
338 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_TRANS
, 0);
339 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_TRANS
, 0);
341 /* Set default read skip parameter */
342 c_set_disp_reg(par
, CARMINE_DISP_REG_L0RM
, 0);
343 c_set_disp_reg(par
, CARMINE_DISP_REG_L2RM
, 0);
344 c_set_disp_reg(par
, CARMINE_DISP_REG_L3RM
, 0);
345 c_set_disp_reg(par
, CARMINE_DISP_REG_L4RM
, 0);
346 c_set_disp_reg(par
, CARMINE_DISP_REG_L5RM
, 0);
347 c_set_disp_reg(par
, CARMINE_DISP_REG_L6RM
, 0);
348 c_set_disp_reg(par
, CARMINE_DISP_REG_L7RM
, 0);
350 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PX
, 0);
351 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PX
, 0);
352 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PX
, 0);
353 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PX
, 0);
354 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PX
, 0);
355 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PX
, 0);
356 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PX
, 0);
358 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PY
, 0);
359 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PY
, 0);
360 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PY
, 0);
361 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PY
, 0);
362 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PY
, 0);
363 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PY
, 0);
364 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PY
, 0);
367 static void set_display_parameters(struct carmine_fb
*par
)
370 u32 hdp
, vdp
, htp
, hsp
, hsw
, vtr
, vsp
, vsw
;
373 * display timing. Parameters are decreased by one because hardware
374 * spec is 0 to (n - 1)
376 hdp
= par
->res
->hdp
- 1;
377 vdp
= par
->res
->vdp
- 1;
378 htp
= par
->res
->htp
- 1;
379 hsp
= par
->res
->hsp
- 1;
380 hsw
= par
->res
->hsw
- 1;
381 vtr
= par
->res
->vtr
- 1;
382 vsp
= par
->res
->vsp
- 1;
383 vsw
= par
->res
->vsw
- 1;
385 c_set_disp_reg(par
, CARMINE_DISP_REG_H_TOTAL
,
386 htp
<< CARMINE_DISP_HTP_SHIFT
);
387 c_set_disp_reg(par
, CARMINE_DISP_REG_H_PERIOD
,
388 (hdp
<< CARMINE_DISP_HDB_SHIFT
) | hdp
);
389 c_set_disp_reg(par
, CARMINE_DISP_REG_V_H_W_H_POS
,
390 (vsw
<< CARMINE_DISP_VSW_SHIFT
) |
391 (hsw
<< CARMINE_DISP_HSW_SHIFT
) |
393 c_set_disp_reg(par
, CARMINE_DISP_REG_V_TOTAL
,
394 vtr
<< CARMINE_DISP_VTR_SHIFT
);
395 c_set_disp_reg(par
, CARMINE_DISP_REG_V_PERIOD_POS
,
396 (vdp
<< CARMINE_DISP_VDP_SHIFT
) | vsp
);
399 mode
= c_get_disp_reg(par
, CARMINE_DISP_REG_DCM1
);
400 mode
= (mode
& ~CARMINE_DISP_DCM_MASK
) |
401 (par
->res
->disp_mode
& CARMINE_DISP_DCM_MASK
);
402 /* enable video output and layer 0 */
403 mode
|= CARMINE_DEN
| CARMINE_L0E
;
404 c_set_disp_reg(par
, CARMINE_DISP_REG_DCM1
, mode
);
407 static int carmine_set_par(struct fb_info
*info
)
409 struct carmine_fb
*par
= info
->par
;
412 ret
= carmine_find_mode(&info
->var
);
417 if (par
->cur_mode
!= par
->new_mode
) {
419 par
->cur_mode
= par
->new_mode
;
420 par
->res
= &car_modes
[par
->new_mode
];
422 carmine_init_display_param(par
);
423 set_display_parameters(par
);
426 info
->fix
.line_length
= info
->var
.xres
* info
->var
.bits_per_pixel
/ 8;
430 static int init_hardware(struct carmine_hw
*hw
)
436 /* Initialize Carmine */
437 /* Sets internal clock */
438 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
,
439 CARMINE_DFLT_IP_CLOCK_ENABLE
);
441 /* Video signal output is turned off */
442 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
443 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
446 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 1);
447 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 0);
449 /* I/O mode settings */
450 flags
= CARMINE_DFLT_IP_DCTL_IO_CONT1
<< 16 |
451 CARMINE_DFLT_IP_DCTL_IO_CONT0
;
452 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_IOCONT1_IOCONT0
,
455 /* DRAM initial sequence */
456 flags
= CARMINE_DFLT_IP_DCTL_MODE
<< 16 | CARMINE_DFLT_IP_DCTL_ADD
;
457 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
,
460 flags
= CARMINE_DFLT_IP_DCTL_SET_TIME1
<< 16 |
461 CARMINE_DFLT_IP_DCTL_EMODE
;
462 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_SETTIME1_EMODE
,
465 flags
= CARMINE_DFLT_IP_DCTL_REFRESH
<< 16 |
466 CARMINE_DFLT_IP_DCTL_SET_TIME2
;
467 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_REFRESH_SETTIME2
,
470 flags
= CARMINE_DFLT_IP_DCTL_RESERVE2
<< 16 |
471 CARMINE_DFLT_IP_DCTL_FIFO_DEPTH
;
472 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV2_RSV1
, flags
);
474 flags
= CARMINE_DFLT_IP_DCTL_DDRIF2
<< 16 | CARMINE_DFLT_IP_DCTL_DDRIF1
;
475 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_DDRIF2_DDRIF1
,
478 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
479 CARMINE_DFLT_IP_DCTL_STATES
;
480 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
483 /* Executes DLL reset */
484 if (CARMINE_DCTL_DLL_RESET
) {
485 for (loops
= 0; loops
< CARMINE_DCTL_INIT_WAIT_LIMIT
; loops
++) {
487 ret
= c_get_hw_reg(hw
, CARMINE_DCTL_REG
+
488 CARMINE_DCTL_REG_RSV0_STATES
);
489 ret
&= CARMINE_DCTL_REG_STATES_MASK
;
493 mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL
);
496 if (loops
>= CARMINE_DCTL_INIT_WAIT_LIMIT
) {
497 printk(KERN_ERR
"DRAM init failed\n");
502 flags
= CARMINE_DFLT_IP_DCTL_MODE_AFT_RST
<< 16 |
503 CARMINE_DFLT_IP_DCTL_ADD
;
504 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
, flags
);
506 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
507 CARMINE_DFLT_IP_DCTL_STATES_AFT_RST
;
508 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
511 /* Initialize the write back register */
512 c_set_hw_reg(hw
, CARMINE_WB_REG
+ CARMINE_WB_REG_WBM
,
513 CARMINE_WB_REG_WBM_DEFAULT
);
515 /* Initialize the Kottos registers */
516 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRINTM
, 0);
517 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRERRM
, 0);
520 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PX
, 0);
521 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PY
, 0);
522 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LX
, 0);
523 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LY
, 0);
524 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TX
, 0);
525 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TY
, 0);
529 static struct fb_ops carminefb_ops
= {
530 .owner
= THIS_MODULE
,
531 .fb_fillrect
= cfb_fillrect
,
532 .fb_copyarea
= cfb_copyarea
,
533 .fb_imageblit
= cfb_imageblit
,
535 .fb_check_var
= carmine_check_var
,
536 .fb_set_par
= carmine_set_par
,
537 .fb_setcolreg
= carmine_setcolreg
,
540 static int alloc_carmine_fb(void __iomem
*regs
, void __iomem
*smem_base
,
541 int smem_offset
, struct device
*device
,
542 struct fb_info
**rinfo
)
545 struct fb_info
*info
;
546 struct carmine_fb
*par
;
548 info
= framebuffer_alloc(sizeof *par
, device
);
553 par
->display_reg
= regs
;
554 par
->smem_offset
= smem_offset
;
556 info
->screen_base
= smem_base
+ smem_offset
;
557 info
->screen_size
= CARMINE_DISPLAY_MEM
;
558 info
->fbops
= &carminefb_ops
;
560 info
->fix
= carminefb_fix
;
561 info
->pseudo_palette
= par
->pseudo_palette
;
562 info
->flags
= FBINFO_DEFAULT
;
564 ret
= fb_alloc_cmap(&info
->cmap
, 256, 1);
568 if (fb_mode
>= ARRAY_SIZE(carmine_modedb
))
569 fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
571 par
->cur_mode
= par
->new_mode
= ~0;
573 ret
= fb_find_mode(&info
->var
, info
, fb_mode_str
, carmine_modedb
,
574 ARRAY_SIZE(carmine_modedb
),
575 &carmine_modedb
[fb_mode
], 32);
576 if (!ret
|| ret
== 4) {
578 goto err_dealloc_cmap
;
581 fb_videomode_to_modelist(carmine_modedb
, ARRAY_SIZE(carmine_modedb
),
584 ret
= register_framebuffer(info
);
586 goto err_dealloc_cmap
;
588 printk(KERN_INFO
"fb%d: %s frame buffer device\n", info
->node
,
595 fb_dealloc_cmap(&info
->cmap
);
597 framebuffer_release(info
);
601 static void cleanup_fb_device(struct fb_info
*info
)
604 unregister_framebuffer(info
);
605 fb_dealloc_cmap(&info
->cmap
);
606 framebuffer_release(info
);
610 static int carminefb_probe(struct pci_dev
*dev
, const struct pci_device_id
*ent
)
612 struct carmine_hw
*hw
;
613 struct device
*device
= &dev
->dev
;
614 struct fb_info
*info
;
617 ret
= pci_enable_device(dev
);
622 hw
= kzalloc(sizeof *hw
, GFP_KERNEL
);
626 carminefb_fix
.mmio_start
= pci_resource_start(dev
, CARMINE_CONFIG_BAR
);
627 carminefb_fix
.mmio_len
= pci_resource_len(dev
, CARMINE_CONFIG_BAR
);
629 if (!request_mem_region(carminefb_fix
.mmio_start
,
630 carminefb_fix
.mmio_len
,
631 "carminefb regbase")) {
632 printk(KERN_ERR
"carminefb: Can't reserve regbase.\n");
636 hw
->v_regs
= ioremap_nocache(carminefb_fix
.mmio_start
,
637 carminefb_fix
.mmio_len
);
639 printk(KERN_ERR
"carminefb: Can't remap %s register.\n",
641 goto err_free_reg_mmio
;
644 carminefb_fix
.smem_start
= pci_resource_start(dev
, CARMINE_MEMORY_BAR
);
645 carminefb_fix
.smem_len
= pci_resource_len(dev
, CARMINE_MEMORY_BAR
);
647 /* The memory area tends to be very large (256 MiB). Remap only what
648 * is required for that largest resolution to avoid remaps at run
651 if (carminefb_fix
.smem_len
> CARMINE_TOTAL_DIPLAY_MEM
)
652 carminefb_fix
.smem_len
= CARMINE_TOTAL_DIPLAY_MEM
;
654 else if (carminefb_fix
.smem_len
< CARMINE_TOTAL_DIPLAY_MEM
) {
655 printk(KERN_ERR
"carminefb: Memory bar is only %d bytes, %d "
656 "are required.", carminefb_fix
.smem_len
,
657 CARMINE_TOTAL_DIPLAY_MEM
);
658 goto err_unmap_vregs
;
661 if (!request_mem_region(carminefb_fix
.smem_start
,
662 carminefb_fix
.smem_len
, "carminefb smem")) {
663 printk(KERN_ERR
"carminefb: Can't reserve smem.\n");
664 goto err_unmap_vregs
;
667 hw
->screen_mem
= ioremap_nocache(carminefb_fix
.smem_start
,
668 carminefb_fix
.smem_len
);
669 if (!hw
->screen_mem
) {
670 printk(KERN_ERR
"carmine: Can't ioremap smem area.\n");
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
.smem_start
, carminefb_fix
.smem_len
);
716 release_mem_region(carminefb_fix
.mmio_start
, carminefb_fix
.mmio_len
);
720 pci_disable_device(dev
);
724 static void 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
[] = {
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
= 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");