1 /* sunxvr1000.c: Sun XVR-1000 driver for sparc64 systems
3 * Copyright (C) 2010 David S. Miller (davem@davemloft.net)
6 #include <linux/module.h>
7 #include <linux/kernel.h>
9 #include <linux/init.h>
10 #include <linux/of_device.h>
15 char __iomem
*fb_base
;
16 unsigned long fb_base_phys
;
18 struct device_node
*of_node
;
25 u32 pseudo_palette
[16];
28 static int gfb_get_props(struct gfb_info
*gp
)
30 gp
->width
= of_getintprop_default(gp
->of_node
, "width", 0);
31 gp
->height
= of_getintprop_default(gp
->of_node
, "height", 0);
32 gp
->depth
= of_getintprop_default(gp
->of_node
, "depth", 32);
34 if (!gp
->width
|| !gp
->height
) {
35 printk(KERN_ERR
"gfb: Critical properties missing for %s\n",
36 gp
->of_node
->full_name
);
43 static int gfb_setcolreg(unsigned regno
,
44 unsigned red
, unsigned green
, unsigned blue
,
45 unsigned transp
, struct fb_info
*info
)
54 value
= (blue
<< 16) | (green
<< 8) | red
;
55 ((u32
*)info
->pseudo_palette
)[regno
] = value
;
61 static struct fb_ops gfb_ops
= {
63 .fb_setcolreg
= gfb_setcolreg
,
64 .fb_fillrect
= cfb_fillrect
,
65 .fb_copyarea
= cfb_copyarea
,
66 .fb_imageblit
= cfb_imageblit
,
69 static int gfb_set_fbinfo(struct gfb_info
*gp
)
71 struct fb_info
*info
= gp
->info
;
72 struct fb_var_screeninfo
*var
= &info
->var
;
74 info
->flags
= FBINFO_DEFAULT
;
75 info
->fbops
= &gfb_ops
;
76 info
->screen_base
= gp
->fb_base
;
77 info
->screen_size
= gp
->fb_size
;
79 info
->pseudo_palette
= gp
->pseudo_palette
;
81 /* Fill fix common fields */
82 strlcpy(info
->fix
.id
, "gfb", sizeof(info
->fix
.id
));
83 info
->fix
.smem_start
= gp
->fb_base_phys
;
84 info
->fix
.smem_len
= gp
->fb_size
;
85 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
86 if (gp
->depth
== 32 || gp
->depth
== 24)
87 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
89 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
91 var
->xres
= gp
->width
;
92 var
->yres
= gp
->height
;
93 var
->xres_virtual
= var
->xres
;
94 var
->yres_virtual
= var
->yres
;
95 var
->bits_per_pixel
= gp
->depth
;
99 var
->green
.offset
= 8;
100 var
->green
.length
= 8;
101 var
->blue
.offset
= 16;
102 var
->blue
.length
= 8;
103 var
->transp
.offset
= 0;
104 var
->transp
.length
= 0;
106 if (fb_alloc_cmap(&info
->cmap
, 256, 0)) {
107 printk(KERN_ERR
"gfb: Cannot allocate color map.\n");
114 static int gfb_probe(struct platform_device
*op
)
116 struct device_node
*dp
= op
->dev
.of_node
;
117 struct fb_info
*info
;
121 info
= framebuffer_alloc(sizeof(struct gfb_info
), &op
->dev
);
123 printk(KERN_ERR
"gfb: Cannot allocate fb_info\n");
132 gp
->fb_base_phys
= op
->resource
[6].start
;
134 err
= gfb_get_props(gp
);
138 /* Framebuffer length is the same regardless of resolution. */
139 info
->fix
.line_length
= 16384;
140 gp
->fb_size
= info
->fix
.line_length
* gp
->height
;
142 gp
->fb_base
= of_ioremap(&op
->resource
[6], 0,
143 gp
->fb_size
, "gfb fb");
149 err
= gfb_set_fbinfo(gp
);
153 printk("gfb: Found device at %s\n", dp
->full_name
);
155 err
= register_framebuffer(info
);
157 printk(KERN_ERR
"gfb: Could not register framebuffer %s\n",
162 dev_set_drvdata(&op
->dev
, info
);
167 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
170 framebuffer_release(info
);
176 static int gfb_remove(struct platform_device
*op
)
178 struct fb_info
*info
= dev_get_drvdata(&op
->dev
);
179 struct gfb_info
*gp
= info
->par
;
181 unregister_framebuffer(info
);
183 iounmap(gp
->fb_base
);
185 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
187 framebuffer_release(info
);
192 static const struct of_device_id gfb_match
[] = {
198 MODULE_DEVICE_TABLE(of
, ffb_match
);
200 static struct platform_driver gfb_driver
= {
202 .remove
= gfb_remove
,
205 .owner
= THIS_MODULE
,
206 .of_match_table
= gfb_match
,
210 static int __init
gfb_init(void)
212 if (fb_get_options("gfb", NULL
))
215 return platform_driver_register(&gfb_driver
);
218 static void __exit
gfb_exit(void)
220 platform_driver_unregister(&gfb_driver
);
223 module_init(gfb_init
);
224 module_exit(gfb_exit
);
226 MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
227 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
228 MODULE_VERSION("1.0");
229 MODULE_LICENSE("GPL");