1*44e69495SMaarten Lankhorst /* SPDX-License-Identifier: MIT */ 2*44e69495SMaarten Lankhorst /* 3*44e69495SMaarten Lankhorst * Copyright © 2023 Intel Corporation 4*44e69495SMaarten Lankhorst */ 5*44e69495SMaarten Lankhorst 6*44e69495SMaarten Lankhorst #include "intel_fbdev_fb.h" 7*44e69495SMaarten Lankhorst 8*44e69495SMaarten Lankhorst #include <drm/drm_fb_helper.h> 9*44e69495SMaarten Lankhorst 10*44e69495SMaarten Lankhorst #include "xe_gt.h" 11*44e69495SMaarten Lankhorst #include "xe_ttm_stolen_mgr.h" 12*44e69495SMaarten Lankhorst 13*44e69495SMaarten Lankhorst #include "i915_drv.h" 14*44e69495SMaarten Lankhorst #include "intel_display_types.h" 15*44e69495SMaarten Lankhorst 16*44e69495SMaarten Lankhorst struct drm_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, 17*44e69495SMaarten Lankhorst struct drm_fb_helper_surface_size *sizes) 18*44e69495SMaarten Lankhorst { 19*44e69495SMaarten Lankhorst struct drm_framebuffer *fb; 20*44e69495SMaarten Lankhorst struct drm_device *dev = helper->dev; 21*44e69495SMaarten Lankhorst struct drm_i915_private *dev_priv = to_i915(dev); 22*44e69495SMaarten Lankhorst struct drm_mode_fb_cmd2 mode_cmd = {}; 23*44e69495SMaarten Lankhorst struct drm_i915_gem_object *obj; 24*44e69495SMaarten Lankhorst int size; 25*44e69495SMaarten Lankhorst 26*44e69495SMaarten Lankhorst /* we don't do packed 24bpp */ 27*44e69495SMaarten Lankhorst if (sizes->surface_bpp == 24) 28*44e69495SMaarten Lankhorst sizes->surface_bpp = 32; 29*44e69495SMaarten Lankhorst 30*44e69495SMaarten Lankhorst mode_cmd.width = sizes->surface_width; 31*44e69495SMaarten Lankhorst mode_cmd.height = sizes->surface_height; 32*44e69495SMaarten Lankhorst 33*44e69495SMaarten Lankhorst mode_cmd.pitches[0] = ALIGN(mode_cmd.width * 34*44e69495SMaarten Lankhorst DIV_ROUND_UP(sizes->surface_bpp, 8), XE_PAGE_SIZE); 35*44e69495SMaarten Lankhorst mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, 36*44e69495SMaarten Lankhorst sizes->surface_depth); 37*44e69495SMaarten Lankhorst 38*44e69495SMaarten Lankhorst size = mode_cmd.pitches[0] * mode_cmd.height; 39*44e69495SMaarten Lankhorst size = PAGE_ALIGN(size); 40*44e69495SMaarten Lankhorst obj = ERR_PTR(-ENODEV); 41*44e69495SMaarten Lankhorst 42*44e69495SMaarten Lankhorst if (!IS_DGFX(dev_priv)) { 43*44e69495SMaarten Lankhorst obj = xe_bo_create_pin_map(dev_priv, xe_device_get_root_tile(dev_priv), 44*44e69495SMaarten Lankhorst NULL, size, 45*44e69495SMaarten Lankhorst ttm_bo_type_kernel, XE_BO_SCANOUT_BIT | 46*44e69495SMaarten Lankhorst XE_BO_CREATE_STOLEN_BIT | 47*44e69495SMaarten Lankhorst XE_BO_CREATE_PINNED_BIT); 48*44e69495SMaarten Lankhorst if (!IS_ERR(obj)) 49*44e69495SMaarten Lankhorst drm_info(&dev_priv->drm, "Allocated fbdev into stolen\n"); 50*44e69495SMaarten Lankhorst else 51*44e69495SMaarten Lankhorst drm_info(&dev_priv->drm, "Allocated fbdev into stolen failed: %li\n", PTR_ERR(obj)); 52*44e69495SMaarten Lankhorst } 53*44e69495SMaarten Lankhorst if (IS_ERR(obj)) { 54*44e69495SMaarten Lankhorst obj = xe_bo_create_pin_map(dev_priv, xe_device_get_root_tile(dev_priv), NULL, size, 55*44e69495SMaarten Lankhorst ttm_bo_type_kernel, XE_BO_SCANOUT_BIT | 56*44e69495SMaarten Lankhorst XE_BO_CREATE_VRAM_IF_DGFX(xe_device_get_root_tile(dev_priv)) | 57*44e69495SMaarten Lankhorst XE_BO_CREATE_PINNED_BIT); 58*44e69495SMaarten Lankhorst } 59*44e69495SMaarten Lankhorst 60*44e69495SMaarten Lankhorst if (IS_ERR(obj)) { 61*44e69495SMaarten Lankhorst drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj); 62*44e69495SMaarten Lankhorst fb = ERR_PTR(-ENOMEM); 63*44e69495SMaarten Lankhorst goto err; 64*44e69495SMaarten Lankhorst } 65*44e69495SMaarten Lankhorst 66*44e69495SMaarten Lankhorst fb = intel_framebuffer_create(obj, &mode_cmd); 67*44e69495SMaarten Lankhorst if (IS_ERR(fb)) { 68*44e69495SMaarten Lankhorst xe_bo_unpin_map_no_vm(obj); 69*44e69495SMaarten Lankhorst goto err; 70*44e69495SMaarten Lankhorst } 71*44e69495SMaarten Lankhorst 72*44e69495SMaarten Lankhorst drm_gem_object_put(intel_bo_to_drm_bo(obj)); 73*44e69495SMaarten Lankhorst return fb; 74*44e69495SMaarten Lankhorst 75*44e69495SMaarten Lankhorst err: 76*44e69495SMaarten Lankhorst return fb; 77*44e69495SMaarten Lankhorst } 78*44e69495SMaarten Lankhorst 79*44e69495SMaarten Lankhorst int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, 80*44e69495SMaarten Lankhorst struct drm_i915_gem_object *obj, struct i915_vma *vma) 81*44e69495SMaarten Lankhorst { 82*44e69495SMaarten Lankhorst struct pci_dev *pdev = to_pci_dev(i915->drm.dev); 83*44e69495SMaarten Lankhorst 84*44e69495SMaarten Lankhorst if (!(obj->flags & XE_BO_CREATE_SYSTEM_BIT)) { 85*44e69495SMaarten Lankhorst if (obj->flags & XE_BO_CREATE_STOLEN_BIT) 86*44e69495SMaarten Lankhorst info->fix.smem_start = xe_ttm_stolen_io_offset(obj, 0); 87*44e69495SMaarten Lankhorst else 88*44e69495SMaarten Lankhorst info->fix.smem_start = 89*44e69495SMaarten Lankhorst pci_resource_start(pdev, 2) + 90*44e69495SMaarten Lankhorst xe_bo_addr(obj, 0, XE_PAGE_SIZE); 91*44e69495SMaarten Lankhorst 92*44e69495SMaarten Lankhorst info->fix.smem_len = obj->ttm.base.size; 93*44e69495SMaarten Lankhorst } else { 94*44e69495SMaarten Lankhorst /* XXX: Pure fiction, as the BO may not be physically accessible.. */ 95*44e69495SMaarten Lankhorst info->fix.smem_start = 0; 96*44e69495SMaarten Lankhorst info->fix.smem_len = obj->ttm.base.size; 97*44e69495SMaarten Lankhorst } 98*44e69495SMaarten Lankhorst XE_WARN_ON(iosys_map_is_null(&obj->vmap)); 99*44e69495SMaarten Lankhorst 100*44e69495SMaarten Lankhorst info->screen_base = obj->vmap.vaddr_iomem; 101*44e69495SMaarten Lankhorst info->screen_size = intel_bo_to_drm_bo(obj)->size; 102*44e69495SMaarten Lankhorst 103*44e69495SMaarten Lankhorst return 0; 104*44e69495SMaarten Lankhorst } 105