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 __devinit
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 __devinit
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 __devinit
gfb_probe(struct platform_device
*op
,
115 const struct of_device_id
*match
)
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");
148 err
= gfb_set_fbinfo(gp
);
152 printk("gfb: Found device at %s\n", dp
->full_name
);
154 err
= register_framebuffer(info
);
156 printk(KERN_ERR
"gfb: Could not register framebuffer %s\n",
161 dev_set_drvdata(&op
->dev
, info
);
166 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
169 framebuffer_release(info
);
175 static int __devexit
gfb_remove(struct platform_device
*op
)
177 struct fb_info
*info
= dev_get_drvdata(&op
->dev
);
178 struct gfb_info
*gp
= info
->par
;
180 unregister_framebuffer(info
);
182 iounmap(gp
->fb_base
);
184 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
186 framebuffer_release(info
);
188 dev_set_drvdata(&op
->dev
, NULL
);
193 static const struct of_device_id gfb_match
[] = {
199 MODULE_DEVICE_TABLE(of
, ffb_match
);
201 static struct of_platform_driver gfb_driver
= {
203 .remove
= __devexit_p(gfb_remove
),
206 .owner
= THIS_MODULE
,
207 .of_match_table
= gfb_match
,
211 static int __init
gfb_init(void)
213 if (fb_get_options("gfb", NULL
))
216 return of_register_platform_driver(&gfb_driver
);
219 static void __exit
gfb_exit(void)
221 of_unregister_platform_driver(&gfb_driver
);
224 module_init(gfb_init
);
225 module_exit(gfb_exit
);
227 MODULE_DESCRIPTION("framebuffer driver for Sun XVR-1000 graphics");
228 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
229 MODULE_VERSION("1.0");
230 MODULE_LICENSE("GPL");