mirror of
https://github.com/torvalds/linux.git
synced 2025-11-02 09:40:27 +02:00
drm/xe/nvm: add on-die non-volatile memory device
Enable access to internal non-volatile memory on DGFX with GSC/CSC devices via a child device. The nvm child device is exposed via auxiliary bus. Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Link: https://lore.kernel.org/r/20250617145159.3803852-7-alexander.usyskin@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
parent
4b93f5fc3b
commit
c28bfb107d
6 changed files with 140 additions and 0 deletions
|
|
@ -80,6 +80,7 @@ xe-y += xe_bb.o \
|
|||
xe_mmio.o \
|
||||
xe_mocs.o \
|
||||
xe_module.o \
|
||||
xe_nvm.o \
|
||||
xe_oa.o \
|
||||
xe_observation.o \
|
||||
xe_pat.o \
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "xe_memirq.h"
|
||||
#include "xe_mmio.h"
|
||||
#include "xe_module.h"
|
||||
#include "xe_nvm.h"
|
||||
#include "xe_oa.h"
|
||||
#include "xe_observation.h"
|
||||
#include "xe_pat.h"
|
||||
|
|
@ -881,6 +882,8 @@ int xe_device_probe(struct xe_device *xe)
|
|||
return err;
|
||||
}
|
||||
|
||||
xe_nvm_init(xe);
|
||||
|
||||
err = xe_heci_gsc_init(xe);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
@ -938,6 +941,8 @@ void xe_device_remove(struct xe_device *xe)
|
|||
{
|
||||
xe_display_unregister(xe);
|
||||
|
||||
xe_nvm_fini(xe);
|
||||
|
||||
drm_dev_unplug(&xe->drm);
|
||||
|
||||
xe_bo_pci_dev_remove_all(xe);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
struct dram_info;
|
||||
struct intel_display;
|
||||
struct intel_dg_nvm_dev;
|
||||
struct xe_ggtt;
|
||||
struct xe_pat_ops;
|
||||
struct xe_pxp;
|
||||
|
|
@ -316,6 +317,8 @@ struct xe_device {
|
|||
u8 has_fan_control:1;
|
||||
/** @info.has_flat_ccs: Whether flat CCS metadata is used */
|
||||
u8 has_flat_ccs:1;
|
||||
/** @info.has_gsc_nvm: Device has gsc non-volatile memory */
|
||||
u8 has_gsc_nvm:1;
|
||||
/** @info.has_heci_cscfi: device has heci cscfi */
|
||||
u8 has_heci_cscfi:1;
|
||||
/** @info.has_heci_gscfi: device has heci gscfi */
|
||||
|
|
@ -549,6 +552,9 @@ struct xe_device {
|
|||
/** @heci_gsc: graphics security controller */
|
||||
struct xe_heci_gsc heci_gsc;
|
||||
|
||||
/** @nvm: discrete graphics non-volatile memory */
|
||||
struct intel_dg_nvm_dev *nvm;
|
||||
|
||||
/** @oa: oa observation subsystem */
|
||||
struct xe_oa oa;
|
||||
|
||||
|
|
|
|||
107
drivers/gpu/drm/xe/xe_nvm.c
Normal file
107
drivers/gpu/drm/xe/xe_nvm.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* Copyright(c) 2019-2025, Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/intel_dg_nvm_aux.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "xe_device_types.h"
|
||||
#include "xe_nvm.h"
|
||||
#include "xe_sriov.h"
|
||||
|
||||
#define GEN12_GUNIT_NVM_BASE 0x00102040
|
||||
#define GEN12_GUNIT_NVM_SIZE 0x80
|
||||
#define HECI_FW_STATUS_2_NVM_ACCESS_MODE BIT(3)
|
||||
|
||||
static const struct intel_dg_nvm_region regions[INTEL_DG_NVM_REGIONS] = {
|
||||
[0] = { .name = "DESCRIPTOR", },
|
||||
[2] = { .name = "GSC", },
|
||||
[9] = { .name = "PADDING", },
|
||||
[11] = { .name = "OptionROM", },
|
||||
[12] = { .name = "DAM", },
|
||||
};
|
||||
|
||||
static void xe_nvm_release_dev(struct device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
int xe_nvm_init(struct xe_device *xe)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
|
||||
struct auxiliary_device *aux_dev;
|
||||
struct intel_dg_nvm_dev *nvm;
|
||||
int ret;
|
||||
|
||||
if (!xe->info.has_gsc_nvm)
|
||||
return 0;
|
||||
|
||||
/* No access to internal NVM from VFs */
|
||||
if (IS_SRIOV_VF(xe))
|
||||
return 0;
|
||||
|
||||
/* Nvm pointer should be NULL here */
|
||||
if (WARN_ON(xe->nvm))
|
||||
return -EFAULT;
|
||||
|
||||
xe->nvm = kzalloc(sizeof(*nvm), GFP_KERNEL);
|
||||
if (!xe->nvm)
|
||||
return -ENOMEM;
|
||||
|
||||
nvm = xe->nvm;
|
||||
|
||||
nvm->writable_override = false;
|
||||
nvm->bar.parent = &pdev->resource[0];
|
||||
nvm->bar.start = GEN12_GUNIT_NVM_BASE + pdev->resource[0].start;
|
||||
nvm->bar.end = nvm->bar.start + GEN12_GUNIT_NVM_SIZE - 1;
|
||||
nvm->bar.flags = IORESOURCE_MEM;
|
||||
nvm->bar.desc = IORES_DESC_NONE;
|
||||
nvm->regions = regions;
|
||||
|
||||
aux_dev = &nvm->aux_dev;
|
||||
|
||||
aux_dev->name = "nvm";
|
||||
aux_dev->id = (pci_domain_nr(pdev->bus) << 16) | pci_dev_id(pdev);
|
||||
aux_dev->dev.parent = &pdev->dev;
|
||||
aux_dev->dev.release = xe_nvm_release_dev;
|
||||
|
||||
ret = auxiliary_device_init(aux_dev);
|
||||
if (ret) {
|
||||
drm_err(&xe->drm, "xe-nvm aux init failed %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = auxiliary_device_add(aux_dev);
|
||||
if (ret) {
|
||||
drm_err(&xe->drm, "xe-nvm aux add failed %d\n", ret);
|
||||
auxiliary_device_uninit(aux_dev);
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
kfree(nvm);
|
||||
xe->nvm = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void xe_nvm_fini(struct xe_device *xe)
|
||||
{
|
||||
struct intel_dg_nvm_dev *nvm = xe->nvm;
|
||||
|
||||
if (!xe->info.has_gsc_nvm)
|
||||
return;
|
||||
|
||||
/* No access to internal NVM from VFs */
|
||||
if (IS_SRIOV_VF(xe))
|
||||
return;
|
||||
|
||||
/* Nvm pointer should not be NULL here */
|
||||
if (WARN_ON(!nvm))
|
||||
return;
|
||||
|
||||
auxiliary_device_delete(&nvm->aux_dev);
|
||||
auxiliary_device_uninit(&nvm->aux_dev);
|
||||
kfree(nvm);
|
||||
xe->nvm = NULL;
|
||||
}
|
||||
15
drivers/gpu/drm/xe/xe_nvm.h
Normal file
15
drivers/gpu/drm/xe/xe_nvm.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright(c) 2019-2025 Intel Corporation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XE_NVM_H__
|
||||
#define __XE_NVM_H__
|
||||
|
||||
struct xe_device;
|
||||
|
||||
int xe_nvm_init(struct xe_device *xe);
|
||||
|
||||
void xe_nvm_fini(struct xe_device *xe);
|
||||
|
||||
#endif
|
||||
|
|
@ -63,6 +63,7 @@ struct xe_device_desc {
|
|||
|
||||
u8 has_display:1;
|
||||
u8 has_fan_control:1;
|
||||
u8 has_gsc_nvm:1;
|
||||
u8 has_heci_gscfi:1;
|
||||
u8 has_heci_cscfi:1;
|
||||
u8 has_llc:1;
|
||||
|
|
@ -272,6 +273,7 @@ static const struct xe_device_desc dg1_desc = {
|
|||
PLATFORM(DG1),
|
||||
.dma_mask_size = 39,
|
||||
.has_display = true,
|
||||
.has_gsc_nvm = 1,
|
||||
.has_heci_gscfi = 1,
|
||||
.require_force_probe = true,
|
||||
};
|
||||
|
|
@ -283,6 +285,7 @@ static const u16 dg2_g12_ids[] = { INTEL_DG2_G12_IDS(NOP), 0 };
|
|||
#define DG2_FEATURES \
|
||||
DGFX_FEATURES, \
|
||||
PLATFORM(DG2), \
|
||||
.has_gsc_nvm = 1, \
|
||||
.has_heci_gscfi = 1, \
|
||||
.subplatforms = (const struct xe_subplatform_desc[]) { \
|
||||
{ XE_SUBPLATFORM_DG2_G10, "G10", dg2_g10_ids }, \
|
||||
|
|
@ -319,6 +322,7 @@ static const __maybe_unused struct xe_device_desc pvc_desc = {
|
|||
PLATFORM(PVC),
|
||||
.dma_mask_size = 52,
|
||||
.has_display = false,
|
||||
.has_gsc_nvm = 1,
|
||||
.has_heci_gscfi = 1,
|
||||
.max_remote_tiles = 1,
|
||||
.require_force_probe = true,
|
||||
|
|
@ -349,6 +353,7 @@ static const struct xe_device_desc bmg_desc = {
|
|||
.has_display = true,
|
||||
.has_fan_control = true,
|
||||
.has_mbx_power_limits = true,
|
||||
.has_gsc_nvm = 1,
|
||||
.has_heci_cscfi = 1,
|
||||
.needs_scratch = true,
|
||||
};
|
||||
|
|
@ -592,6 +597,7 @@ static int xe_info_init_early(struct xe_device *xe,
|
|||
xe->info.is_dgfx = desc->is_dgfx;
|
||||
xe->info.has_fan_control = desc->has_fan_control;
|
||||
xe->info.has_mbx_power_limits = desc->has_mbx_power_limits;
|
||||
xe->info.has_gsc_nvm = desc->has_gsc_nvm;
|
||||
xe->info.has_heci_gscfi = desc->has_heci_gscfi;
|
||||
xe->info.has_heci_cscfi = desc->has_heci_cscfi;
|
||||
xe->info.has_llc = desc->has_llc;
|
||||
|
|
|
|||
Loading…
Reference in a new issue