Rev 2332 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2332 | Rev 2335 | ||
---|---|---|---|
Line 43... | Line 43... | ||
43 | #include "intel_drv.h" |
43 | #include "intel_drv.h" |
44 | #include "i915_drm.h" |
44 | #include "i915_drm.h" |
45 | #include "i915_drv.h" |
45 | #include "i915_drv.h" |
Line -... | Line 46... | ||
- | 46 | ||
- | 47 | ||
- | 48 | struct fb_info *framebuffer_alloc(size_t size, struct device *dev) |
|
- | 49 | { |
|
- | 50 | #define BYTES_PER_LONG (BITS_PER_LONG/8) |
|
- | 51 | #define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG)) |
|
- | 52 | int fb_info_size = sizeof(struct fb_info); |
|
- | 53 | struct fb_info *info; |
|
- | 54 | char *p; |
|
- | 55 | ||
- | 56 | if (size) |
|
- | 57 | fb_info_size += PADDING; |
|
- | 58 | ||
- | 59 | p = kzalloc(fb_info_size + size, GFP_KERNEL); |
|
- | 60 | ||
- | 61 | if (!p) |
|
- | 62 | return NULL; |
|
- | 63 | ||
- | 64 | info = (struct fb_info *) p; |
|
- | 65 | ||
- | 66 | if (size) |
|
- | 67 | info->par = p + fb_info_size; |
|
- | 68 | ||
- | 69 | return info; |
|
- | 70 | #undef PADDING |
|
- | 71 | #undef BYTES_PER_LONG |
|
- | 72 | } |
|
- | 73 | ||
- | 74 | ||
- | 75 | static struct fb_ops intelfb_ops = { |
|
- | 76 | // .owner = THIS_MODULE, |
|
- | 77 | .fb_check_var = drm_fb_helper_check_var, |
|
- | 78 | .fb_set_par = drm_fb_helper_set_par, |
|
- | 79 | // .fb_fillrect = cfb_fillrect, |
|
- | 80 | // .fb_copyarea = cfb_copyarea, |
|
- | 81 | // .fb_imageblit = cfb_imageblit, |
|
- | 82 | // .fb_pan_display = drm_fb_helper_pan_display, |
|
- | 83 | .fb_blank = drm_fb_helper_blank, |
|
- | 84 | // .fb_setcmap = drm_fb_helper_setcmap, |
|
- | 85 | // .fb_debug_enter = drm_fb_helper_debug_enter, |
|
- | 86 | // .fb_debug_leave = drm_fb_helper_debug_leave, |
|
- | 87 | }; |
|
- | 88 | ||
- | 89 | static int intelfb_create(struct intel_fbdev *ifbdev, |
|
- | 90 | struct drm_fb_helper_surface_size *sizes) |
|
- | 91 | { |
|
- | 92 | struct drm_device *dev = ifbdev->helper.dev; |
|
- | 93 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 94 | struct fb_info *info; |
|
- | 95 | struct drm_framebuffer *fb; |
|
- | 96 | struct drm_mode_fb_cmd mode_cmd; |
|
- | 97 | struct drm_i915_gem_object *obj; |
|
- | 98 | struct device *device = &dev->pdev->dev; |
|
- | 99 | int size, ret; |
|
- | 100 | ||
- | 101 | /* we don't do packed 24bpp */ |
|
- | 102 | if (sizes->surface_bpp == 24) |
|
- | 103 | sizes->surface_bpp = 32; |
|
- | 104 | ||
- | 105 | mode_cmd.width = sizes->surface_width; |
|
- | 106 | mode_cmd.height = sizes->surface_height; |
|
- | 107 | ||
- | 108 | mode_cmd.bpp = sizes->surface_bpp; |
|
- | 109 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64); |
|
- | 110 | mode_cmd.depth = sizes->surface_depth; |
|
- | 111 | ||
- | 112 | size = mode_cmd.pitch * mode_cmd.height; |
|
- | 113 | size = ALIGN(size, PAGE_SIZE); |
|
- | 114 | obj = i915_gem_alloc_object(dev, size); |
|
- | 115 | if (!obj) { |
|
- | 116 | DRM_ERROR("failed to allocate framebuffer\n"); |
|
- | 117 | ret = -ENOMEM; |
|
- | 118 | goto out; |
|
- | 119 | } |
|
- | 120 | ||
- | 121 | mutex_lock(&dev->struct_mutex); |
|
- | 122 | ||
- | 123 | /* Flush everything out, we'll be doing GTT only from now on */ |
|
- | 124 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); |
|
- | 125 | if (ret) { |
|
- | 126 | DRM_ERROR("failed to pin fb: %d\n", ret); |
|
- | 127 | goto out_unref; |
|
- | 128 | } |
|
- | 129 | ||
- | 130 | info = framebuffer_alloc(0, device); |
|
- | 131 | if (!info) { |
|
- | 132 | ret = -ENOMEM; |
|
- | 133 | goto out_unpin; |
|
- | 134 | } |
|
- | 135 | ||
- | 136 | info->par = ifbdev; |
|
- | 137 | ||
- | 138 | ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); |
|
- | 139 | if (ret) |
|
- | 140 | goto out_unpin; |
|
- | 141 | ||
- | 142 | fb = &ifbdev->ifb.base; |
|
- | 143 | ||
- | 144 | ifbdev->helper.fb = fb; |
|
- | 145 | ifbdev->helper.fbdev = info; |
|
- | 146 | ||
- | 147 | strcpy(info->fix.id, "inteldrmfb"); |
|
- | 148 | ||
- | 149 | info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT; |
|
- | 150 | info->fbops = &intelfb_ops; |
|
- | 151 | ||
- | 152 | /* setup aperture base/size for vesafb takeover */ |
|
- | 153 | info->apertures = alloc_apertures(1); |
|
- | 154 | if (!info->apertures) { |
|
- | 155 | ret = -ENOMEM; |
|
- | 156 | goto out_unpin; |
|
- | 157 | } |
|
- | 158 | info->apertures->ranges[0].base = dev->mode_config.fb_base; |
|
- | 159 | info->apertures->ranges[0].size = |
|
- | 160 | dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
|
- | 161 | ||
- | 162 | info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; |
|
- | 163 | info->fix.smem_len = size; |
|
- | 164 | ||
- | 165 | info->screen_size = size; |
|
- | 166 | ||
- | 167 | // memset(info->screen_base, 0, size); |
|
- | 168 | ||
- | 169 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); |
|
- | 170 | drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
|
- | 171 | ||
- | 172 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", |
|
- | 173 | fb->width, fb->height, |
|
- | 174 | obj->gtt_offset, obj); |
|
- | 175 | ||
- | 176 | ||
- | 177 | mutex_unlock(&dev->struct_mutex); |
|
- | 178 | // vga_switcheroo_client_fb_set(dev->pdev, info); |
|
- | 179 | return 0; |
|
- | 180 | ||
- | 181 | out_unpin: |
|
- | 182 | // i915_gem_object_unpin(obj); |
|
- | 183 | out_unref: |
|
- | 184 | // drm_gem_object_unreference(&obj->base); |
|
- | 185 | mutex_unlock(&dev->struct_mutex); |
|
- | 186 | out: |
|
- | 187 | return ret; |
|
- | 188 | } |
|
- | 189 | static int intel_fb_find_or_create_single(struct drm_fb_helper *helper, |
|
- | 190 | struct drm_fb_helper_surface_size *sizes) |
|
- | 191 | { |
|
- | 192 | struct intel_fbdev *ifbdev = (struct intel_fbdev *)helper; |
|
- | 193 | int new_fb = 0; |
|
- | 194 | int ret; |
|
- | 195 | ||
- | 196 | if (!helper->fb) { |
|
- | 197 | ret = intelfb_create(ifbdev, sizes); |
|
- | 198 | if (ret) |
|
- | 199 | return ret; |
|
- | 200 | new_fb = 1; |
|
- | 201 | } |
|
- | 202 | return new_fb; |
|
46 | 203 | } |
|
47 | 204 | ||
48 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
205 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
49 | .gamma_set = intel_crtc_fb_gamma_set, |
206 | .gamma_set = intel_crtc_fb_gamma_set, |
50 | .gamma_get = intel_crtc_fb_gamma_get, |
207 | .gamma_get = intel_crtc_fb_gamma_get, |
Line 51... | Line 208... | ||
51 | // .fb_probe = intel_fb_find_or_create_single, |
208 | .fb_probe = intel_fb_find_or_create_single, |
52 | }; |
209 | }; |