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>
8 #include <linux/slab.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 __devinit
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 __devinit
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 __devinit
gfb_probe(struct of_device
*op
,
116 const struct of_device_id
*match
)
118 struct device_node
*dp
= op
->node
;
119 struct fb_info
*info
;
123 info
= framebuffer_alloc(sizeof(struct gfb_info
), &op
->dev
);
125 printk(KERN_ERR
"gfb: Cannot allocate fb_info\n");
134 gp
->fb_base_phys
= op
->resource
[6].start
;
136 err
= gfb_get_props(gp
);
140 /* Framebuffer length is the same regardless of resolution. */
141 info
->fix
.line_length
= 16384;
142 gp
->fb_size
= info
->fix
.line_length
* gp
->height
;
144 gp
->fb_base
= of_ioremap(&op
->resource
[6], 0,
145 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 __devexit
gfb_remove(struct of_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
);
189 dev_set_drvdata(&op
->dev
, NULL
);
194 static const struct of_device_id gfb_match
[] = {
200 MODULE_DEVICE_TABLE(of
, ffb_match
);
202 static struct of_platform_driver gfb_driver
= {
204 .match_table
= gfb_match
,
206 .remove
= __devexit_p(gfb_remove
),
209 static int __init
gfb_init(void)
211 if (fb_get_options("gfb", NULL
))
214 return of_register_driver(&gfb_driver
, &of_bus_type
);
217 static void __exit
gfb_exit(void)
219 of_unregister_driver(&gfb_driver
);
222 module_init(gfb_init
);
223 module_exit(gfb_exit
);
225 MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
226 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
227 MODULE_VERSION("1.0");
228 MODULE_LICENSE("GPL");