21 #include <linux/module.h>
23 #include <linux/slab.h>
30 #define EP93XXFB_VLINES_TOTAL 0x0000
31 #define EP93XXFB_VSYNC 0x0004
32 #define EP93XXFB_VACTIVE 0x0008
33 #define EP93XXFB_VBLANK 0x0228
34 #define EP93XXFB_VCLK 0x000c
37 #define EP93XXFB_HCLKS_TOTAL 0x0010
38 #define EP93XXFB_HSYNC 0x0014
39 #define EP93XXFB_HACTIVE 0x0018
40 #define EP93XXFB_HBLANK 0x022c
41 #define EP93XXFB_HCLK 0x001c
44 #define EP93XXFB_SCREEN_PAGE 0x0028
45 #define EP93XXFB_SCREEN_HPAGE 0x002c
46 #define EP93XXFB_SCREEN_LINES 0x0030
47 #define EP93XXFB_LINE_LENGTH 0x0034
48 #define EP93XXFB_VLINE_STEP 0x0038
49 #define EP93XXFB_LINE_CARRY 0x003c
50 #define EP93XXFB_EOL_OFFSET 0x0230
53 #define EP93XXFB_BRIGHTNESS 0x0020
54 #define EP93XXFB_ATTRIBS 0x0024
55 #define EP93XXFB_SWLOCK 0x007c
56 #define EP93XXFB_AC_RATE 0x0214
57 #define EP93XXFB_FIFO_LEVEL 0x0234
58 #define EP93XXFB_PIXELMODE 0x0054
59 #define EP93XXFB_PIXELMODE_32BPP (0x7 << 0)
60 #define EP93XXFB_PIXELMODE_24BPP (0x6 << 0)
61 #define EP93XXFB_PIXELMODE_16BPP (0x4 << 0)
62 #define EP93XXFB_PIXELMODE_8BPP (0x2 << 0)
63 #define EP93XXFB_PIXELMODE_SHIFT_1P_24B (0x0 << 3)
64 #define EP93XXFB_PIXELMODE_SHIFT_1P_18B (0x1 << 3)
65 #define EP93XXFB_PIXELMODE_COLOR_LUT (0x0 << 10)
66 #define EP93XXFB_PIXELMODE_COLOR_888 (0x4 << 10)
67 #define EP93XXFB_PIXELMODE_COLOR_555 (0x5 << 10)
68 #define EP93XXFB_PARL_IF_OUT 0x0058
69 #define EP93XXFB_PARL_IF_IN 0x005c
72 #define EP93XXFB_BLINK_RATE 0x0040
73 #define EP93XXFB_BLINK_MASK 0x0044
74 #define EP93XXFB_BLINK_PATTRN 0x0048
75 #define EP93XXFB_PATTRN_MASK 0x004c
76 #define EP93XXFB_BKGRND_OFFSET 0x0050
79 #define EP93XXFB_CURSOR_ADR_START 0x0060
80 #define EP93XXFB_CURSOR_ADR_RESET 0x0064
81 #define EP93XXFB_CURSOR_SIZE 0x0068
82 #define EP93XXFB_CURSOR_COLOR1 0x006c
83 #define EP93XXFB_CURSOR_COLOR2 0x0070
84 #define EP93XXFB_CURSOR_BLINK_COLOR1 0x021c
85 #define EP93XXFB_CURSOR_BLINK_COLOR2 0x0220
86 #define EP93XXFB_CURSOR_XY_LOC 0x0074
87 #define EP93XXFB_CURSOR_DSCAN_HY_LOC 0x0078
88 #define EP93XXFB_CURSOR_BLINK_RATE_CTRL 0x0224
91 #define EP93XXFB_GRY_SCL_LUTR 0x0080
92 #define EP93XXFB_GRY_SCL_LUTG 0x0280
93 #define EP93XXFB_GRY_SCL_LUTB 0x0300
94 #define EP93XXFB_LUT_SW_CONTROL 0x0218
95 #define EP93XXFB_LUT_SW_CONTROL_SWTCH (1 << 0)
96 #define EP93XXFB_LUT_SW_CONTROL_SSTAT (1 << 1)
97 #define EP93XXFB_COLOR_LUT 0x0400
100 #define EP93XXFB_VID_SIG_RSLT_VAL 0x0200
101 #define EP93XXFB_VID_SIG_CTRL 0x0204
102 #define EP93XXFB_VSIG 0x0208
103 #define EP93XXFB_HSIG 0x020c
104 #define EP93XXFB_SIG_CLR_STR 0x0210
107 #define EP93XXFB_MIN_XRES 64
108 #define EP93XXFB_MIN_YRES 64
109 #define EP93XXFB_MAX_XRES 1024
110 #define EP93XXFB_MAX_YRES 768
120 static int check_screenpage_bug = 1;
123 "Check for bit 27 screen page bug. Default = 1");
125 static inline unsigned int ep93xxfb_readl(
struct ep93xx_fbi *fbi,
131 static inline void ep93xxfb_writel(
struct ep93xx_fbi *fbi,
132 unsigned int val,
unsigned int off)
140 static inline void ep93xxfb_out_locked(
struct ep93xx_fbi *fbi,
141 unsigned int val,
unsigned int reg)
148 ep93xxfb_writel(fbi, val, reg);
151 static void ep93xxfb_set_video_attribs(
struct fb_info *
info)
154 unsigned int attribs;
161 static int ep93xxfb_set_pixelmode(
struct fb_info *
info)
166 info->
var.transp.offset = 0;
167 info->
var.transp.length = 0;
169 switch (info->
var.bits_per_pixel) {
174 info->
var.red.offset = 0;
175 info->
var.red.length = 8;
176 info->
var.green.offset = 0;
177 info->
var.green.length = 8;
178 info->
var.blue.offset = 0;
179 info->
var.blue.length = 8;
187 info->
var.red.offset = 11;
188 info->
var.red.length = 5;
189 info->
var.green.offset = 5;
190 info->
var.green.length = 6;
191 info->
var.blue.offset = 0;
192 info->
var.blue.length = 5;
200 info->
var.red.offset = 16;
201 info->
var.red.length = 8;
202 info->
var.green.offset = 8;
203 info->
var.green.length = 8;
204 info->
var.blue.offset = 0;
205 info->
var.blue.length = 8;
213 info->
var.red.offset = 16;
214 info->
var.red.length = 8;
215 info->
var.green.offset = 8;
216 info->
var.green.length = 8;
217 info->
var.blue.offset = 0;
218 info->
var.blue.length = 8;
230 static void ep93xxfb_set_timing(
struct fb_info *info)
233 unsigned int vlines_total, hclks_total,
start,
stop;
235 vlines_total = info->
var.yres + info->
var.upper_margin +
236 info->
var.lower_margin + info->
var.vsync_len - 1;
238 hclks_total = info->
var.xres + info->
var.left_margin +
239 info->
var.right_margin + info->
var.hsync_len - 1;
244 start = vlines_total;
245 stop = vlines_total - info->
var.vsync_len;
248 start = vlines_total - info->
var.vsync_len - info->
var.upper_margin;
249 stop = info->
var.lower_margin - 1;
253 start = vlines_total;
254 stop = vlines_total + 1;
255 ep93xxfb_out_locked(fbi, start | (stop << 16),
EP93XXFB_VCLK);
258 stop = hclks_total - info->
var.hsync_len;
261 start = hclks_total - info->
var.hsync_len - info->
var.left_margin;
262 stop = info->
var.right_margin - 1;
268 ep93xxfb_out_locked(fbi, start | (stop << 16),
EP93XXFB_HCLK);
273 static int ep93xxfb_set_par(
struct fb_info *info)
279 ep93xxfb_set_timing(info);
281 info->
fix.line_length = info->
var.xres_virtual *
282 info->
var.bits_per_pixel / 8;
286 ep93xxfb_writel(fbi, ((info->
var.xres * info->
var.bits_per_pixel)
289 ep93xxfb_set_video_attribs(info);
298 err = ep93xxfb_set_pixelmode(info);
319 info->
fix.smem_start,
326 static int ep93xxfb_blank(
int blank_mode,
struct fb_info *info)
348 static inline int ep93xxfb_convert_color(
int val,
int width)
350 return ((val << width) + 0x7fff - val) >> 16;
353 static int ep93xxfb_setcolreg(
unsigned int regno,
unsigned int red,
359 unsigned int ctrl,
i, rgb, lut_current, lut_stat;
361 switch (info->
fix.visual) {
365 rgb = ((red & 0xff00) << 8) | (green & 0xff00) |
366 ((blue & 0xff00) >> 8);
374 if (lut_stat == lut_current) {
375 for (i = 0; i < 256; i++) {
376 ep93xxfb_writel(fbi, pal[i],
390 red = ep93xxfb_convert_color(red, info->
var.red.length);
391 green = ep93xxfb_convert_color(green, info->
var.green.length);
392 blue = ep93xxfb_convert_color(blue, info->
var.blue.length);
393 transp = ep93xxfb_convert_color(transp,
394 info->
var.transp.length);
396 pal[regno] = (red << info->
var.red.offset) |
397 (green << info->
var.green.offset) |
398 (blue << info->
var.blue.offset) |
399 (transp << info->
var.transp.offset);
409 static struct fb_ops ep93xxfb_ops = {
411 .fb_check_var = ep93xxfb_check_var,
412 .fb_set_par = ep93xxfb_set_par,
413 .fb_blank = ep93xxfb_blank,
417 .fb_setcolreg = ep93xxfb_setcolreg,
418 .fb_mmap = ep93xxfb_mmap,
429 for (i = 0; i < mach_info->
num_modes; i++) {
433 mode = &mach_info->
modes[
i];
434 size = mode->
xres * mode->
yres * mach_info->
bpp / 8;
443 static int __init ep93xxfb_alloc_videomem(
struct fb_info *info)
448 unsigned int fb_size;
450 fb_size = ep93xxfb_calc_fbsize(fbi->
mach_info);
464 if (check_screenpage_bug && phys_addr & (1 << 27)) {
465 dev_err(info->
dev,
"ep93xx framebuffer bug. phys addr (0x%x) "
466 "has bit 27 set: cannot init framebuffer\n",
474 info->
fix.smem_len = fb_size;
480 static void ep93xxfb_dealloc_videomem(
struct fb_info *info)
504 platform_set_drvdata(pdev, info);
512 err = ep93xxfb_alloc_videomem(info);
514 goto failed_videomem;
519 goto failed_resource;
536 goto failed_resource;
540 info->
fbops = &ep93xxfb_ops;
555 dev_err(info->
dev,
"No suitable video mode found\n");
557 goto failed_resource;
560 if (mach_info->
setup) {
561 err = mach_info->
setup(pdev);
563 goto failed_resource;
566 err = ep93xxfb_check_var(&info->
var, info);
571 if (IS_ERR(fbi->
clk)) {
572 err = PTR_ERR(fbi->
clk);
577 ep93xxfb_set_par(info);
584 dev_info(info->
dev,
"registered. Mode = %dx%d-%d\n",
585 info->
var.xres, info->
var.yres, info->
var.bits_per_pixel);
592 ep93xxfb_dealloc_videomem(info);
597 platform_set_drvdata(pdev,
NULL);
604 struct fb_info *info = platform_get_drvdata(pdev);
609 ep93xxfb_dealloc_videomem(info);
616 platform_set_drvdata(pdev,
NULL);
622 .probe = ep93xxfb_probe,
635 static void __exit ep93xxfb_exit(
void)