drm/gma500: Remove unnecessary include statements
[linux-2.6-microblaze.git] / drivers / gpu / drm / gma500 / framebuffer.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /**************************************************************************
3  * Copyright (c) 2007-2011, Intel Corporation.
4  * All Rights Reserved.
5  *
6  **************************************************************************/
7
8 #include <linux/pfn_t.h>
9
10 #include <drm/drm_crtc_helper.h>
11 #include <drm/drm_fb_helper.h>
12 #include <drm/drm_framebuffer.h>
13 #include <drm/drm_gem_framebuffer_helper.h>
14 #include <drm/drm_modeset_helper.h>
15
16 #include "framebuffer.h"
17 #include "gem.h"
18 #include "psb_drv.h"
19
20 static const struct drm_framebuffer_funcs psb_fb_funcs = {
21         .destroy = drm_gem_fb_destroy,
22         .create_handle = drm_gem_fb_create_handle,
23 };
24
25 #define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
26
27 static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
28                            unsigned blue, unsigned transp,
29                            struct fb_info *info)
30 {
31         struct drm_fb_helper *fb_helper = info->par;
32         struct drm_framebuffer *fb = fb_helper->fb;
33         uint32_t v;
34
35         if (!fb)
36                 return -ENOMEM;
37
38         if (regno > 255)
39                 return 1;
40
41         red = CMAP_TOHW(red, info->var.red.length);
42         blue = CMAP_TOHW(blue, info->var.blue.length);
43         green = CMAP_TOHW(green, info->var.green.length);
44         transp = CMAP_TOHW(transp, info->var.transp.length);
45
46         v = (red << info->var.red.offset) |
47             (green << info->var.green.offset) |
48             (blue << info->var.blue.offset) |
49             (transp << info->var.transp.offset);
50
51         if (regno < 16) {
52                 switch (fb->format->cpp[0] * 8) {
53                 case 16:
54                         ((uint32_t *) info->pseudo_palette)[regno] = v;
55                         break;
56                 case 24:
57                 case 32:
58                         ((uint32_t *) info->pseudo_palette)[regno] = v;
59                         break;
60                 }
61         }
62
63         return 0;
64 }
65
66 static vm_fault_t psbfb_vm_fault(struct vm_fault *vmf)
67 {
68         struct vm_area_struct *vma = vmf->vma;
69         struct drm_framebuffer *fb = vma->vm_private_data;
70         struct drm_device *dev = fb->dev;
71         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
72         struct psb_gem_object *pobj = to_psb_gem_object(fb->obj[0]);
73         int page_num;
74         int i;
75         unsigned long address;
76         vm_fault_t ret = VM_FAULT_SIGBUS;
77         unsigned long pfn;
78         unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + pobj->offset;
79
80         page_num = vma_pages(vma);
81         address = vmf->address - (vmf->pgoff << PAGE_SHIFT);
82
83         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
84
85         for (i = 0; i < page_num; i++) {
86                 pfn = (phys_addr >> PAGE_SHIFT);
87
88                 ret = vmf_insert_mixed(vma, address,
89                                 __pfn_to_pfn_t(pfn, PFN_DEV));
90                 if (unlikely(ret & VM_FAULT_ERROR))
91                         break;
92                 address += PAGE_SIZE;
93                 phys_addr += PAGE_SIZE;
94         }
95         return ret;
96 }
97
98 static void psbfb_vm_open(struct vm_area_struct *vma)
99 {
100 }
101
102 static void psbfb_vm_close(struct vm_area_struct *vma)
103 {
104 }
105
106 static const struct vm_operations_struct psbfb_vm_ops = {
107         .fault  = psbfb_vm_fault,
108         .open   = psbfb_vm_open,
109         .close  = psbfb_vm_close
110 };
111
112 static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
113 {
114         struct drm_fb_helper *fb_helper = info->par;
115         struct drm_framebuffer *fb = fb_helper->fb;
116
117         if (vma->vm_pgoff != 0)
118                 return -EINVAL;
119         if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
120                 return -EINVAL;
121
122         /*
123          * If this is a GEM object then info->screen_base is the virtual
124          * kernel remapping of the object. FIXME: Review if this is
125          * suitable for our mmap work
126          */
127         vma->vm_ops = &psbfb_vm_ops;
128         vma->vm_private_data = (void *)fb;
129         vm_flags_set(vma, VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP);
130         return 0;
131 }
132
133 static const struct fb_ops psbfb_unaccel_ops = {
134         .owner = THIS_MODULE,
135         DRM_FB_HELPER_DEFAULT_OPS,
136         .fb_setcolreg = psbfb_setcolreg,
137         .fb_read = drm_fb_helper_cfb_read,
138         .fb_write = drm_fb_helper_cfb_write,
139         .fb_fillrect = drm_fb_helper_cfb_fillrect,
140         .fb_copyarea = drm_fb_helper_cfb_copyarea,
141         .fb_imageblit = drm_fb_helper_cfb_imageblit,
142         .fb_mmap = psbfb_mmap,
143 };
144
145 /**
146  *      psb_framebuffer_init    -       initialize a framebuffer
147  *      @dev: our DRM device
148  *      @fb: framebuffer to set up
149  *      @mode_cmd: mode description
150  *      @obj: backing object
151  *
152  *      Configure and fill in the boilerplate for our frame buffer. Return
153  *      0 on success or an error code if we fail.
154  */
155 static int psb_framebuffer_init(struct drm_device *dev,
156                                         struct drm_framebuffer *fb,
157                                         const struct drm_mode_fb_cmd2 *mode_cmd,
158                                         struct drm_gem_object *obj)
159 {
160         const struct drm_format_info *info;
161         int ret;
162
163         /*
164          * Reject unknown formats, YUV formats, and formats with more than
165          * 4 bytes per pixel.
166          */
167         info = drm_get_format_info(dev, mode_cmd);
168         if (!info || !info->depth || info->cpp[0] > 4)
169                 return -EINVAL;
170
171         if (mode_cmd->pitches[0] & 63)
172                 return -EINVAL;
173
174         drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
175         fb->obj[0] = obj;
176         ret = drm_framebuffer_init(dev, fb, &psb_fb_funcs);
177         if (ret) {
178                 dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
179                 return ret;
180         }
181         return 0;
182 }
183
184 /**
185  *      psb_framebuffer_create  -       create a framebuffer backed by gt
186  *      @dev: our DRM device
187  *      @mode_cmd: the description of the requested mode
188  *      @obj: the backing object
189  *
190  *      Create a framebuffer object backed by the gt, and fill in the
191  *      boilerplate required
192  *
193  *      TODO: review object references
194  */
195
196 static struct drm_framebuffer *psb_framebuffer_create
197                         (struct drm_device *dev,
198                          const struct drm_mode_fb_cmd2 *mode_cmd,
199                          struct drm_gem_object *obj)
200 {
201         struct drm_framebuffer *fb;
202         int ret;
203
204         fb = kzalloc(sizeof(*fb), GFP_KERNEL);
205         if (!fb)
206                 return ERR_PTR(-ENOMEM);
207
208         ret = psb_framebuffer_init(dev, fb, mode_cmd, obj);
209         if (ret) {
210                 kfree(fb);
211                 return ERR_PTR(ret);
212         }
213         return fb;
214 }
215
216 /**
217  *      psbfb_create            -       create a framebuffer
218  *      @fb_helper: the framebuffer helper
219  *      @sizes: specification of the layout
220  *
221  *      Create a framebuffer to the specifications provided
222  */
223 static int psbfb_create(struct drm_fb_helper *fb_helper,
224                                 struct drm_fb_helper_surface_size *sizes)
225 {
226         struct drm_device *dev = fb_helper->dev;
227         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
228         struct pci_dev *pdev = to_pci_dev(dev->dev);
229         struct fb_info *info;
230         struct drm_framebuffer *fb;
231         struct drm_mode_fb_cmd2 mode_cmd;
232         int size;
233         int ret;
234         struct psb_gem_object *backing;
235         struct drm_gem_object *obj;
236         u32 bpp, depth;
237
238         mode_cmd.width = sizes->surface_width;
239         mode_cmd.height = sizes->surface_height;
240         bpp = sizes->surface_bpp;
241         depth = sizes->surface_depth;
242
243         /* No 24bit packed */
244         if (bpp == 24)
245                 bpp = 32;
246
247         mode_cmd.pitches[0] = ALIGN(mode_cmd.width * DIV_ROUND_UP(bpp, 8), 64);
248
249         size = mode_cmd.pitches[0] * mode_cmd.height;
250         size = ALIGN(size, PAGE_SIZE);
251
252         /* Allocate the framebuffer in the GTT with stolen page backing */
253         backing = psb_gem_create(dev, size, "fb", true, PAGE_SIZE);
254         if (IS_ERR(backing))
255                 return PTR_ERR(backing);
256         obj = &backing->base;
257
258         memset(dev_priv->vram_addr + backing->offset, 0, size);
259
260         info = drm_fb_helper_alloc_info(fb_helper);
261         if (IS_ERR(info)) {
262                 ret = PTR_ERR(info);
263                 goto err_drm_gem_object_put;
264         }
265
266         mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
267
268         fb = psb_framebuffer_create(dev, &mode_cmd, obj);
269         if (IS_ERR(fb)) {
270                 ret = PTR_ERR(fb);
271                 goto err_drm_gem_object_put;
272         }
273
274         fb_helper->fb = fb;
275
276         info->fbops = &psbfb_unaccel_ops;
277
278         info->fix.smem_start = dev_priv->fb_base;
279         info->fix.smem_len = size;
280         info->fix.ywrapstep = 0;
281         info->fix.ypanstep = 0;
282
283         /* Accessed stolen memory directly */
284         info->screen_base = dev_priv->vram_addr + backing->offset;
285         info->screen_size = size;
286
287         drm_fb_helper_fill_info(info, fb_helper, sizes);
288
289         info->fix.mmio_start = pci_resource_start(pdev, 0);
290         info->fix.mmio_len = pci_resource_len(pdev, 0);
291
292         /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
293
294         dev_dbg(dev->dev, "allocated %dx%d fb\n", fb->width, fb->height);
295
296         return 0;
297
298 err_drm_gem_object_put:
299         drm_gem_object_put(obj);
300         return ret;
301 }
302
303 /**
304  *      psb_user_framebuffer_create     -       create framebuffer
305  *      @dev: our DRM device
306  *      @filp: client file
307  *      @cmd: mode request
308  *
309  *      Create a new framebuffer backed by a userspace GEM object
310  */
311 static struct drm_framebuffer *psb_user_framebuffer_create
312                         (struct drm_device *dev, struct drm_file *filp,
313                          const struct drm_mode_fb_cmd2 *cmd)
314 {
315         struct drm_gem_object *obj;
316         struct drm_framebuffer *fb;
317
318         /*
319          *      Find the GEM object and thus the gtt range object that is
320          *      to back this space
321          */
322         obj = drm_gem_object_lookup(filp, cmd->handles[0]);
323         if (obj == NULL)
324                 return ERR_PTR(-ENOENT);
325
326         /* Let the core code do all the work */
327         fb = psb_framebuffer_create(dev, cmd, obj);
328         if (IS_ERR(fb))
329                 drm_gem_object_put(obj);
330
331         return fb;
332 }
333
334 static int psbfb_probe(struct drm_fb_helper *fb_helper,
335                                 struct drm_fb_helper_surface_size *sizes)
336 {
337         struct drm_device *dev = fb_helper->dev;
338         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
339         unsigned int fb_size;
340         int bytespp;
341
342         bytespp = sizes->surface_bpp / 8;
343         if (bytespp == 3)       /* no 24bit packed */
344                 bytespp = 4;
345
346         /* If the mode will not fit in 32bit then switch to 16bit to get
347            a console on full resolution. The X mode setting server will
348            allocate its own 32bit GEM framebuffer */
349         fb_size = ALIGN(sizes->surface_width * bytespp, 64) *
350                   sizes->surface_height;
351         fb_size = ALIGN(fb_size, PAGE_SIZE);
352
353         if (fb_size > dev_priv->vram_stolen_size) {
354                 sizes->surface_bpp = 16;
355                 sizes->surface_depth = 16;
356         }
357
358         return psbfb_create(fb_helper, sizes);
359 }
360
361 static const struct drm_fb_helper_funcs psb_fb_helper_funcs = {
362         .fb_probe = psbfb_probe,
363 };
364
365 static int psb_fbdev_destroy(struct drm_device *dev,
366                              struct drm_fb_helper *fb_helper)
367 {
368         struct drm_framebuffer *fb = fb_helper->fb;
369
370         drm_fb_helper_unregister_info(fb_helper);
371
372         drm_fb_helper_fini(fb_helper);
373         drm_framebuffer_unregister_private(fb);
374         drm_framebuffer_cleanup(fb);
375
376         if (fb->obj[0])
377                 drm_gem_object_put(fb->obj[0]);
378         kfree(fb);
379
380         return 0;
381 }
382
383 int psb_fbdev_init(struct drm_device *dev)
384 {
385         struct drm_fb_helper *fb_helper;
386         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
387         int ret;
388
389         fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
390         if (!fb_helper) {
391                 dev_err(dev->dev, "no memory\n");
392                 return -ENOMEM;
393         }
394
395         dev_priv->fb_helper = fb_helper;
396
397         drm_fb_helper_prepare(dev, fb_helper, 32, &psb_fb_helper_funcs);
398
399         ret = drm_fb_helper_init(dev, fb_helper);
400         if (ret)
401                 goto free;
402
403         /* disable all the possible outputs/crtcs before entering KMS mode */
404         drm_helper_disable_unused_functions(dev);
405
406         ret = drm_fb_helper_initial_config(fb_helper);
407         if (ret)
408                 goto fini;
409
410         return 0;
411
412 fini:
413         drm_fb_helper_fini(fb_helper);
414 free:
415         drm_fb_helper_unprepare(fb_helper);
416         kfree(fb_helper);
417         return ret;
418 }
419
420 static void psb_fbdev_fini(struct drm_device *dev)
421 {
422         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
423
424         if (!dev_priv->fb_helper)
425                 return;
426
427         psb_fbdev_destroy(dev, dev_priv->fb_helper);
428         drm_fb_helper_unprepare(dev_priv->fb_helper);
429         kfree(dev_priv->fb_helper);
430         dev_priv->fb_helper = NULL;
431 }
432
433 static const struct drm_mode_config_funcs psb_mode_funcs = {
434         .fb_create = psb_user_framebuffer_create,
435         .output_poll_changed = drm_fb_helper_output_poll_changed,
436 };
437
438 static void psb_setup_outputs(struct drm_device *dev)
439 {
440         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
441         struct drm_connector_list_iter conn_iter;
442         struct drm_connector *connector;
443
444         drm_mode_create_scaling_mode_property(dev);
445
446         /* It is ok for this to fail - we just don't get backlight control */
447         if (!dev_priv->backlight_property)
448                 dev_priv->backlight_property = drm_property_create_range(dev, 0,
449                                                         "backlight", 0, 100);
450         dev_priv->ops->output_init(dev);
451
452         drm_connector_list_iter_begin(dev, &conn_iter);
453         drm_for_each_connector_iter(connector, &conn_iter) {
454                 struct gma_encoder *gma_encoder = gma_attached_encoder(connector);
455                 struct drm_encoder *encoder = &gma_encoder->base;
456                 int crtc_mask = 0, clone_mask = 0;
457
458                 /* valid crtcs */
459                 switch (gma_encoder->type) {
460                 case INTEL_OUTPUT_ANALOG:
461                         crtc_mask = (1 << 0);
462                         clone_mask = (1 << INTEL_OUTPUT_ANALOG);
463                         break;
464                 case INTEL_OUTPUT_SDVO:
465                         crtc_mask = dev_priv->ops->sdvo_mask;
466                         clone_mask = 0;
467                         break;
468                 case INTEL_OUTPUT_LVDS:
469                         crtc_mask = dev_priv->ops->lvds_mask;
470                         clone_mask = 0;
471                         break;
472                 case INTEL_OUTPUT_MIPI:
473                         crtc_mask = (1 << 0);
474                         clone_mask = 0;
475                         break;
476                 case INTEL_OUTPUT_MIPI2:
477                         crtc_mask = (1 << 2);
478                         clone_mask = 0;
479                         break;
480                 case INTEL_OUTPUT_HDMI:
481                         crtc_mask = dev_priv->ops->hdmi_mask;
482                         clone_mask = (1 << INTEL_OUTPUT_HDMI);
483                         break;
484                 case INTEL_OUTPUT_DISPLAYPORT:
485                         crtc_mask = (1 << 0) | (1 << 1);
486                         clone_mask = 0;
487                         break;
488                 case INTEL_OUTPUT_EDP:
489                         crtc_mask = (1 << 1);
490                         clone_mask = 0;
491                 }
492                 encoder->possible_crtcs = crtc_mask;
493                 encoder->possible_clones =
494                     gma_connector_clones(dev, clone_mask);
495         }
496         drm_connector_list_iter_end(&conn_iter);
497 }
498
499 void psb_modeset_init(struct drm_device *dev)
500 {
501         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
502         struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
503         struct pci_dev *pdev = to_pci_dev(dev->dev);
504         int i;
505
506         if (drmm_mode_config_init(dev))
507                 return;
508
509         dev->mode_config.min_width = 0;
510         dev->mode_config.min_height = 0;
511
512         dev->mode_config.funcs = &psb_mode_funcs;
513
514         /* set memory base */
515         /* Oaktrail and Poulsbo should use BAR 2*/
516         pci_read_config_dword(pdev, PSB_BSM, (u32 *)&(dev_priv->fb_base));
517
518         /* num pipes is 2 for PSB but 1 for Mrst */
519         for (i = 0; i < dev_priv->num_pipe; i++)
520                 psb_intel_crtc_init(dev, i, mode_dev);
521
522         dev->mode_config.max_width = 4096;
523         dev->mode_config.max_height = 4096;
524
525         psb_setup_outputs(dev);
526
527         if (dev_priv->ops->errata)
528                 dev_priv->ops->errata(dev);
529
530         dev_priv->modeset = true;
531 }
532
533 void psb_modeset_cleanup(struct drm_device *dev)
534 {
535         struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
536         if (dev_priv->modeset) {
537                 drm_kms_helper_poll_fini(dev);
538                 psb_fbdev_fini(dev);
539         }
540 }