1 /* SPDX-License-Identifier: MIT */ 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/fb.h> 7 8 #include "intel_fbdev_fb.h" 9 #include "xe_bo.h" 10 #include "xe_ttm_stolen_mgr.h" 11 #include "xe_wa.h" 12 13 #include <generated/xe_device_wa_oob.h> 14 15 /* 16 * FIXME: There shouldn't be any reason to have XE_PAGE_SIZE stride 17 * alignment. The same 64 as i915 uses should be fine, and we shouldn't need to 18 * have driver specific values. However, dropping the stride alignment to 64 19 * leads to underflowing the bo pin count in the atomic cleanup work. 20 */ 21 u32 intel_fbdev_fb_pitch_align(u32 stride) 22 { 23 return ALIGN(stride, XE_PAGE_SIZE); 24 } 25 26 struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size) 27 { 28 struct xe_device *xe = to_xe_device(drm); 29 struct xe_bo *obj; 30 31 obj = ERR_PTR(-ENODEV); 32 33 if (!IS_DGFX(xe) && !XE_DEVICE_WA(xe, 22019338487_display)) { 34 obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), 35 size, 36 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | 37 XE_BO_FLAG_STOLEN | 38 XE_BO_FLAG_GGTT, false); 39 if (!IS_ERR(obj)) 40 drm_info(&xe->drm, "Allocated fbdev into stolen\n"); 41 else 42 drm_info(&xe->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj)); 43 } 44 45 if (IS_ERR(obj)) { 46 obj = xe_bo_create_pin_map_novm(xe, xe_device_get_root_tile(xe), size, 47 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | 48 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | 49 XE_BO_FLAG_GGTT, false); 50 } 51 52 if (IS_ERR(obj)) { 53 drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj); 54 return ERR_PTR(-ENOMEM); 55 } 56 57 return &obj->ttm.base; 58 } 59 60 void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj) 61 { 62 xe_bo_unpin_map_no_vm(gem_to_xe_bo(obj)); 63 } 64 65 int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info, 66 struct drm_gem_object *_obj, struct i915_vma *vma) 67 { 68 struct xe_bo *obj = gem_to_xe_bo(_obj); 69 struct pci_dev *pdev = to_pci_dev(drm->dev); 70 71 if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { 72 if (obj->flags & XE_BO_FLAG_STOLEN) 73 info->fix.smem_start = xe_ttm_stolen_io_offset(obj, 0); 74 else 75 info->fix.smem_start = 76 pci_resource_start(pdev, 2) + 77 xe_bo_addr(obj, 0, XE_PAGE_SIZE); 78 79 info->fix.smem_len = obj->ttm.base.size; 80 } else { 81 /* XXX: Pure fiction, as the BO may not be physically accessible.. */ 82 info->fix.smem_start = 0; 83 info->fix.smem_len = obj->ttm.base.size; 84 } 85 XE_WARN_ON(iosys_map_is_null(&obj->vmap)); 86 87 info->screen_base = obj->vmap.vaddr_iomem; 88 info->screen_size = obj->ttm.base.size; 89 90 return 0; 91 } 92