Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/i915/gt/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  intel_region_lmem.c   Sprache: C

 
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2019 Intel Corporation
 */


#include "i915_drv.h"
#include "i915_pci.h"
#include "i915_reg.h"
#include "intel_memory_region.h"
#include "intel_pci_config.h"
#include "intel_region_lmem.h"
#include "intel_region_ttm.h"
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gem/i915_gem_ttm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_mcr.h"
#include "gt/intel_gt_regs.h"

#ifdef CONFIG_64BIT
static void _release_bars(struct pci_dev *pdev)
{
 int resno;

 for (resno = PCI_STD_RESOURCES; resno < PCI_STD_RESOURCE_END; resno++) {
  if (pci_resource_len(pdev, resno))
   pci_release_resource(pdev, resno);
 }
}

static void
_resize_bar(struct drm_i915_private *i915, int resno, resource_size_t size)
{
 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
 int bar_size = pci_rebar_bytes_to_size(size);
 int ret;

 _release_bars(pdev);

 ret = pci_resize_resource(pdev, resno, bar_size);
 if (ret) {
  drm_info(&i915->drm, "Failed to resize BAR%d to %dM (%pe)\n",
    resno, 1 << bar_size, ERR_PTR(ret));
  return;
 }

 drm_info(&i915->drm, "BAR%d resized to %dM\n", resno, 1 << bar_size);
}

static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t lmem_size)
{
 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
 struct pci_bus *root = pdev->bus;
 struct resource *root_res;
 resource_size_t rebar_size;
 resource_size_t current_size;
 intel_wakeref_t wakeref;
 u32 pci_cmd;
 int i;

 current_size = roundup_pow_of_two(pci_resource_len(pdev, GEN12_LMEM_BAR));

 if (i915->params.lmem_bar_size) {
  u32 bar_sizes;

  rebar_size = i915->params.lmem_bar_size *
   (resource_size_t)SZ_1M;
  bar_sizes = pci_rebar_get_possible_sizes(pdev, GEN12_LMEM_BAR);

  if (rebar_size == current_size)
   return;

  if (!(bar_sizes & BIT(pci_rebar_bytes_to_size(rebar_size))) ||
      rebar_size >= roundup_pow_of_two(lmem_size)) {
   rebar_size = lmem_size;

   drm_info(&i915->drm,
     "Given bar size is not within supported size, setting it to default: %llu\n",
     (u64)lmem_size >> 20);
  }
 } else {
  rebar_size = current_size;

  if (rebar_size != roundup_pow_of_two(lmem_size))
   rebar_size = lmem_size;
  else
   return;
 }

 /* Find out if root bus contains 64bit memory addressing */
 while (root->parent)
  root = root->parent;

 pci_bus_for_each_resource(root, root_res, i) {
  if (root_res && root_res->flags & (IORESOURCE_MEM | IORESOURCE_MEM_64) &&
      root_res->start > 0x100000000ull)
   break;
 }

 /* pci_resize_resource will fail anyways */
 if (!root_res) {
  drm_info(&i915->drm, "Can't resize LMEM BAR - platform support is missing\n");
  return;
 }

 /*
 * Releasing forcewake during BAR resizing results in later forcewake
 * ack timeouts and former can happen any time - it is asynchronous.
 * Grabbing all forcewakes prevents it.
 */

 with_intel_runtime_pm(i915->uncore.rpm, wakeref) {
  intel_uncore_forcewake_get(&i915->uncore, FORCEWAKE_ALL);

  /* First disable PCI memory decoding references */
  pci_read_config_dword(pdev, PCI_COMMAND, &pci_cmd);
  pci_write_config_dword(pdev, PCI_COMMAND,
           pci_cmd & ~PCI_COMMAND_MEMORY);

  _resize_bar(i915, GEN12_LMEM_BAR, rebar_size);

  pci_assign_unassigned_bus_resources(pdev->bus);
  pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd);
  intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL);
 }
}
#else
static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t lmem_size) {}
#endif

static int
region_lmem_release(struct intel_memory_region *mem)
{
 int ret;

 ret = intel_region_ttm_fini(mem);
 io_mapping_fini(&mem->iomap);

 return ret;
}

static int
region_lmem_init(struct intel_memory_region *mem)
{
 int ret;

 if (!io_mapping_init_wc(&mem->iomap,
    mem->io.start,
    resource_size(&mem->io)))
  return -EIO;

 ret = intel_region_ttm_init(mem);
 if (ret)
  goto out_no_buddy;

 return 0;

out_no_buddy:
 io_mapping_fini(&mem->iomap);

 return ret;
}

