1 /* sunxvr1000.c: Sun XVR-1000 fb driver for sparc64 systems
5 * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
8 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/of_device.h>
16 char __iomem
*fb_base
;
17 unsigned long fb_base_phys
;
19 struct device_node
*of_node
;
26 u32 pseudo_palette
[16];
29 static int gfb_get_props(struct gfb_info
*gp
)
31 gp
->width
= of_getintprop_default(gp
->of_node
, "width", 0);
32 gp
->height
= of_getintprop_default(gp
->of_node
, "height", 0);
33 gp
->depth
= of_getintprop_default(gp
->of_node
, "depth", 32);
35 if (!gp
->width
|| !gp
->height
) {
36 printk(KERN_ERR
"gfb: Critical properties missing for %s\n",
37 gp
->of_node
->full_name
);
44 static int gfb_setcolreg(unsigned regno
,
45 unsigned red
, unsigned green
, unsigned blue
,
46 unsigned transp
, struct fb_info
*info
)
55 value
= (blue
<< 16) | (green
<< 8) | red
;
56 ((u32
*)info
->pseudo_palette
)[regno
] = value
;
62 static struct fb_ops gfb_ops
= {
64 .fb_setcolreg
= gfb_setcolreg
,
65 .fb_fillrect
= cfb_fillrect
,
66 .fb_copyarea
= cfb_copyarea
,
67 .fb_imageblit
= cfb_imageblit
,
70 static int gfb_set_fbinfo(struct gfb_info
*gp
)
72 struct fb_info
*info
= gp
->info
;
73 struct fb_var_screeninfo
*var
= &info
->var
;
75 info
->flags
= FBINFO_DEFAULT
;
76 info
->fbops
= &gfb_ops
;
77 info
->screen_base
= gp
->fb_base
;
78 info
->screen_size
= gp
->fb_size
;
80 info
->pseudo_palette
= gp
->pseudo_palette
;
82 /* Fill fix common fields */
83 strlcpy(info
->fix
.id
, "gfb", sizeof(info
->fix
.id
));
84 info
->fix
.smem_start
= gp
->fb_base_phys
;
85 info
->fix
.smem_len
= gp
->fb_size
;
86 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
87 if (gp
->depth
== 32 || gp
->depth
== 24)
88 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
90 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
92 var
->xres
= gp
->width
;
93 var
->yres
= gp
->height
;
94 var
->xres_virtual
= var
->xres
;
95 var
->yres_virtual
= var
->yres
;
96 var
->bits_per_pixel
= gp
->depth
;
100 var
->green
.offset
= 8;
101 var
->green
.length
= 8;
102 var
->blue
.offset
= 16;
103 var
->blue
.length
= 8;
104 var
->transp
.offset
= 0;
105 var
->transp
.length
= 0;
107 if (fb_alloc_cmap(&info
->cmap
, 256, 0)) {
108 printk(KERN_ERR
"gfb: Cannot allocate color map.\n");
115 static int gfb_probe(struct platform_device
*op
)
117 struct device_node
*dp
= op
->dev
.of_node
;
118 struct fb_info
*info
;
122 info
= framebuffer_alloc(sizeof(struct gfb_info
), &op
->dev
);
124 printk(KERN_ERR
"gfb: Cannot allocate fb_info\n");
133 gp
->fb_base_phys
= op
->resource
[6].start
;
135 err
= gfb_get_props(gp
);
139 /* Framebuffer length is the same regardless of resolution. */
140 info
->fix
.line_length
= 16384;
141 gp
->fb_size
= info
->fix
.line_length
* gp
->height
;
143 gp
->fb_base
= of_ioremap(&op
->resource
[6], 0,
144 gp
->fb_size
, "gfb fb");
150 err
= gfb_set_fbinfo(gp
);
154 printk("gfb: Found device at %s\n", dp
->full_name
);
156 err
= register_framebuffer(info
);
158 printk(KERN_ERR
"gfb: Could not register framebuffer %s\n",
163 dev_set_drvdata(&op
->dev
, info
);
168 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
171 framebuffer_release(info
);
177 static const struct of_device_id gfb_match
[] = {
184 static struct platform_driver gfb_driver
= {
188 .of_match_table
= gfb_match
,
189 .suppress_bind_attrs
= true,
193 static int __init
gfb_init(void)
195 if (fb_get_options("gfb", NULL
))
198 return platform_driver_register(&gfb_driver
);
200 device_initcall(gfb_init
);