20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/string.h>
25 #include <linux/tty.h>
26 #include <linux/slab.h>
45 struct drm_file *file_priv,
49 .destroy = psb_user_framebuffer_destroy,
50 .create_handle = psb_user_framebuffer_create_handle,
53 #define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
55 static int psbfb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
74 v = (red << info->
var.red.offset) |
75 (green << info->
var.green.offset) |
76 (blue << info->
var.blue.offset) |
77 (transp << info->
var.transp.offset);
105 if (psbfb->
gtt->npage) {
108 int pages = info->
fix.line_length >> 12;
114 static int psbfb_vm_fault(
struct vm_area_struct *vma,
struct vm_fault *vmf)
128 address = (
unsigned long)vmf->virtual_address - (vmf->pgoff <<
PAGE_SHIFT);
132 for (i = 0; i < page_num; i++) {
139 ret = (ret == -
ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
145 return VM_FAULT_NOPAGE;
156 static const struct vm_operations_struct psbfb_vm_ops = {
157 .fault = psbfb_vm_fault,
158 .open = psbfb_vm_open,
159 .close = psbfb_vm_close
179 vma->
vm_ops = &psbfb_vm_ops;
181 vma->
vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
185 static int psbfb_ioctl(
struct fb_info *info,
unsigned int cmd,
191 static struct fb_ops psbfb_ops = {
196 .fb_setcolreg = psbfb_setcolreg,
200 .fb_mmap = psbfb_mmap,
202 .fb_ioctl = psbfb_ioctl,
205 static struct fb_ops psbfb_roll_ops = {
210 .fb_setcolreg = psbfb_setcolreg,
214 .fb_pan_display = psbfb_pan,
215 .fb_mmap = psbfb_mmap,
216 .fb_ioctl = psbfb_ioctl,
219 static struct fb_ops psbfb_unaccel_ops = {
224 .fb_setcolreg = psbfb_setcolreg,
228 .fb_mmap = psbfb_mmap,
229 .fb_ioctl = psbfb_ioctl,
242 static int psb_framebuffer_init(
struct drm_device *dev,
265 dev_err(dev->dev,
"framebuffer init failed: %d\n", ret);
297 ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
325 &backing->
gem, aligned_size) == 0)
339 static int psbfb_create(
struct psb_fbdev *fbdev,
371 mode_cmd.
pitches[0] =
ALIGN(mode_cmd.
width * ((bpp + 7) / 8), 4096 >> pitch_lines);
377 backing = psbfb_alloc(dev, size);
384 }
while (backing ==
NULL && pitch_lines <= 16);
389 if (backing ==
NULL) {
405 backing = psbfb_alloc(dev, size);
423 ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
437 if (dev_priv->
ops->accel_2d && pitch_lines > 8)
438 info->
fbops = &psbfb_ops;
440 info->
fbops = &psbfb_roll_ops;
443 info->
fbops = &psbfb_unaccel_ops;
451 info->
fix.smem_start = dev->mode_config.fb_base;
453 info->
fix.ywrapstep = gtt_roll;
454 info->
fix.ypanstep = 0;
460 if (dev_priv->
gtt.stolen_size) {
466 info->
apertures->ranges[0].base = dev->mode_config.fb_base;
467 info->
apertures->ranges[0].size = dev_priv->
gtt.stolen_size;
478 dev_dbg(dev->dev,
"allocated %dx%d fb\n",
479 psbfb->
base.width, psbfb->
base.height);
487 drm_gem_object_unreference(&backing->
gem);
503 (
struct drm_device *dev,
struct drm_file *filp,
507 struct drm_gem_object *obj;
519 return psb_framebuffer_create(dev, cmd, r);
527 intel_crtc->
lut_r[regno] = red >> 8;
528 intel_crtc->
lut_g[regno] = green >> 8;
529 intel_crtc->
lut_b[regno] = blue >> 8;
537 *red = intel_crtc->
lut_r[regno] << 8;
538 *green = intel_crtc->
lut_g[regno] << 8;
539 *blue = intel_crtc->
lut_b[regno] << 8;
566 ret = psbfb_create(psb_fbdev, sizes);
575 .gamma_set = psbfb_gamma_set,
576 .gamma_get = psbfb_gamma_get,
577 .fb_probe = psbfb_probe,
580 static int psb_fbdev_destroy(
struct drm_device *dev,
struct psb_fbdev *fbdev)
596 drm_gem_object_unreference(&psbfb->
gtt->gem);
602 struct psb_fbdev *
fbdev;
605 fbdev = kzalloc(
sizeof(
struct psb_fbdev),
GFP_KERNEL);
607 dev_err(dev->dev,
"no memory\n");
622 static void psb_fbdev_fini(
struct drm_device *dev)
626 if (!dev_priv->
fbdev)
629 psb_fbdev_destroy(dev, dev_priv->
fbdev);
634 static void psbfb_output_poll_changed(
struct drm_device *dev)
637 struct psb_fbdev *fbdev = (
struct psb_fbdev *)dev_priv->
fbdev;
651 static int psb_user_framebuffer_create_handle(
struct drm_framebuffer *fb,
652 struct drm_file *file_priv,
673 struct psb_fbdev *fbdev = dev_priv->
fbdev;
699 drm_gem_object_unreference_unlocked(&r->
gem);
704 .
fb_create = psb_user_framebuffer_create,
705 .output_poll_changed = psbfb_output_poll_changed,
708 static int psb_create_backlight_property(
struct drm_device *dev)
723 static void psb_setup_outputs(
struct drm_device *dev)
729 psb_create_backlight_property(dev);
731 dev_priv->
ops->output_init(dev);
736 psb_intel_attached_encoder(connector);
738 int crtc_mask = 0, clone_mask = 0;
741 switch (psb_intel_encoder->
type) {
743 crtc_mask = (1 << 0);
747 crtc_mask = ((1 << 0) | (1 << 1));
751 crtc_mask = dev_priv->
ops->lvds_mask;
755 crtc_mask = (1 << 0);
759 crtc_mask = (1 << 2);
763 crtc_mask = dev_priv->
ops->hdmi_mask;
767 crtc_mask = (1 << 0) | (1 << 1);
771 crtc_mask = (1 << 1);
788 dev->mode_config.min_width = 0;
789 dev->mode_config.min_height = 0;
791 dev->mode_config.funcs = &psb_mode_funcs;
795 pci_read_config_dword(dev->pdev,
PSB_BSM, (
u32 *)
796 &(dev->mode_config.fb_base));
799 for (i = 0; i < dev_priv->
num_pipe; i++)
802 dev->mode_config.max_width = 2048;
803 dev->mode_config.max_height = 2048;
805 psb_setup_outputs(dev);
807 if (dev_priv->
ops->errata)
808 dev_priv->
ops->errata(dev);