static const struct intel_memory_region_ops intel_region_lmem_ops = {
 .init = region_lmem_init,
 .release = region_lmem_release,
 .init_object = __i915_gem_ttm_object_init,
};

static bool get_legacy_lowmem_region(struct intel_uncore *uncore,
         u64 *start, u32 *size)
{
 if (!IS_DG1(uncore->i915))
  return false;

 *start = 0;
 *size = SZ_1M;

 drm_dbg(&uncore->i915->drm, "LMEM: reserved legacy low-memory [0x%llx-0x%llx]\n",
  *start, *start + *size);

 return true;
}

static int reserve_lowmem_region(struct intel_uncore *uncore,
     struct intel_memory_region *mem)
{
 u64 reserve_start;
 u32 reserve_size;
 int ret;

 if (!get_legacy_lowmem_region(uncore, &reserve_start, &reserve_size))
  return 0;

 ret = intel_memory_region_reserve(mem, reserve_start, reserve_size);
 if (ret)
  drm_err(&uncore->i915->drm, "LMEM: reserving low memory region failed\n");

 return ret;
}

static struct intel_memory_region *setup_lmem(struct intel_gt *gt)
{
 struct drm_i915_private *i915 = gt->i915;
 struct intel_uncore *uncore = gt->uncore;
 struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
 struct intel_memory_region *mem;
 resource_size_t min_page_size;
 resource_size_t io_start;
 resource_size_t io_size;
 resource_size_t lmem_size;
 int err;

 if (!IS_DGFX(i915))
  return ERR_PTR(-ENODEV);

 if (!i915_pci_resource_valid(pdev, GEN12_LMEM_BAR))
  return ERR_PTR(-ENXIO);

 if (HAS_FLAT_CCS(i915)) {
  resource_size_t lmem_range;
  u64 tile_stolen, flat_ccs_base;

  lmem_range = intel_gt_mcr_read_any(to_gt(i915), XEHP_TILE0_ADDR_RANGE) & 0xFFFF;
  lmem_size = lmem_range >> XEHP_TILE_LMEM_RANGE_SHIFT;
  lmem_size *= SZ_1G;

  flat_ccs_base = intel_gt_mcr_read_any(gt, XEHP_FLAT_CCS_BASE_ADDR);
  flat_ccs_base = (flat_ccs_base >> XEHP_CCS_BASE_SHIFT) * SZ_64K;

  if (GEM_WARN_ON(lmem_size < flat_ccs_base))
   return ERR_PTR(-EIO);

  tile_stolen = lmem_size - flat_ccs_base;

  /* If the FLAT_CCS_BASE_ADDR register is not populated, flag an error */
  if (tile_stolen == lmem_size)
   drm_err(&i915->drm,
    "CCS_BASE_ADDR register did not have expected value\n");

  lmem_size -= tile_stolen;
 } else {
  /* Stolen starts from GSMBASE without CCS */
  lmem_size = intel_uncore_read64(&i915->uncore, GEN6_GSMBASE);
 }

 i915_resize_lmem_bar(i915, lmem_size);

 if (i915->params.lmem_size > 0) {
  lmem_size = min_t(resource_size_t, lmem_size,
      mul_u32_u32(i915->params.lmem_size, SZ_1M));
 }

 io_start = pci_resource_start(pdev, GEN12_LMEM_BAR);
 io_size = min(pci_resource_len(pdev, GEN12_LMEM_BAR), lmem_size);
 if (!io_size)
  return ERR_PTR(-EIO);

 min_page_size = HAS_64K_PAGES(i915) ? I915_GTT_PAGE_SIZE_64K :
      I915_GTT_PAGE_SIZE_4K;
 mem = intel_memory_region_create(i915,
      0,
      lmem_size,
      min_page_size,
      io_start,
      io_size,
      INTEL_MEMORY_LOCAL,
      0,
      &intel_region_lmem_ops);
 if (IS_ERR(mem))
  return mem;

 err = reserve_lowmem_region(uncore, mem);
 if (err)
  goto err_region_put;

 if (io_size < lmem_size)
  drm_info(&i915->drm, "Using a reduced BAR size of %lluMiB. Consider enabling 'Resizable BAR' or similar, if available in the BIOS.\n",
    (u64)io_size >> 20);

 return mem;

err_region_put:
 intel_memory_region_destroy(mem);
 return ERR_PTR(err);
}

struct intel_memory_region *intel_gt_setup_lmem(struct intel_gt *gt)
{
 return setup_lmem(gt);
}

Messung V0.5
C=95 H=94 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.