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>
12 #include <linux/platform_device.h>
17 char __iomem
*fb_base
;
18 unsigned long fb_base_phys
;
20 struct device_node
*of_node
;
27 u32 pseudo_palette
[16];
30 static int gfb_get_props(struct gfb_info
*gp
)
32 gp
->width
= of_getintprop_default(gp
->of_node
, "width", 0);
33 gp
->height
= of_getintprop_default(gp
->of_node
, "height", 0);
34 gp
->depth
= of_getintprop_default(gp
->of_node
, "depth", 32);
36 if (!gp
->width
|| !gp
->height
) {
37 printk(KERN_ERR
"gfb: Critical properties missing for %pOF\n",
45 static int gfb_setcolreg(unsigned regno
,
46 unsigned red
, unsigned green
, unsigned blue
,
47 unsigned transp
, struct fb_info
*info
)
56 value
= (blue
<< 16) | (green
<< 8) | red
;
57 ((u32
*)info
->pseudo_palette
)[regno
] = value
;
63 static const struct fb_ops gfb_ops
= {
66 .fb_setcolreg
= gfb_setcolreg
,
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
->fbops
= &gfb_ops
;
75 info
->screen_base
= gp
->fb_base
;
76 info
->screen_size
= gp
->fb_size
;
78 info
->pseudo_palette
= gp
->pseudo_palette
;
80 /* Fill fix common fields */
81 strscpy(info
->fix
.id
, "gfb", sizeof(info
->fix
.id
));
82 info
->fix
.smem_start
= gp
->fb_base_phys
;
83 info
->fix
.smem_len
= gp
->fb_size
;
84 info
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
85 if (gp
->depth
== 32 || gp
->depth
== 24)
86 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
88 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
90 var
->xres
= gp
->width
;
91 var
->yres
= gp
->height
;
92 var
->xres_virtual
= var
->xres
;
93 var
->yres_virtual
= var
->yres
;
94 var
->bits_per_pixel
= gp
->depth
;
98 var
->green
.offset
= 8;
99 var
->green
.length
= 8;
100 var
->blue
.offset
= 16;
101 var
->blue
.length
= 8;
102 var
->transp
.offset
= 0;
103 var
->transp
.length
= 0;
105 if (fb_alloc_cmap(&info
->cmap
, 256, 0)) {
106 printk(KERN_ERR
"gfb: Cannot allocate color map.\n");
113 static int gfb_probe(struct platform_device
*op
)
115 struct device_node
*dp
= op
->dev
.of_node
;
116 struct fb_info
*info
;
120 info
= framebuffer_alloc(sizeof(struct gfb_info
), &op
->dev
);
130 gp
->fb_base_phys
= op
->resource
[6].start
;
132 err
= gfb_get_props(gp
);
136 /* Framebuffer length is the same regardless of resolution. */
137 info
->fix
.line_length
= 16384;
138 gp
->fb_size
= info
->fix
.line_length
* gp
->height
;
140 gp
->fb_base
= of_ioremap(&op
->resource
[6], 0,
141 gp
->fb_size
, "gfb fb");
147 err
= gfb_set_fbinfo(gp
);
151 printk("gfb: Found device at %pOF\n", dp
);
153 err
= register_framebuffer(info
);
155 printk(KERN_ERR
"gfb: Could not register framebuffer %pOF\n",
160 dev_set_drvdata(&op
->dev
, info
);
165 of_iounmap(&op
->resource
[6], gp
->fb_base
, gp
->fb_size
);
168 framebuffer_release(info
);
174 static const struct of_device_id gfb_match
[] = {
181 static struct platform_driver gfb_driver
= {
185 .of_match_table
= gfb_match
,
186 .suppress_bind_attrs
= true,
190 static int __init
gfb_init(void)
192 if (fb_get_options("gfb", NULL
))
195 return platform_driver_register(&gfb_driver
);
197 device_initcall(gfb_init
);