Contributors: 14
| Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
| Jouni Högander |
273 |
55.94% |
1 |
2.70% |
| Jani Nikula |
68 |
13.93% |
11 |
29.73% |
| Ville Syrjälä |
39 |
7.99% |
3 |
8.11% |
| Chris Wilson |
21 |
4.30% |
8 |
21.62% |
| Anusha Srivatsa |
19 |
3.89% |
1 |
2.70% |
| Vinod Govindapillai |
14 |
2.87% |
2 |
5.41% |
| Nirmoy Das |
12 |
2.46% |
4 |
10.81% |
| Mohammed Khajapasha |
10 |
2.05% |
1 |
2.70% |
| CQ Tang |
8 |
1.64% |
1 |
2.70% |
| Dave Airlie |
7 |
1.43% |
1 |
2.70% |
| Jesse Barnes |
6 |
1.23% |
1 |
2.70% |
| Thomas Zimmermann |
5 |
1.02% |
1 |
2.70% |
| Wambui Karuga |
3 |
0.61% |
1 |
2.70% |
| Paulo Zanoni |
3 |
0.61% |
1 |
2.70% |
| Total |
488 |
|
37 |
|
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2023 Intel Corporation
*/
#include <linux/fb.h>
#include <drm/drm_print.h>
#include "gem/i915_gem_lmem.h"
#include "i915_drv.h"
#include "intel_fbdev_fb.h"
u32 intel_fbdev_fb_pitch_align(u32 stride)
{
return ALIGN(stride, 64);
}
bool intel_fbdev_fb_prefer_stolen(struct drm_device *drm, unsigned int size)
{
struct drm_i915_private *i915 = to_i915(drm);
/* Skip stolen on MTL as Wa_22018444074 mitigation. */
if (IS_METEORLAKE(i915))
return false;
/*
* If the FB is too big, just don't use it since fbdev is not very
* important and we should probably use that space with FBC or other
* features.
*/
return i915->dsm.usable_size >= size * 2;
}
struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size)
{
struct drm_i915_private *i915 = to_i915(drm);
struct drm_i915_gem_object *obj;
obj = ERR_PTR(-ENODEV);
if (HAS_LMEM(i915)) {
obj = i915_gem_object_create_lmem(i915, size,
I915_BO_ALLOC_CONTIGUOUS |
I915_BO_ALLOC_USER);
} else {
if (intel_fbdev_fb_prefer_stolen(drm, size))
obj = i915_gem_object_create_stolen(i915, size);
else
drm_info(drm, "Allocating fbdev: Stolen memory not preferred.\n");
if (IS_ERR(obj))
obj = i915_gem_object_create_shmem(i915, size);
}
if (IS_ERR(obj)) {
drm_err(drm, "failed to allocate framebuffer (%pe)\n", obj);
return ERR_PTR(-ENOMEM);
}
return &obj->base;
}
void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj)
{
drm_gem_object_put(obj);
}
int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info,
struct drm_gem_object *_obj, struct i915_vma *vma)
{
struct drm_i915_private *i915 = to_i915(drm);
struct drm_i915_gem_object *obj = to_intel_bo(_obj);
struct i915_gem_ww_ctx ww;
void __iomem *vaddr;
int ret;
if (i915_gem_object_is_lmem(obj)) {
struct intel_memory_region *mem = obj->mm.region;
/* Use fbdev's framebuffer from lmem for discrete */
info->fix.smem_start =
(unsigned long)(mem->io.start +
i915_gem_object_get_dma_address(obj, 0) -
mem->region.start);
info->fix.smem_len = obj->base.size;
} else {
struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
/* Our framebuffer is the entirety of fbdev's system memory */
info->fix.smem_start =
(unsigned long)(ggtt->gmadr.start + i915_ggtt_offset(vma));
info->fix.smem_len = vma->size;
}
for_i915_gem_ww(&ww, ret, false) {
ret = i915_gem_object_lock(vma->obj, &ww);
if (ret)
continue;
vaddr = i915_vma_pin_iomap(vma);
if (IS_ERR(vaddr)) {
drm_err(drm,
"Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
ret = PTR_ERR(vaddr);
continue;
}
}
if (ret)
return ret;
info->screen_base = vaddr;
info->screen_size = intel_bo_to_drm_bo(obj)->size;
return 0;
}