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_wa_oob.h> 14 15 struct drm_gem_object *intel_fbdev_fb_bo_create(struct drm_device *drm, int size) 16 { 17 struct xe_device *xe = to_xe_device(drm); 18 struct xe_bo *obj; 19 20 obj = ERR_PTR(-ENODEV); 21 22 if (!IS_DGFX(xe) && !XE_GT_WA(xe_root_mmio_gt(xe), 22019338487_display)) { 23 obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), 24 NULL, size, 25 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | 26 XE_BO_FLAG_STOLEN | 27 XE_BO_FLAG_GGTT); 28 if (!IS_ERR(obj)) 29 drm_info(&xe->drm, "Allocated fbdev into stolen\n"); 30 else 31 drm_info(&xe->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj)); 32 } 33 34 if (IS_ERR(obj)) { 35 obj = xe_bo_create_pin_map(xe, xe_device_get_root_tile(xe), NULL, size, 36 ttm_bo_type_kernel, XE_BO_FLAG_SCANOUT | 37 XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) | 38 XE_BO_FLAG_GGTT); 39 } 40 41 if (IS_ERR(obj)) { 42 drm_err(&xe->drm, "failed to allocate framebuffer (%pe)\n", obj); 43 return ERR_PTR(-ENOMEM); 44 } 45 46 return &obj->ttm.base; 47 } 48 49 void intel_fbdev_fb_bo_destroy(struct drm_gem_object *obj) 50 { 51 xe_bo_unpin_map_no_vm(gem_to_xe_bo(obj)); 52 } 53 54 int intel_fbdev_fb_fill_info(struct drm_device *drm, struct fb_info *info, 55 struct drm_gem_object *_obj, struct i915_vma *vma) 56 { 57 struct xe_bo *obj = gem_to_xe_bo(_obj); 58 struct pci_dev *pdev = to_pci_dev(drm->dev); 59 60 if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { 61 if (obj->flags & XE_BO_FLAG_STOLEN) 62 info->fix.smem_start = xe_ttm_stolen_io_offset(obj, 0); 63 else 64 info->fix.smem_start = 65 pci_resource_start(pdev, 2) + 66 xe_bo_addr(obj, 0, XE_PAGE_SIZE); 67 68 info->fix.smem_len = obj->ttm.base.size; 69 } else { 70 /* XXX: Pure fiction, as the BO may not be physically accessible.. */ 71 info->fix.smem_start = 0; 72 info->fix.smem_len = obj->ttm.base.size; 73 } 74 XE_WARN_ON(iosys_map_is_null(&obj->vmap)); 75 76 info->screen_base = obj->vmap.vaddr_iomem; 77 info->screen_size = obj->ttm.base.size; 78 79 return 0; 80 } 81