drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
Extension
.c
Size
9115 bytes
Lines
331
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2021-2023 Intel Corporation
 * Copyright (C) 2021-2022 Red Hat
 */

#include <drm/drm_managed.h>

#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_range_manager.h>

#include <generated/xe_wa_oob.h>

#include "regs/xe_bars.h"
#include "regs/xe_gt_regs.h"
#include "regs/xe_regs.h"
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_gt_printk.h"
#include "xe_mmio.h"
#include "xe_sriov.h"
#include "xe_ttm_stolen_mgr.h"
#include "xe_vram.h"
#include "xe_wa.h"

/**
 * xe_ttm_stolen_cpu_access_needs_ggtt() - If we can't directly CPU access
 * stolen, can we then fallback to mapping through the GGTT.
 * @xe: xe device
 *
 * Some older integrated platforms don't support reliable CPU access for stolen,
 * however on such hardware we can always use the mappable part of the GGTT for
 * CPU access. Check if that's the case for this device.
 */
bool xe_ttm_stolen_cpu_access_needs_ggtt(struct xe_device *xe)
{
	return GRAPHICS_VERx100(xe) < 1270 && !IS_DGFX(xe);
}

static u32 get_wopcm_size(struct xe_device *xe)
{
	u32 wopcm_size;
	u64 val;

	val = xe_mmio_read64_2x32(xe_root_tile_mmio(xe), STOLEN_RESERVED);
	val = REG_FIELD_GET64(WOPCM_SIZE_MASK, val);

	switch (val) {
	case 0x5 ... 0x6:
		val--;
		fallthrough;
	case 0x0 ... 0x3:
		wopcm_size = (1U << val) * SZ_1M;
		break;
	default:
		WARN(1, "Missing case wopcm_size=%llx\n", val);
		wopcm_size = 0;
	}

	return wopcm_size;
}

static u64 detect_bar2_dgfx(struct xe_device *xe, struct xe_ttm_stolen_mgr *mgr)
{
	struct xe_vram_region *tile_vram = xe_device_get_root_tile(xe)->mem.vram;
	resource_size_t tile_io_start = xe_vram_region_io_start(tile_vram);
	struct xe_mmio *mmio = xe_root_tile_mmio(xe);
	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
	u64 stolen_size, wopcm_size;
	u64 tile_offset;
	u64 tile_size;

	tile_offset = tile_io_start - xe_vram_region_io_start(xe->mem.vram);
	tile_size = xe_vram_region_actual_physical_size(tile_vram);

	/* Use DSM base address instead for stolen memory */
	mgr->stolen_base = (xe_mmio_read64_2x32(mmio, DSMBASE) & BDSM_MASK) - tile_offset;
	if (drm_WARN_ON(&xe->drm, tile_size < mgr->stolen_base))
		return 0;

	/* Carve out the top of DSM as it contains the reserved WOPCM region */
	wopcm_size = get_wopcm_size(xe);
	if (drm_WARN_ON(&xe->drm, !wopcm_size))
		return 0;

	stolen_size = tile_size - mgr->stolen_base;

	xe_assert(xe, stolen_size >= wopcm_size);
	stolen_size -= wopcm_size;

Annotation

Implementation Notes