1 // SPDX-License-Identifier: GPL-2.0-only
3 * Frame buffer driver for the Carmine GPU.
5 * The driver configures the GPU as follows
6 * - FB0 is display 0 with unique memory area
7 * - FB1 is display 1 with unique memory area
8 * - both display use 32 bit colors
10 #include <linux/delay.h>
11 #include <linux/errno.h>
13 #include <linux/interrupt.h>
14 #include <linux/pci.h>
15 #include <linux/slab.h>
16 #include <linux/module.h>
18 #include "carminefb.h"
19 #include "carminefb_regs.h"
21 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
22 #error "The endianness of the target host has not been defined."
26 * The initial video mode can be supplied via two different ways:
27 * - as a string that is passed to fb_find_mode() (module option fb_mode_str)
28 * - as an integer that picks the video mode from carmine_modedb[] (module
31 * If nothing is used than the initial video mode will be the
32 * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[].
34 #define CARMINEFB_DEFAULT_VIDEO_MODE 1
36 static unsigned int fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
37 module_param(fb_mode
, uint
, 0444);
38 MODULE_PARM_DESC(fb_mode
, "Initial video mode as integer.");
40 static char *fb_mode_str
;
41 module_param(fb_mode_str
, charp
, 0444);
42 MODULE_PARM_DESC(fb_mode_str
, "Initial video mode in characters.");
50 static int fb_displays
= CARMINE_USE_DISPLAY0
| CARMINE_USE_DISPLAY1
;
51 module_param(fb_displays
, int, 0444);
52 MODULE_PARM_DESC(fb_displays
, "Bit mode, which displays are used");
56 void __iomem
*screen_mem
;
57 struct fb_info
*fb
[MAX_DISPLAY
];
60 struct carmine_resolution
{
73 void __iomem
*display_reg
;
74 void __iomem
*screen_base
;
78 struct carmine_resolution
*res
;
79 u32 pseudo_palette
[16];
82 static struct fb_fix_screeninfo carminefb_fix
= {
84 .type
= FB_TYPE_PACKED_PIXELS
,
85 .visual
= FB_VISUAL_TRUECOLOR
,
86 .accel
= FB_ACCEL_NONE
,
89 static const struct fb_videomode carmine_modedb
[] = {
101 static struct carmine_resolution car_modes
[] = {
128 static int carmine_find_mode(const struct fb_var_screeninfo
*var
)
132 for (i
= 0; i
< ARRAY_SIZE(car_modes
); i
++)
133 if (car_modes
[i
].hdp
== var
->xres
&&
134 car_modes
[i
].vdp
== var
->yres
)
139 static void c_set_disp_reg(const struct carmine_fb
*par
,
142 writel(val
, par
->display_reg
+ offset
);
145 static u32
c_get_disp_reg(const struct carmine_fb
*par
,
148 return readl(par
->display_reg
+ offset
);
151 static void c_set_hw_reg(const struct carmine_hw
*hw
,
154 writel(val
, hw
->v_regs
+ offset
);
157 static u32
c_get_hw_reg(const struct carmine_hw
*hw
,
160 return readl(hw
->v_regs
+ offset
);
163 static int carmine_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
164 unsigned blue
, unsigned transp
, struct fb_info
*info
)
174 ((__be32
*)info
->pseudo_palette
)[regno
] = cpu_to_be32(transp
<< 24 |
175 red
<< 0 | green
<< 8 | blue
<< 16);
179 static int carmine_check_var(struct fb_var_screeninfo
*var
,
180 struct fb_info
*info
)
184 ret
= carmine_find_mode(var
);
188 if (var
->grayscale
|| var
->rotate
|| var
->nonstd
)
191 var
->xres_virtual
= var
->xres
;
192 var
->yres_virtual
= var
->yres
;
194 var
->bits_per_pixel
= 32;
197 var
->transp
.offset
= 24;
199 var
->green
.offset
= 8;
200 var
->blue
.offset
= 16;
202 var
->transp
.offset
= 24;
203 var
->red
.offset
= 16;
204 var
->green
.offset
= 8;
205 var
->blue
.offset
= 0;
209 var
->green
.length
= 8;
210 var
->blue
.length
= 8;
211 var
->transp
.length
= 8;
213 var
->red
.msb_right
= 0;
214 var
->green
.msb_right
= 0;
215 var
->blue
.msb_right
= 0;
216 var
->transp
.msb_right
= 0;
220 static void carmine_init_display_param(struct carmine_fb
*par
)
226 u32 soffset
= par
->smem_offset
;
228 c_set_disp_reg(par
, CARMINE_DISP_REG_C_TRANS
, 0);
229 c_set_disp_reg(par
, CARMINE_DISP_REG_MLMR_TRANS
, 0);
230 c_set_disp_reg(par
, CARMINE_DISP_REG_CURSOR_MODE
,
231 CARMINE_CURSOR0_PRIORITY_MASK
|
232 CARMINE_CURSOR1_PRIORITY_MASK
|
233 CARMINE_CURSOR_CUTZ_MASK
);
235 /* Set default cursor position */
236 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR1_POS
, 0 << 16 | 0);
237 c_set_disp_reg(par
, CARMINE_DISP_REG_CUR2_POS
, 0 << 16 | 0);
239 /* Set default display mode */
240 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_EXT_MODE
, CARMINE_WINDOW_MODE
|
241 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
242 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_EXT_MODE
,
243 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
244 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_EXT_MODE
, CARMINE_EXTEND_MODE
|
245 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
246 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_EXT_MODE
, CARMINE_EXTEND_MODE
|
247 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
248 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_EXT_MODE
, CARMINE_EXTEND_MODE
|
249 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
250 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_EXT_MODE
, CARMINE_EXTEND_MODE
|
251 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
252 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_EXT_MODE
, CARMINE_EXTEND_MODE
|
253 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
254 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_EXT_MODE
, CARMINE_EXTEND_MODE
|
255 CARMINE_EXT_CMODE_DIRECT24_RGBA
);
257 /* Set default frame size to layer mode register */
258 width
= par
->res
->hdp
* 4 / CARMINE_DISP_WIDTH_UNIT
;
259 width
= width
<< CARMINE_DISP_WIDTH_SHIFT
;
261 height
= par
->res
->vdp
- 1;
262 param
= width
| height
;
264 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_MODE_W_H
, param
);
265 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIDTH
, width
);
266 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_MODE_W_H
, param
);
267 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_MODE_W_H
, param
);
268 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_MODE_W_H
, param
);
269 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_MODE_W_H
, param
);
270 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_MODE_W_H
, param
);
271 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_MODE_W_H
, param
);
273 /* Set default pos and size */
274 window_size
= (par
->res
->vdp
- 1) << CARMINE_DISP_WIN_H_SHIFT
;
275 window_size
|= par
->res
->hdp
;
277 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_POS
, 0);
278 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_WIN_SIZE
, window_size
);
279 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_POS
, 0);
280 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_WIN_SIZE
, window_size
);
281 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_POS
, 0);
282 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_WIN_SIZE
, window_size
);
283 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_POS
, 0);
284 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_WIN_SIZE
, window_size
);
285 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_POS
, 0);
286 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_WIN_SIZE
, window_size
);
287 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_POS
, 0);
288 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_WIN_SIZE
, window_size
);
289 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_POS
, 0);
290 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_WIN_SIZE
, window_size
);
291 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_POS
, 0);
292 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_WIN_SIZE
, window_size
);
294 /* Set default origin address */
295 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_ORG_ADR
, soffset
);
296 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_ORG_ADR
, soffset
);
297 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_ORG_ADR1
, soffset
);
298 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_ORG_ADR1
, soffset
);
299 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_ORG_ADR1
, soffset
);
300 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_ORG_ADR1
, soffset
);
301 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_ORG_ADR1
, soffset
);
302 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_ORG_ADR1
, soffset
);
304 /* Set default display address */
305 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_ADR
, soffset
);
306 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_ADR1
, soffset
);
307 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_ADR1
, soffset
);
308 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_ADR1
, soffset
);
309 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_ADR1
, soffset
);
310 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_ADR0
, soffset
);
311 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_ADR0
, soffset
);
313 /* Set default display position */
314 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_DISP_POS
, 0);
315 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_DISP_POS
, 0);
316 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_DISP_POS
, 0);
317 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_DISP_POS
, 0);
318 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_DISP_POS
, 0);
319 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_DISP_POS
, 0);
320 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_DISP_POS
, 0);
322 /* Set default blend mode */
323 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L0
, 0);
324 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L1
, 0);
325 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L2
, 0);
326 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L3
, 0);
327 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L4
, 0);
328 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L5
, 0);
329 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L6
, 0);
330 c_set_disp_reg(par
, CARMINE_DISP_REG_BLEND_MODE_L7
, 0);
332 /* default transparency mode */
333 c_set_disp_reg(par
, CARMINE_DISP_REG_L0_TRANS
, 0);
334 c_set_disp_reg(par
, CARMINE_DISP_REG_L1_TRANS
, 0);
335 c_set_disp_reg(par
, CARMINE_DISP_REG_L2_TRANS
, 0);
336 c_set_disp_reg(par
, CARMINE_DISP_REG_L3_TRANS
, 0);
337 c_set_disp_reg(par
, CARMINE_DISP_REG_L4_TRANS
, 0);
338 c_set_disp_reg(par
, CARMINE_DISP_REG_L5_TRANS
, 0);
339 c_set_disp_reg(par
, CARMINE_DISP_REG_L6_TRANS
, 0);
340 c_set_disp_reg(par
, CARMINE_DISP_REG_L7_TRANS
, 0);
342 /* Set default read skip parameter */
343 c_set_disp_reg(par
, CARMINE_DISP_REG_L0RM
, 0);
344 c_set_disp_reg(par
, CARMINE_DISP_REG_L2RM
, 0);
345 c_set_disp_reg(par
, CARMINE_DISP_REG_L3RM
, 0);
346 c_set_disp_reg(par
, CARMINE_DISP_REG_L4RM
, 0);
347 c_set_disp_reg(par
, CARMINE_DISP_REG_L5RM
, 0);
348 c_set_disp_reg(par
, CARMINE_DISP_REG_L6RM
, 0);
349 c_set_disp_reg(par
, CARMINE_DISP_REG_L7RM
, 0);
351 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PX
, 0);
352 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PX
, 0);
353 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PX
, 0);
354 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PX
, 0);
355 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PX
, 0);
356 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PX
, 0);
357 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PX
, 0);
359 c_set_disp_reg(par
, CARMINE_DISP_REG_L0PY
, 0);
360 c_set_disp_reg(par
, CARMINE_DISP_REG_L2PY
, 0);
361 c_set_disp_reg(par
, CARMINE_DISP_REG_L3PY
, 0);
362 c_set_disp_reg(par
, CARMINE_DISP_REG_L4PY
, 0);
363 c_set_disp_reg(par
, CARMINE_DISP_REG_L5PY
, 0);
364 c_set_disp_reg(par
, CARMINE_DISP_REG_L6PY
, 0);
365 c_set_disp_reg(par
, CARMINE_DISP_REG_L7PY
, 0);
368 static void set_display_parameters(struct carmine_fb
*par
)
371 u32 hdp
, vdp
, htp
, hsp
, hsw
, vtr
, vsp
, vsw
;
374 * display timing. Parameters are decreased by one because hardware
375 * spec is 0 to (n - 1)
377 hdp
= par
->res
->hdp
- 1;
378 vdp
= par
->res
->vdp
- 1;
379 htp
= par
->res
->htp
- 1;
380 hsp
= par
->res
->hsp
- 1;
381 hsw
= par
->res
->hsw
- 1;
382 vtr
= par
->res
->vtr
- 1;
383 vsp
= par
->res
->vsp
- 1;
384 vsw
= par
->res
->vsw
- 1;
386 c_set_disp_reg(par
, CARMINE_DISP_REG_H_TOTAL
,
387 htp
<< CARMINE_DISP_HTP_SHIFT
);
388 c_set_disp_reg(par
, CARMINE_DISP_REG_H_PERIOD
,
389 (hdp
<< CARMINE_DISP_HDB_SHIFT
) | hdp
);
390 c_set_disp_reg(par
, CARMINE_DISP_REG_V_H_W_H_POS
,
391 (vsw
<< CARMINE_DISP_VSW_SHIFT
) |
392 (hsw
<< CARMINE_DISP_HSW_SHIFT
) |
394 c_set_disp_reg(par
, CARMINE_DISP_REG_V_TOTAL
,
395 vtr
<< CARMINE_DISP_VTR_SHIFT
);
396 c_set_disp_reg(par
, CARMINE_DISP_REG_V_PERIOD_POS
,
397 (vdp
<< CARMINE_DISP_VDP_SHIFT
) | vsp
);
400 mode
= c_get_disp_reg(par
, CARMINE_DISP_REG_DCM1
);
401 mode
= (mode
& ~CARMINE_DISP_DCM_MASK
) |
402 (par
->res
->disp_mode
& CARMINE_DISP_DCM_MASK
);
403 /* enable video output and layer 0 */
404 mode
|= CARMINE_DEN
| CARMINE_L0E
;
405 c_set_disp_reg(par
, CARMINE_DISP_REG_DCM1
, mode
);
408 static int carmine_set_par(struct fb_info
*info
)
410 struct carmine_fb
*par
= info
->par
;
413 ret
= carmine_find_mode(&info
->var
);
418 if (par
->cur_mode
!= par
->new_mode
) {
420 par
->cur_mode
= par
->new_mode
;
421 par
->res
= &car_modes
[par
->new_mode
];
423 carmine_init_display_param(par
);
424 set_display_parameters(par
);
427 info
->fix
.line_length
= info
->var
.xres
* info
->var
.bits_per_pixel
/ 8;
431 static int init_hardware(struct carmine_hw
*hw
)
437 /* Initialize Carmine */
438 /* Sets internal clock */
439 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_CLOCK_ENABLE
,
440 CARMINE_DFLT_IP_CLOCK_ENABLE
);
442 /* Video signal output is turned off */
443 c_set_hw_reg(hw
, CARMINE_DISP0_REG
+ CARMINE_DISP_REG_DCM1
, 0);
444 c_set_hw_reg(hw
, CARMINE_DISP1_REG
+ CARMINE_DISP_REG_DCM1
, 0);
447 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 1);
448 c_set_hw_reg(hw
, CARMINE_CTL_REG
+ CARMINE_CTL_REG_SOFTWARE_RESET
, 0);
450 /* I/O mode settings */
451 flags
= CARMINE_DFLT_IP_DCTL_IO_CONT1
<< 16 |
452 CARMINE_DFLT_IP_DCTL_IO_CONT0
;
453 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_IOCONT1_IOCONT0
,
456 /* DRAM initial sequence */
457 flags
= CARMINE_DFLT_IP_DCTL_MODE
<< 16 | CARMINE_DFLT_IP_DCTL_ADD
;
458 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
,
461 flags
= CARMINE_DFLT_IP_DCTL_SET_TIME1
<< 16 |
462 CARMINE_DFLT_IP_DCTL_EMODE
;
463 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_SETTIME1_EMODE
,
466 flags
= CARMINE_DFLT_IP_DCTL_REFRESH
<< 16 |
467 CARMINE_DFLT_IP_DCTL_SET_TIME2
;
468 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_REFRESH_SETTIME2
,
471 flags
= CARMINE_DFLT_IP_DCTL_RESERVE2
<< 16 |
472 CARMINE_DFLT_IP_DCTL_FIFO_DEPTH
;
473 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV2_RSV1
, flags
);
475 flags
= CARMINE_DFLT_IP_DCTL_DDRIF2
<< 16 | CARMINE_DFLT_IP_DCTL_DDRIF1
;
476 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_DDRIF2_DDRIF1
,
479 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
480 CARMINE_DFLT_IP_DCTL_STATES
;
481 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
484 /* Executes DLL reset */
485 if (CARMINE_DCTL_DLL_RESET
) {
486 for (loops
= 0; loops
< CARMINE_DCTL_INIT_WAIT_LIMIT
; loops
++) {
488 ret
= c_get_hw_reg(hw
, CARMINE_DCTL_REG
+
489 CARMINE_DCTL_REG_RSV0_STATES
);
490 ret
&= CARMINE_DCTL_REG_STATES_MASK
;
494 mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL
);
497 if (loops
>= CARMINE_DCTL_INIT_WAIT_LIMIT
) {
498 printk(KERN_ERR
"DRAM init failed\n");
503 flags
= CARMINE_DFLT_IP_DCTL_MODE_AFT_RST
<< 16 |
504 CARMINE_DFLT_IP_DCTL_ADD
;
505 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_MODE_ADD
, flags
);
507 flags
= CARMINE_DFLT_IP_DCTL_RESERVE0
<< 16 |
508 CARMINE_DFLT_IP_DCTL_STATES_AFT_RST
;
509 c_set_hw_reg(hw
, CARMINE_DCTL_REG
+ CARMINE_DCTL_REG_RSV0_STATES
,
512 /* Initialize the write back register */
513 c_set_hw_reg(hw
, CARMINE_WB_REG
+ CARMINE_WB_REG_WBM
,
514 CARMINE_WB_REG_WBM_DEFAULT
);
516 /* Initialize the Kottos registers */
517 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRINTM
, 0);
518 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_VRERRM
, 0);
521 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PX
, 0);
522 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_PY
, 0);
523 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LX
, 0);
524 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_LY
, 0);
525 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TX
, 0);
526 c_set_hw_reg(hw
, CARMINE_GRAPH_REG
+ CARMINE_GRAPH_REG_DC_OFFSET_TY
, 0);
530 static const struct fb_ops carminefb_ops
= {
531 .owner
= THIS_MODULE
,
532 .fb_fillrect
= cfb_fillrect
,
533 .fb_copyarea
= cfb_copyarea
,
534 .fb_imageblit
= cfb_imageblit
,
536 .fb_check_var
= carmine_check_var
,
537 .fb_set_par
= carmine_set_par
,
538 .fb_setcolreg
= carmine_setcolreg
,
541 static int alloc_carmine_fb(void __iomem
*regs
, void __iomem
*smem_base
,
542 int smem_offset
, struct device
*device
,
543 struct fb_info
**rinfo
)
546 struct fb_info
*info
;
547 struct carmine_fb
*par
;
549 info
= framebuffer_alloc(sizeof *par
, device
);
554 par
->display_reg
= regs
;
555 par
->smem_offset
= smem_offset
;
557 info
->screen_base
= smem_base
+ smem_offset
;
558 info
->screen_size
= CARMINE_DISPLAY_MEM
;
559 info
->fbops
= &carminefb_ops
;
561 info
->fix
= carminefb_fix
;
562 info
->pseudo_palette
= par
->pseudo_palette
;
563 info
->flags
= FBINFO_DEFAULT
;
565 ret
= fb_alloc_cmap(&info
->cmap
, 256, 1);
569 if (fb_mode
>= ARRAY_SIZE(carmine_modedb
))
570 fb_mode
= CARMINEFB_DEFAULT_VIDEO_MODE
;
572 par
->cur_mode
= par
->new_mode
= ~0;
574 ret
= fb_find_mode(&info
->var
, info
, fb_mode_str
, carmine_modedb
,
575 ARRAY_SIZE(carmine_modedb
),
576 &carmine_modedb
[fb_mode
], 32);
577 if (!ret
|| ret
== 4) {
579 goto err_dealloc_cmap
;
582 fb_videomode_to_modelist(carmine_modedb
, ARRAY_SIZE(carmine_modedb
),
585 ret
= register_framebuffer(info
);
587 goto err_dealloc_cmap
;
589 fb_info(info
, "%s frame buffer device\n", info
->fix
.id
);
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(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(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_disable_device(dev
);
753 #define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
754 static struct pci_device_id carmine_devices
[] = {
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
= 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");