From 7ceb94e87bffff7c12b61eb29749e1d8ac976896 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Fri, 2 Feb 2024 14:00:27 -0500 Subject: drm/amd: Add gfx12 swizzle mode defs Add GFX12 swizzle mode definitions for use with DCN401 Signed-off-by: Aurabindo Pillai Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- include/uapi/drm/drm_fourcc.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 84d502e42961..4168445fbb8b 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1476,6 +1476,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_TILE_VER_GFX10 2 #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 #define AMD_FMT_MOD_TILE_VER_GFX11 4 +#define AMD_FMT_MOD_TILE_VER_GFX12 5 /* * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical @@ -1486,6 +1487,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) /* * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has * GFX9 as canonical version. + * + * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. */ #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 @@ -1493,6 +1496,19 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 #define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31 +/* Gfx12 swizzle modes: + * 0 - LINEAR + * 1 - 256B_2D - 2D block dimensions + * 2 - 4KB_2D + * 3 - 64KB_2D + * 4 - 256KB_2D + * 5 - 4KB_3D - 3D block dimensions + * 6 - 64KB_3D + * 7 - 256KB_3D + */ +#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 +#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 + #define AMD_FMT_MOD_DCC_BLOCK_64B 0 #define AMD_FMT_MOD_DCC_BLOCK_128B 1 #define AMD_FMT_MOD_DCC_BLOCK_256B 2 -- cgit v1.2.3 From 7d09d80b93ab15c1ff969facb8f6111fb9c084ce Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Fri, 19 Apr 2024 12:17:56 -0400 Subject: drm/amd: define new gfx12 uapi flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit define new gfx12 uapi flags Signed-off-by: Marek Olšák Signed-off-by: Aurabindo Pillai Acked-by: Hawking Zhang Signed-off-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 96e32dafd4f0..feb47623458a 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -392,7 +392,7 @@ struct drm_amdgpu_gem_userptr { #define AMDGPU_TILING_NUM_BANKS_SHIFT 21 #define AMDGPU_TILING_NUM_BANKS_MASK 0x3 -/* GFX9 and later: */ +/* GFX9 - GFX11: */ #define AMDGPU_TILING_SWIZZLE_MODE_SHIFT 0 #define AMDGPU_TILING_SWIZZLE_MODE_MASK 0x1f #define AMDGPU_TILING_DCC_OFFSET_256B_SHIFT 5 @@ -406,6 +406,17 @@ struct drm_amdgpu_gem_userptr { #define AMDGPU_TILING_SCANOUT_SHIFT 63 #define AMDGPU_TILING_SCANOUT_MASK 0x1 +/* GFX12 and later: */ +#define AMDGPU_TILING_GFX12_SWIZZLE_MODE_SHIFT 0 +#define AMDGPU_TILING_GFX12_SWIZZLE_MODE_MASK 0x7 +/* These are DCC recompression setting for memory management: */ +#define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_SHIFT 3 +#define AMDGPU_TILING_GFX12_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 /* 0:64B, 1:128B, 2:256B */ +#define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_SHIFT 5 +#define AMDGPU_TILING_GFX12_DCC_NUMBER_TYPE_MASK 0x7 /* CB_COLOR0_INFO.NUMBER_TYPE */ +#define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_SHIFT 8 +#define AMDGPU_TILING_GFX12_DCC_DATA_FORMAT_MASK 0x3f /* [0:4]:CB_COLOR0_INFO.FORMAT, [5]:MM */ + /* Set/Get helpers for tiling flags. */ #define AMDGPU_TILING_SET(field, value) \ (((__u64)(value) & AMDGPU_TILING_##field##_MASK) << AMDGPU_TILING_##field##_SHIFT) @@ -1268,6 +1279,7 @@ struct drm_amdgpu_info_gpuvm_fault { #define AMDGPU_FAMILY_GC_10_3_6 149 /* GC 10.3.6 */ #define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */ #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ +#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ #if defined(__cplusplus) } -- cgit v1.2.3 From 96557f785a7701c7e0c327bd25b701d0eb5dcee0 Mon Sep 17 00:00:00 2001 From: Aurabindo Pillai Date: Tue, 5 Mar 2024 14:38:31 -0500 Subject: drm/amd: GFX12 changes for converting tiling flags to modifiers GFX12 swizzle mode and GCC formats changed and is much simpler. Use a seperate function for the same. Changes: * Swizzle mode is now 3 bits only * DCC enablement doesn't come from tiling_flags, it is always set in modifiers * DCC max compressed block size of 128B Signed-off-by: Aurabindo Pillai Acked-by: Rodrigo Siqueira Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 37 +++++++++++++++++++++++++++++ include/uapi/drm/drm_fourcc.h | 3 +++ 2 files changed, 40 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 3ecc7ef95172..cfec85563bc6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -718,6 +718,37 @@ extract_render_dcc_offset(struct amdgpu_device *adev, return 0; } +static int convert_tiling_flags_to_modifier_gfx12(struct amdgpu_framebuffer *afb) +{ + struct amdgpu_device *adev = drm_to_adev(afb->base.dev); + const struct drm_format_info *format_info; + u64 modifier = 0; + int tile = 0; + int swizzle = 0; + + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0)) { + tile = AMD_FMT_MOD_TILE_VER_GFX12; + swizzle = AMDGPU_TILING_GET(afb->tiling_flags, GFX12_SWIZZLE_MODE); + } + + modifier = + AMD_FMT_MOD | + AMD_FMT_MOD_SET(TILE, swizzle) | + AMD_FMT_MOD_SET(TILE_VERSION, tile) | + AMD_FMT_MOD_SET(DCC, 0) | + AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, 0); + + format_info = amdgpu_lookup_format_info(afb->base.format->format, + modifier); + if (!format_info) + return -EINVAL; + + afb->base.modifier = modifier; + afb->base.flags |= DRM_MODE_FB_MODIFIERS; + + return 0; +} + static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) { struct amdgpu_device *adev = drm_to_adev(afb->base.dev); @@ -742,6 +773,12 @@ static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb) int pipes = ilog2(num_pipes); uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B); + + if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 0, 0)) { + convert_tiling_flags_to_modifier_gfx12(afb); + return 0; + } + switch (swizzle >> 2) { case 0: /* 256B */ block_size_bits = 8; diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 4168445fbb8b..d0063ac6e09f 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1540,6 +1540,9 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18 #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 +#define AMD_FMT_MOD_GFX12_DCC_MAX_COMPRESSED_BLOCK_SHIFT 3 +#define AMD_FMT_MOD_GFX12_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 /* 0:64B, 1:128B, 2:256B */ + /* * DCC supports embedding some clear colors directly in the DCC surface. * However, on older GPUs the rendering HW ignores the embedded clear color -- cgit v1.2.3 From 155ce502e9adf9001d6fa35ca85843b7f0e538c7 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Fri, 5 Apr 2024 15:46:50 -0400 Subject: drm/amdgpu: Support contiguous VRAM allocation RDMA device with limited scatter-gather ability requires contiguous VRAM buffer allocation for RDMA peer direct support. Add a new KFD alloc memory flag and store as bo alloc flag AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS. When pin this bo to export for RDMA peerdirect access, this will set TTM_PL_FLAG_CONTIFUOUS flag, and ask VRAM buddy allocator to get contiguous VRAM. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 4 ++++ include/uapi/linux/kfd_ioctl.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index e4d4e55c08ad..5c06279c6bef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1712,6 +1712,10 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( alloc_flags = AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE; alloc_flags |= (flags & KFD_IOC_ALLOC_MEM_FLAGS_PUBLIC) ? AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED : 0; + + /* For contiguous VRAM allocation */ + if (flags & KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS) + alloc_flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; } xcp_id = fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION ? 0 : fpriv->xcp_id; diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 2040a470ddb4..d09c4a18e571 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -407,6 +407,7 @@ struct kfd_ioctl_acquire_vm_args { #define KFD_IOC_ALLOC_MEM_FLAGS_COHERENT (1 << 26) #define KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED (1 << 25) #define KFD_IOC_ALLOC_MEM_FLAGS_EXT_COHERENT (1 << 24) +#define KFD_IOC_ALLOC_MEM_FLAGS_CONTIGUOUS (1 << 23) /* Allocate memory for later SVM (shared virtual memory) mapping. * -- cgit v1.2.3 From 52666d8cc7f9c7810d25d5ef41f1a0b62153f368 Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Mon, 8 Apr 2024 09:26:56 -0400 Subject: drm/amdkfd: Bump kfd version for contiguous VRAM allocation Bump the kfd ioctl minor version to delcare the contiguous VRAM allocation flag support. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- include/uapi/linux/kfd_ioctl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index d09c4a18e571..f8e9d3c1d117 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -41,9 +41,10 @@ * - 1.13 - Add debugger API * - 1.14 - Update kfd_event_data * - 1.15 - Enable managing mappings in compute VMs with GEM_VA ioctl + * - 1.16 - Add contiguous VRAM allocation flag */ #define KFD_IOCTL_MAJOR_VERSION 1 -#define KFD_IOCTL_MINOR_VERSION 15 +#define KFD_IOCTL_MINOR_VERSION 16 struct kfd_ioctl_get_version_args { __u32 major_version; /* from KFD */ -- cgit v1.2.3 From 747bda7bb5b1644a06734900326847a5d353c448 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 19 Apr 2024 10:29:00 +0200 Subject: fbdev/deferred-io: Provide get_page hook in struct fb_deferred_io Add a callback for drivers to provide framebuffer pages to fbdev's deferred-I/O helpers. Implementations need to acquire a reference on the page before returning it. Returning NULL generates a SIGBUS signal. This will be useful for DRM's fbdev emulation with GEM-shmem buffer objects. v2: - fix typo in commit message (Javier) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-8-tzimmermann@suse.de --- drivers/video/fbdev/core/fb_defio.c | 4 ++++ include/linux/fb.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index c68c51d0ef70..5ee7e78c2cea 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -25,9 +25,13 @@ static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned long offs) { + struct fb_deferred_io *fbdefio = info->fbdefio; const void *screen_buffer = info->screen_buffer; struct page *page = NULL; + if (fbdefio->get_page) + return fbdefio->get_page(info, offs); + if (is_vmalloc_addr(screen_buffer + offs)) page = vmalloc_to_page(screen_buffer + offs); else if (info->fix.smem_start) diff --git a/include/linux/fb.h b/include/linux/fb.h index 811e47f9d1c3..5358edbb9c0b 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -225,6 +225,7 @@ struct fb_deferred_io { struct mutex lock; /* mutex that protects the pageref list */ struct list_head pagereflist; /* list of pagerefs for touched pages */ /* callback */ + struct page *(*get_page)(struct fb_info *info, unsigned long offset); void (*deferred_io)(struct fb_info *info, struct list_head *pagelist); }; #endif -- cgit v1.2.3 From 150f431a08317e0e0363a7f9147b6246d3b40ba6 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 19 Apr 2024 10:29:01 +0200 Subject: drm/fbdev: Add fbdev-shmem Add an fbdev emulation for SHMEM-based memory managers. The code is similar to fbdev-generic, but does not require an additional shadow buffer for mmap(). Fbdev-shmem operates directly on the buffer object's SHMEM pages. Fbdev's deferred-I/O mechanism updates the hardware state on write operations. The memory pages of GEM SHMEM cannot be detected by fbdefio. Therefore fbdev-shmem implements the .get_page() hook in struct fb_deferred_io. The fbdefio helpers call this hook to retrieve the page directly from fbdev-shmem instead of trying to detect it internally. v3: - clarify on get_page mechanism in commit description (Javier) v2: - use drm_driver_legacy_fb_format() (Geert) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-9-tzimmermann@suse.de --- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_fbdev_shmem.c | 316 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_fbdev_shmem.h | 15 ++ 3 files changed, 332 insertions(+) create mode 100644 drivers/gpu/drm/drm_fbdev_shmem.c create mode 100644 include/drm/drm_fbdev_shmem.h (limited to 'include') diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index f9ca4f8fa6c5..fc793c6dd299 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -108,6 +108,7 @@ drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += drm_fb_dma_helper.o obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o drm_shmem_helper-y := drm_gem_shmem_helper.o +drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o drm_suballoc_helper-y := drm_suballoc.o diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c b/drivers/gpu/drm/drm_fbdev_shmem.c new file mode 100644 index 000000000000..a85a8a8e2eb8 --- /dev/null +++ b/drivers/gpu/drm/drm_fbdev_shmem.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: MIT + +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* + * struct fb_ops + */ + +static int drm_fbdev_shmem_fb_open(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + /* No need to take a ref for fbcon because it unbinds on unregister */ + if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) + return -ENODEV; + + return 0; +} + +static int drm_fbdev_shmem_fb_release(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (user) + module_put(fb_helper->dev->driver->fops->owner); + + return 0; +} + +FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_shmem, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area); + +static int drm_fbdev_shmem_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0); + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + + if (shmem->map_wc) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + return fb_deferred_io_mmap(info, vma); +} + +static void drm_fbdev_shmem_fb_destroy(struct fb_info *info) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (!fb_helper->dev) + return; + + drm_fb_helper_fini(fb_helper); + + drm_client_buffer_vunmap(fb_helper->buffer); + drm_client_framebuffer_delete(fb_helper->buffer); + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} + +static const struct fb_ops drm_fbdev_shmem_fb_ops = { + .owner = THIS_MODULE, + .fb_open = drm_fbdev_shmem_fb_open, + .fb_release = drm_fbdev_shmem_fb_release, + __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_shmem), + DRM_FB_HELPER_DEFAULT_OPS, + __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_shmem), + .fb_mmap = drm_fbdev_shmem_fb_mmap, + .fb_destroy = drm_fbdev_shmem_fb_destroy, +}; + +static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned long offset) +{ + struct drm_fb_helper *fb_helper = info->par; + struct drm_framebuffer *fb = fb_helper->fb; + struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0); + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + unsigned int i = offset >> PAGE_SHIFT; + struct page *page; + + if (fb_WARN_ON_ONCE(info, offset > obj->size)) + return NULL; + + page = shmem->pages[i]; // protected by active vmap + if (page) + get_page(page); + fb_WARN_ON_ONCE(info, !page); + + return page; +} + +/* + * struct drm_fb_helper + */ + +static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; + struct drm_client_buffer *buffer; + struct drm_gem_shmem_object *shmem; + struct drm_framebuffer *fb; + struct fb_info *info; + u32 format; + struct iosys_map map; + int ret; + + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp, sizes->surface_depth); + buffer = drm_client_framebuffer_create(client, sizes->surface_width, + sizes->surface_height, format); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + shmem = to_drm_gem_shmem_obj(buffer->gem); + + fb = buffer->fb; + + ret = drm_client_buffer_vmap(buffer, &map); + if (ret) { + goto err_drm_client_buffer_delete; + } else if (drm_WARN_ON(dev, map.is_iomem)) { + ret = -ENODEV; /* I/O memory not supported; use generic emulation */ + goto err_drm_client_buffer_delete; + } + + fb_helper->buffer = buffer; + fb_helper->fb = fb; + + info = drm_fb_helper_alloc_info(fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_drm_client_buffer_vunmap; + } + + drm_fb_helper_fill_info(info, fb_helper, sizes); + + info->fbops = &drm_fbdev_shmem_fb_ops; + + /* screen */ + info->flags |= FBINFO_VIRTFB; /* system memory */ + if (!shmem->map_wc) + info->flags |= FBINFO_READS_FAST; /* signal caching */ + info->screen_size = sizes->surface_height * fb->pitches[0]; + info->screen_buffer = map.vaddr; + info->fix.smem_len = info->screen_size; + + /* deferred I/O */ + fb_helper->fbdefio.delay = HZ / 20; + fb_helper->fbdefio.get_page = drm_fbdev_shmem_get_page; + fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; + + info->fbdefio = &fb_helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) + goto err_drm_fb_helper_release_info; + + return 0; + +err_drm_fb_helper_release_info: + drm_fb_helper_release_info(fb_helper); +err_drm_client_buffer_vunmap: + fb_helper->fb = NULL; + fb_helper->buffer = NULL; + drm_client_buffer_vunmap(buffer); +err_drm_client_buffer_delete: + drm_client_framebuffer_delete(buffer); + return ret; +} + +static int drm_fbdev_shmem_helper_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + +static const struct drm_fb_helper_funcs drm_fbdev_shmem_helper_funcs = { + .fb_probe = drm_fbdev_shmem_helper_fb_probe, + .fb_dirty = drm_fbdev_shmem_helper_fb_dirty, +}; + +/* + * struct drm_client_funcs + */ + +static void drm_fbdev_shmem_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) { + drm_fb_helper_unregister_info(fb_helper); + } else { + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + } +} + +static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); + + return 0; +} + +static int drm_fbdev_shmem_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; + + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err_drm_err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper); + if (ret) + goto err_drm_fb_helper_fini; + + return 0; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "fbdev-shmem: Failed to setup emulation (ret=%d)\n", ret); + return ret; +} + +static const struct drm_client_funcs drm_fbdev_shmem_client_funcs = { + .owner = THIS_MODULE, + .unregister = drm_fbdev_shmem_client_unregister, + .restore = drm_fbdev_shmem_client_restore, + .hotplug = drm_fbdev_shmem_client_hotplug, +}; + +/** + * drm_fbdev_shmem_setup() - Setup fbdev emulation for GEM SHMEM helpers + * @dev: DRM device + * @preferred_bpp: Preferred bits per pixel for the device. + * 32 is used if this is zero. + * + * This function sets up fbdev emulation for GEM DMA drivers that support + * dumb buffers with a virtual address and that can be mmap'ed. + * drm_fbdev_shmem_setup() shall be called after the DRM driver registered + * the new DRM device with drm_dev_register(). + * + * Restore, hotplug events and teardown are all taken care of. Drivers that do + * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. + * Simple drivers might use drm_mode_config_helper_suspend(). + * + * This function is safe to call even when there are no connectors present. + * Setup will be retried on the next hotplug event. + * + * The fbdev is destroyed by drm_dev_unregister(). + */ +void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp) +{ + struct drm_fb_helper *fb_helper; + int ret; + + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); + + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return; + drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_shmem_helper_funcs); + + ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_shmem_client_funcs); + if (ret) { + drm_err(dev, "Failed to register client: %d\n", ret); + goto err_drm_client_init; + } + + drm_client_register(&fb_helper->client); + + return; + +err_drm_client_init: + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} +EXPORT_SYMBOL(drm_fbdev_shmem_setup); diff --git a/include/drm/drm_fbdev_shmem.h b/include/drm/drm_fbdev_shmem.h new file mode 100644 index 000000000000..fb43cadd1950 --- /dev/null +++ b/include/drm/drm_fbdev_shmem.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_FBDEV_SHMEM_H +#define DRM_FBDEV_SHMEM_H + +struct drm_device; + +#ifdef CONFIG_DRM_FBDEV_EMULATION +void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp); +#else +static inline void drm_fbdev_shmem_setup(struct drm_device *dev, unsigned int preferred_bpp) +{ } +#endif + +#endif -- cgit v1.2.3 From aae4682e5d66c1e1dc181fa341652e037237f144 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 19 Apr 2024 10:29:35 +0200 Subject: drm/fbdev-generic: Convert to fbdev-ttm Only TTM-based drivers use fbdev-generic. Rename it to fbdev-ttm and change the symbol infix from _generic_ to _ttm_. Link the source file into TTM helpers, so that it is only build if TTM-based drivers have been selected. Select DRM_TTM_HELPER for loongson. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-43-tzimmermann@suse.de --- Documentation/gpu/drm-kms-helpers.rst | 2 +- drivers/gpu/drm/Makefile | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 6 +- drivers/gpu/drm/drm_fbdev_generic.c | 349 ------------------------ drivers/gpu/drm/drm_fbdev_ttm.c | 349 ++++++++++++++++++++++++ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 +- drivers/gpu/drm/loongson/Kconfig | 1 + drivers/gpu/drm/loongson/lsdc_drv.c | 4 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 6 +- drivers/gpu/drm/qxl/qxl_drv.c | 4 +- drivers/gpu/drm/tiny/bochs.c | 4 +- drivers/gpu/drm/vboxvideo/vbox_drv.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 4 +- include/drm/drm_fbdev_generic.h | 15 - include/drm/drm_fbdev_ttm.h | 15 + 15 files changed, 386 insertions(+), 386 deletions(-) delete mode 100644 drivers/gpu/drm/drm_fbdev_generic.c create mode 100644 drivers/gpu/drm/drm_fbdev_ttm.c delete mode 100644 include/drm/drm_fbdev_generic.h create mode 100644 include/drm/drm_fbdev_ttm.h (limited to 'include') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 59cfe8a7a8ba..e46ab9b670ac 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -116,7 +116,7 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :export: -.. kernel-doc:: drivers/gpu/drm/drm_fbdev_generic.c +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c :export: format Helper Functions Reference diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index fc793c6dd299..68cc9258ffc4 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -118,6 +118,7 @@ drm_vram_helper-y := drm_gem_vram_helper.o obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o drm_ttm_helper-y := drm_gem_ttm_helper.o +drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o # @@ -143,9 +144,7 @@ drm_kms_helper-y := \ drm_self_refresh_helper.o \ drm_simple_kms_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o -drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \ - drm_fbdev_generic.o \ - drm_fb_helper.o +drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o # diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index ea14f1c8f430..4f76aa606ac9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -2318,9 +2318,9 @@ retry_init: !list_empty(&adev_to_drm(adev)->mode_config.connector_list)) { /* select 8 bpp console on low vram cards */ if (adev->gmc.real_vram_size <= (32*1024*1024)) - drm_fbdev_generic_setup(adev_to_drm(adev), 8); + drm_fbdev_ttm_setup(adev_to_drm(adev), 8); else - drm_fbdev_generic_setup(adev_to_drm(adev), 32); + drm_fbdev_ttm_setup(adev_to_drm(adev), 32); } ret = amdgpu_debugfs_init(adev); diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c deleted file mode 100644 index 97e579c33d84..000000000000 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -/* @user: 1=userspace, 0=fbcon */ -static int drm_fbdev_generic_fb_open(struct fb_info *info, int user) -{ - struct drm_fb_helper *fb_helper = info->par; - - /* No need to take a ref for fbcon because it unbinds on unregister */ - if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) - return -ENODEV; - - return 0; -} - -static int drm_fbdev_generic_fb_release(struct fb_info *info, int user) -{ - struct drm_fb_helper *fb_helper = info->par; - - if (user) - module_put(fb_helper->dev->driver->fops->owner); - - return 0; -} - -FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_generic, - drm_fb_helper_damage_range, - drm_fb_helper_damage_area); - -static void drm_fbdev_generic_fb_destroy(struct fb_info *info) -{ - struct drm_fb_helper *fb_helper = info->par; - void *shadow = info->screen_buffer; - - if (!fb_helper->dev) - return; - - fb_deferred_io_cleanup(info); - drm_fb_helper_fini(fb_helper); - vfree(shadow); - drm_client_framebuffer_delete(fb_helper->buffer); - - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); -} - -static const struct fb_ops drm_fbdev_generic_fb_ops = { - .owner = THIS_MODULE, - .fb_open = drm_fbdev_generic_fb_open, - .fb_release = drm_fbdev_generic_fb_release, - FB_DEFAULT_DEFERRED_OPS(drm_fbdev_generic), - DRM_FB_HELPER_DEFAULT_OPS, - .fb_destroy = drm_fbdev_generic_fb_destroy, -}; - -/* - * This function uses the client API to create a framebuffer backed by a dumb buffer. - */ -static int drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_client_dev *client = &fb_helper->client; - struct drm_device *dev = fb_helper->dev; - struct drm_client_buffer *buffer; - struct fb_info *info; - size_t screen_size; - void *screen_buffer; - u32 format; - int ret; - - drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", - sizes->surface_width, sizes->surface_height, - sizes->surface_bpp); - - format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); - buffer = drm_client_framebuffer_create(client, sizes->surface_width, - sizes->surface_height, format); - if (IS_ERR(buffer)) - return PTR_ERR(buffer); - - fb_helper->buffer = buffer; - fb_helper->fb = buffer->fb; - - screen_size = buffer->gem->size; - screen_buffer = vzalloc(screen_size); - if (!screen_buffer) { - ret = -ENOMEM; - goto err_drm_client_framebuffer_delete; - } - - info = drm_fb_helper_alloc_info(fb_helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto err_vfree; - } - - drm_fb_helper_fill_info(info, fb_helper, sizes); - - info->fbops = &drm_fbdev_generic_fb_ops; - - /* screen */ - info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; - info->screen_buffer = screen_buffer; - info->fix.smem_len = screen_size; - - /* deferred I/O */ - fb_helper->fbdefio.delay = HZ / 20; - fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; - - info->fbdefio = &fb_helper->fbdefio; - ret = fb_deferred_io_init(info); - if (ret) - goto err_drm_fb_helper_release_info; - - return 0; - -err_drm_fb_helper_release_info: - drm_fb_helper_release_info(fb_helper); -err_vfree: - vfree(screen_buffer); -err_drm_client_framebuffer_delete: - fb_helper->fb = NULL; - fb_helper->buffer = NULL; - drm_client_framebuffer_delete(buffer); - return ret; -} - -static void drm_fbdev_generic_damage_blit_real(struct drm_fb_helper *fb_helper, - struct drm_clip_rect *clip, - struct iosys_map *dst) -{ - struct drm_framebuffer *fb = fb_helper->fb; - size_t offset = clip->y1 * fb->pitches[0]; - size_t len = clip->x2 - clip->x1; - unsigned int y; - void *src; - - switch (drm_format_info_bpp(fb->format, 0)) { - case 1: - offset += clip->x1 / 8; - len = DIV_ROUND_UP(len + clip->x1 % 8, 8); - break; - case 2: - offset += clip->x1 / 4; - len = DIV_ROUND_UP(len + clip->x1 % 4, 4); - break; - case 4: - offset += clip->x1 / 2; - len = DIV_ROUND_UP(len + clip->x1 % 2, 2); - break; - default: - offset += clip->x1 * fb->format->cpp[0]; - len *= fb->format->cpp[0]; - break; - } - - src = fb_helper->info->screen_buffer + offset; - iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ - - for (y = clip->y1; y < clip->y2; y++) { - iosys_map_memcpy_to(dst, 0, src, len); - iosys_map_incr(dst, fb->pitches[0]); - src += fb->pitches[0]; - } -} - -static int drm_fbdev_generic_damage_blit(struct drm_fb_helper *fb_helper, - struct drm_clip_rect *clip) -{ - struct drm_client_buffer *buffer = fb_helper->buffer; - struct iosys_map map, dst; - int ret; - - /* - * We have to pin the client buffer to its current location while - * flushing the shadow buffer. In the general case, concurrent - * modesetting operations could try to move the buffer and would - * fail. The modeset has to be serialized by acquiring the reservation - * object of the underlying BO here. - * - * For fbdev emulation, we only have to protect against fbdev modeset - * operations. Nothing else will involve the client buffer's BO. So it - * is sufficient to acquire struct drm_fb_helper.lock here. - */ - mutex_lock(&fb_helper->lock); - - ret = drm_client_buffer_vmap_local(buffer, &map); - if (ret) - goto out; - - dst = map; - drm_fbdev_generic_damage_blit_real(fb_helper, clip, &dst); - - drm_client_buffer_vunmap_local(buffer); - -out: - mutex_unlock(&fb_helper->lock); - - return ret; -} - -static int drm_fbdev_generic_helper_fb_dirty(struct drm_fb_helper *helper, - struct drm_clip_rect *clip) -{ - struct drm_device *dev = helper->dev; - int ret; - - /* Call damage handlers only if necessary */ - if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) - return 0; - - ret = drm_fbdev_generic_damage_blit(helper, clip); - if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) - return ret; - - if (helper->fb->funcs->dirty) { - ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); - if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) - return ret; - } - - return 0; -} - -static const struct drm_fb_helper_funcs drm_fbdev_generic_helper_funcs = { - .fb_probe = drm_fbdev_generic_helper_fb_probe, - .fb_dirty = drm_fbdev_generic_helper_fb_dirty, -}; - -static void drm_fbdev_generic_client_unregister(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - - if (fb_helper->info) { - drm_fb_helper_unregister_info(fb_helper); - } else { - drm_client_release(&fb_helper->client); - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - } -} - -static int drm_fbdev_generic_client_restore(struct drm_client_dev *client) -{ - drm_fb_helper_lastclose(client->dev); - - return 0; -} - -static int drm_fbdev_generic_client_hotplug(struct drm_client_dev *client) -{ - struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - struct drm_device *dev = client->dev; - int ret; - - if (dev->fb_helper) - return drm_fb_helper_hotplug_event(dev->fb_helper); - - ret = drm_fb_helper_init(dev, fb_helper); - if (ret) - goto err_drm_err; - - if (!drm_drv_uses_atomic_modeset(dev)) - drm_helper_disable_unused_functions(dev); - - ret = drm_fb_helper_initial_config(fb_helper); - if (ret) - goto err_drm_fb_helper_fini; - - return 0; - -err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); -err_drm_err: - drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); - return ret; -} - -static const struct drm_client_funcs drm_fbdev_generic_client_funcs = { - .owner = THIS_MODULE, - .unregister = drm_fbdev_generic_client_unregister, - .restore = drm_fbdev_generic_client_restore, - .hotplug = drm_fbdev_generic_client_hotplug, -}; - -/** - * drm_fbdev_generic_setup() - Setup generic fbdev emulation - * @dev: DRM device - * @preferred_bpp: Preferred bits per pixel for the device. - * - * This function sets up generic fbdev emulation for drivers that supports - * dumb buffers with a virtual address and that can be mmap'ed. - * drm_fbdev_generic_setup() shall be called after the DRM driver registered - * the new DRM device with drm_dev_register(). - * - * Restore, hotplug events and teardown are all taken care of. Drivers that do - * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. - * Simple drivers might use drm_mode_config_helper_suspend(). - * - * In order to provide fixed mmap-able memory ranges, generic fbdev emulation - * uses a shadow buffer in system memory. The implementation blits the shadow - * fbdev buffer onto the real buffer in regular intervals. - * - * This function is safe to call even when there are no connectors present. - * Setup will be retried on the next hotplug event. - * - * The fbdev is destroyed by drm_dev_unregister(). - */ -void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ - struct drm_fb_helper *fb_helper; - int ret; - - drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); - drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); - if (!fb_helper) - return; - drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_generic_helper_funcs); - - ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_generic_client_funcs); - if (ret) { - drm_err(dev, "Failed to register client: %d\n", ret); - goto err_drm_client_init; - } - - drm_client_register(&fb_helper->client); - - return; - -err_drm_client_init: - drm_fb_helper_unprepare(fb_helper); - kfree(fb_helper); - return; -} -EXPORT_SYMBOL(drm_fbdev_generic_setup); diff --git a/drivers/gpu/drm/drm_fbdev_ttm.c b/drivers/gpu/drm/drm_fbdev_ttm.c new file mode 100644 index 000000000000..bb7898cd7dc6 --- /dev/null +++ b/drivers/gpu/drm/drm_fbdev_ttm.c @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +/* @user: 1=userspace, 0=fbcon */ +static int drm_fbdev_ttm_fb_open(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + /* No need to take a ref for fbcon because it unbinds on unregister */ + if (user && !try_module_get(fb_helper->dev->driver->fops->owner)) + return -ENODEV; + + return 0; +} + +static int drm_fbdev_ttm_fb_release(struct fb_info *info, int user) +{ + struct drm_fb_helper *fb_helper = info->par; + + if (user) + module_put(fb_helper->dev->driver->fops->owner); + + return 0; +} + +FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_ttm, + drm_fb_helper_damage_range, + drm_fb_helper_damage_area); + +static void drm_fbdev_ttm_fb_destroy(struct fb_info *info) +{ + struct drm_fb_helper *fb_helper = info->par; + void *shadow = info->screen_buffer; + + if (!fb_helper->dev) + return; + + fb_deferred_io_cleanup(info); + drm_fb_helper_fini(fb_helper); + vfree(shadow); + drm_client_framebuffer_delete(fb_helper->buffer); + + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); +} + +static const struct fb_ops drm_fbdev_ttm_fb_ops = { + .owner = THIS_MODULE, + .fb_open = drm_fbdev_ttm_fb_open, + .fb_release = drm_fbdev_ttm_fb_release, + FB_DEFAULT_DEFERRED_OPS(drm_fbdev_ttm), + DRM_FB_HELPER_DEFAULT_OPS, + .fb_destroy = drm_fbdev_ttm_fb_destroy, +}; + +/* + * This function uses the client API to create a framebuffer backed by a dumb buffer. + */ +static int drm_fbdev_ttm_helper_fb_probe(struct drm_fb_helper *fb_helper, + struct drm_fb_helper_surface_size *sizes) +{ + struct drm_client_dev *client = &fb_helper->client; + struct drm_device *dev = fb_helper->dev; + struct drm_client_buffer *buffer; + struct fb_info *info; + size_t screen_size; + void *screen_buffer; + u32 format; + int ret; + + drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n", + sizes->surface_width, sizes->surface_height, + sizes->surface_bpp); + + format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth); + buffer = drm_client_framebuffer_create(client, sizes->surface_width, + sizes->surface_height, format); + if (IS_ERR(buffer)) + return PTR_ERR(buffer); + + fb_helper->buffer = buffer; + fb_helper->fb = buffer->fb; + + screen_size = buffer->gem->size; + screen_buffer = vzalloc(screen_size); + if (!screen_buffer) { + ret = -ENOMEM; + goto err_drm_client_framebuffer_delete; + } + + info = drm_fb_helper_alloc_info(fb_helper); + if (IS_ERR(info)) { + ret = PTR_ERR(info); + goto err_vfree; + } + + drm_fb_helper_fill_info(info, fb_helper, sizes); + + info->fbops = &drm_fbdev_ttm_fb_ops; + + /* screen */ + info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST; + info->screen_buffer = screen_buffer; + info->fix.smem_len = screen_size; + + /* deferred I/O */ + fb_helper->fbdefio.delay = HZ / 20; + fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io; + + info->fbdefio = &fb_helper->fbdefio; + ret = fb_deferred_io_init(info); + if (ret) + goto err_drm_fb_helper_release_info; + + return 0; + +err_drm_fb_helper_release_info: + drm_fb_helper_release_info(fb_helper); +err_vfree: + vfree(screen_buffer); +err_drm_client_framebuffer_delete: + fb_helper->fb = NULL; + fb_helper->buffer = NULL; + drm_client_framebuffer_delete(buffer); + return ret; +} + +static void drm_fbdev_ttm_damage_blit_real(struct drm_fb_helper *fb_helper, + struct drm_clip_rect *clip, + struct iosys_map *dst) +{ + struct drm_framebuffer *fb = fb_helper->fb; + size_t offset = clip->y1 * fb->pitches[0]; + size_t len = clip->x2 - clip->x1; + unsigned int y; + void *src; + + switch (drm_format_info_bpp(fb->format, 0)) { + case 1: + offset += clip->x1 / 8; + len = DIV_ROUND_UP(len + clip->x1 % 8, 8); + break; + case 2: + offset += clip->x1 / 4; + len = DIV_ROUND_UP(len + clip->x1 % 4, 4); + break; + case 4: + offset += clip->x1 / 2; + len = DIV_ROUND_UP(len + clip->x1 % 2, 2); + break; + default: + offset += clip->x1 * fb->format->cpp[0]; + len *= fb->format->cpp[0]; + break; + } + + src = fb_helper->info->screen_buffer + offset; + iosys_map_incr(dst, offset); /* go to first pixel within clip rect */ + + for (y = clip->y1; y < clip->y2; y++) { + iosys_map_memcpy_to(dst, 0, src, len); + iosys_map_incr(dst, fb->pitches[0]); + src += fb->pitches[0]; + } +} + +static int drm_fbdev_ttm_damage_blit(struct drm_fb_helper *fb_helper, + struct drm_clip_rect *clip) +{ + struct drm_client_buffer *buffer = fb_helper->buffer; + struct iosys_map map, dst; + int ret; + + /* + * We have to pin the client buffer to its current location while + * flushing the shadow buffer. In the general case, concurrent + * modesetting operations could try to move the buffer and would + * fail. The modeset has to be serialized by acquiring the reservation + * object of the underlying BO here. + * + * For fbdev emulation, we only have to protect against fbdev modeset + * operations. Nothing else will involve the client buffer's BO. So it + * is sufficient to acquire struct drm_fb_helper.lock here. + */ + mutex_lock(&fb_helper->lock); + + ret = drm_client_buffer_vmap_local(buffer, &map); + if (ret) + goto out; + + dst = map; + drm_fbdev_ttm_damage_blit_real(fb_helper, clip, &dst); + + drm_client_buffer_vunmap_local(buffer); + +out: + mutex_unlock(&fb_helper->lock); + + return ret; +} + +static int drm_fbdev_ttm_helper_fb_dirty(struct drm_fb_helper *helper, + struct drm_clip_rect *clip) +{ + struct drm_device *dev = helper->dev; + int ret; + + /* Call damage handlers only if necessary */ + if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2)) + return 0; + + ret = drm_fbdev_ttm_damage_blit(helper, clip); + if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret)) + return ret; + + if (helper->fb->funcs->dirty) { + ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1); + if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret)) + return ret; + } + + return 0; +} + +static const struct drm_fb_helper_funcs drm_fbdev_ttm_helper_funcs = { + .fb_probe = drm_fbdev_ttm_helper_fb_probe, + .fb_dirty = drm_fbdev_ttm_helper_fb_dirty, +}; + +static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) { + drm_fb_helper_unregister_info(fb_helper); + } else { + drm_client_release(&fb_helper->client); + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + } +} + +static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client) +{ + drm_fb_helper_lastclose(client->dev); + + return 0; +} + +static int drm_fbdev_ttm_client_hotplug(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + struct drm_device *dev = client->dev; + int ret; + + if (dev->fb_helper) + return drm_fb_helper_hotplug_event(dev->fb_helper); + + ret = drm_fb_helper_init(dev, fb_helper); + if (ret) + goto err_drm_err; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper); + if (ret) + goto err_drm_fb_helper_fini; + + return 0; + +err_drm_fb_helper_fini: + drm_fb_helper_fini(fb_helper); +err_drm_err: + drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret); + return ret; +} + +static const struct drm_client_funcs drm_fbdev_ttm_client_funcs = { + .owner = THIS_MODULE, + .unregister = drm_fbdev_ttm_client_unregister, + .restore = drm_fbdev_ttm_client_restore, + .hotplug = drm_fbdev_ttm_client_hotplug, +}; + +/** + * drm_fbdev_ttm_setup() - Setup fbdev emulation for TTM-based drivers + * @dev: DRM device + * @preferred_bpp: Preferred bits per pixel for the device. + * + * This function sets up fbdev emulation for TTM-based drivers that support + * dumb buffers with a virtual address and that can be mmap'ed. + * drm_fbdev_ttm_setup() shall be called after the DRM driver registered + * the new DRM device with drm_dev_register(). + * + * Restore, hotplug events and teardown are all taken care of. Drivers that do + * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves. + * Simple drivers might use drm_mode_config_helper_suspend(). + * + * In order to provide fixed mmap-able memory ranges, fbdev emulation + * uses a shadow buffer in system memory. The implementation blits the shadow + * fbdev buffer onto the real buffer in regular intervals. + * + * This function is safe to call even when there are no connectors present. + * Setup will be retried on the next hotplug event. + * + * The fbdev is destroyed by drm_dev_unregister(). + */ +void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) +{ + struct drm_fb_helper *fb_helper; + int ret; + + drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); + drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); + + fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + if (!fb_helper) + return; + drm_fb_helper_prepare(dev, fb_helper, preferred_bpp, &drm_fbdev_ttm_helper_funcs); + + ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_ttm_client_funcs); + if (ret) { + drm_err(dev, "Failed to register client: %d\n", ret); + goto err_drm_client_init; + } + + drm_client_register(&fb_helper->client); + + return; + +err_drm_client_init: + drm_fb_helper_unprepare(fb_helper); + kfree(fb_helper); + return; +} +EXPORT_SYMBOL(drm_fbdev_ttm_setup); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 57c21ec452b7..9f9b19ea0587 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -339,7 +339,7 @@ static int hibmc_pci_probe(struct pci_dev *pdev, goto err_unload; } - drm_fbdev_generic_setup(dev, 32); + drm_fbdev_ttm_setup(dev, 32); return 0; diff --git a/drivers/gpu/drm/loongson/Kconfig b/drivers/gpu/drm/loongson/Kconfig index 8e59753e532d..9ed463a76ae2 100644 --- a/drivers/gpu/drm/loongson/Kconfig +++ b/drivers/gpu/drm/loongson/Kconfig @@ -6,6 +6,7 @@ config DRM_LOONGSON depends on LOONGARCH || MIPS || COMPILE_TEST select DRM_KMS_HELPER select DRM_TTM + select DRM_TTM_HELPER select I2C select I2C_ALGOBIT help diff --git a/drivers/gpu/drm/loongson/lsdc_drv.c b/drivers/gpu/drm/loongson/lsdc_drv.c index d8ff60b46abe..adc7344d2f80 100644 --- a/drivers/gpu/drm/loongson/lsdc_drv.c +++ b/drivers/gpu/drm/loongson/lsdc_drv.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -314,7 +314,7 @@ static int lsdc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - drm_fbdev_generic_setup(ddev, 32); + drm_fbdev_ttm_setup(ddev, 32); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index a947e1d5f309..a58c31089613 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include #include @@ -846,9 +846,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev, goto fail_drm_dev_init; if (nouveau_drm(drm_dev)->client.device.info.ram_size <= 32 * 1024 * 1024) - drm_fbdev_generic_setup(drm_dev, 8); + drm_fbdev_ttm_setup(drm_dev, 8); else - drm_fbdev_generic_setup(drm_dev, 32); + drm_fbdev_ttm_setup(drm_dev, 32); quirk_broken_nv_runpm(pdev); return 0; diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c index beee5563031a..5eb3f5719fdf 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.c +++ b/drivers/gpu/drm/qxl/qxl_drv.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include @@ -118,7 +118,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto modeset_cleanup; - drm_fbdev_generic_setup(&qdev->ddev, 32); + drm_fbdev_ttm_setup(&qdev->ddev, 32); return 0; modeset_cleanup: diff --git a/drivers/gpu/drm/tiny/bochs.c b/drivers/gpu/drm/tiny/bochs.c index c23c9f0cf49c..2d7ad808cc0e 100644 --- a/drivers/gpu/drm/tiny/bochs.c +++ b/drivers/gpu/drm/tiny/bochs.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -670,7 +670,7 @@ static int bochs_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent if (ret) goto err_hw_fini; - drm_fbdev_generic_setup(dev, 32); + drm_fbdev_ttm_setup(dev, 32); return ret; err_hw_fini: diff --git a/drivers/gpu/drm/vboxvideo/vbox_drv.c b/drivers/gpu/drm/vboxvideo/vbox_drv.c index cd9e66a06596..ef36834c8673 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ b/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,7 +80,7 @@ static int vbox_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_irq_fini; - drm_fbdev_generic_setup(&vbox->ddev, 32); + drm_fbdev_ttm_setup(&vbox->ddev, 32); return 0; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index bdad93864b98..4bf6da2b15fe 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include @@ -1685,7 +1685,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vmw_fifo_resource_inc(vmw); vmw_svga_enable(vmw); - drm_fbdev_generic_setup(&vmw->drm, 0); + drm_fbdev_ttm_setup(&vmw->drm, 0); vmw_debugfs_gem_init(vmw); vmw_debugfs_resource_managers_init(vmw); diff --git a/include/drm/drm_fbdev_generic.h b/include/drm/drm_fbdev_generic.h deleted file mode 100644 index 75799342098d..000000000000 --- a/include/drm/drm_fbdev_generic.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -#ifndef DRM_FBDEV_GENERIC_H -#define DRM_FBDEV_GENERIC_H - -struct drm_device; - -#ifdef CONFIG_DRM_FBDEV_EMULATION -void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp); -#else -static inline void drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) -{ } -#endif - -#endif diff --git a/include/drm/drm_fbdev_ttm.h b/include/drm/drm_fbdev_ttm.h new file mode 100644 index 000000000000..9e6c3bdf3537 --- /dev/null +++ b/include/drm/drm_fbdev_ttm.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_FBDEV_TTM_H +#define DRM_FBDEV_TTM_H + +struct drm_device; + +#ifdef CONFIG_DRM_FBDEV_EMULATION +void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp); +#else +static inline void drm_fbdev_ttm_setup(struct drm_device *dev, unsigned int preferred_bpp) +{ } +#endif + +#endif -- cgit v1.2.3 From 18bc074c226bfecd205bf031678f5e35ee55c3da Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Fri, 19 Apr 2024 10:29:36 +0200 Subject: drm/fbdev: Clean up fbdev documentation Rewrite some docs that are not up-to-date any longer. Remove the TODO item for fbdev-generic conversion, as the helper has been replaced. Make documentation for DMA, SHMEM and TTM emulation available. Signed-off-by: Thomas Zimmermann Cc: Jonathan Corbet Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240419083331.7761-44-tzimmermann@suse.de --- Documentation/gpu/drm-kms-helpers.rst | 12 +++++++++--- Documentation/gpu/todo.rst | 13 ------------- drivers/gpu/drm/drm_drv.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 11 ++--------- include/drm/drm_mode_config.h | 4 ++-- 5 files changed, 14 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index e46ab9b670ac..8435e8621cc0 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -110,15 +110,21 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :doc: fbdev helpers -.. kernel-doc:: include/drm/drm_fb_helper.h - :internal: +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_dma.c + :export: -.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c +.. kernel-doc:: drivers/gpu/drm/drm_fbdev_shmem.c :export: .. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c :export: +.. kernel-doc:: include/drm/drm_fb_helper.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c + :export: + format Helper Functions Reference ================================= diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index fb9ad120b141..e2a0585915b3 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -243,19 +243,6 @@ Contact: Maintainer of the driver you plan to convert Level: Intermediate -Convert drivers to use drm_fbdev_generic_setup() ------------------------------------------------- - -Most drivers can use drm_fbdev_generic_setup(). Driver have to implement -atomic modesetting and GEM vmap support. Historically, generic fbdev emulation -expected the framebuffer in system memory or system-like memory. By employing -struct iosys_map, drivers with frambuffers in I/O memory can be supported -as well. - -Contact: Maintainer of the driver you plan to convert - -Level: Intermediate - Reimplement functions in drm_fbdev_fb_ops without fbdev ------------------------------------------------------- diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 535b624d4c9d..b8186cf16230 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -346,7 +346,7 @@ void drm_minor_release(struct drm_minor *minor) * if (ret) * return ret; * - * drm_fbdev_generic_setup(drm, 32); + * drm_fbdev_{...}_setup(drm, 32); * * return 0; * } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d612133e2cf7..e2e19f49342e 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -85,12 +85,8 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * The fb helper functions are useful to provide an fbdev on top of a drm kernel * mode setting driver. They can be used mostly independently from the crtc * helper functions used by many drivers to implement the kernel mode setting - * interfaces. - * - * Drivers that support a dumb buffer with a virtual address and mmap support, - * should try out the generic fbdev emulation using drm_fbdev_generic_setup(). - * It will automatically set up deferred I/O if the driver requires a shadow - * buffer. + * interfaces. Drivers that use one of the shared memory managers, TTM, SHMEM, + * DMA, should instead use the corresponding fbdev emulation. * * Existing fbdev implementations should restore the fbdev console by using * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback. @@ -126,9 +122,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io * callback it will also schedule dirty_work with the damage collected from the * mmap page writes. - * - * Deferred I/O is not compatible with SHMEM. Such drivers should request an - * fbdev shadow buffer and call drm_fbdev_generic_setup() instead. */ static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc) diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 8de3c9a5f61b..ab0f167474b1 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -106,8 +106,8 @@ struct drm_mode_config_funcs { * Drivers implementing fbdev emulation use drm_kms_helper_hotplug_event() * to call this hook to inform the fbdev helper of output changes. * - * This hook is deprecated, drivers should instead use - * drm_fbdev_generic_setup() which takes care of any necessary + * This hook is deprecated, drivers should instead implement fbdev + * support with struct drm_client, which takes care of any necessary * hotplug event forwarding already without further involvement by * the driver. */ -- cgit v1.2.3 From 226e4ca5d4f683b3013947e495c6b433b35718b7 Mon Sep 17 00:00:00 2001 From: Likun Gao Date: Mon, 13 Feb 2023 18:19:27 +0800 Subject: drm/amdgpu: Add gfx v12_0_0 family id Add gfx v12_0_0 family id Signed-off-by: Likun Gao Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index feb47623458a..5b6c0055cfcf 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1279,7 +1279,7 @@ struct drm_amdgpu_info_gpuvm_fault { #define AMDGPU_FAMILY_GC_10_3_6 149 /* GC 10.3.6 */ #define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */ #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ -#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ +#define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ #if defined(__cplusplus) } -- cgit v1.2.3 From 9243240bed3859fba2d15c016902a4c73a186249 Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Mon, 21 Aug 2023 11:47:47 -0400 Subject: drm/amdkfd: enable single alu ops for gfx12 GFX12 debugging requires setting up precise ALU operation for catching ALU exceptions. Signed-off-by: Jonathan Kim Tested-by: Lancelot Six Reviewed-by: Eric Huang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 15 +++++++++++++-- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 4 ++++ include/uapi/linux/kfd_ioctl.h | 1 + include/uapi/linux/kfd_sysfs.h | 19 ++++++++++--------- 4 files changed, 28 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index d889e3545120..45b1975b149a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -25,6 +25,7 @@ #include "kfd_topology.h" #include #include +#include #define MAX_WATCH_ADDRESSES 4 @@ -497,14 +498,24 @@ int kfd_dbg_trap_set_flags(struct kfd_process *target, uint32_t *flags) int i, r = 0, rewind_count = 0; for (i = 0; i < target->n_pdds; i++) { - if (!kfd_dbg_is_per_vmid_supported(target->pdds[i]->dev) && + struct kfd_topology_device *topo_dev = + kfd_topology_device_by_id(target->pdds[i]->dev->id); + uint32_t caps = topo_dev->node_props.capability; + + if (!(caps | HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED) && (*flags & KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP)) { *flags = prev_flags; return -EACCES; } + + if (!(caps | HSA_CAP_TRAP_DEBUG_PRECISE_ALU_OPERATIONS_SUPPORTED) && + (*flags & KFD_DBG_TRAP_FLAG_SINGLE_ALU_OP)) { + *flags = prev_flags; + return -EACCES; + } } - target->dbg_flags = *flags & KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP; + target->dbg_flags = *flags; *flags = prev_flags; for (i = 0; i < target->n_pdds; i++) { struct kfd_process_device *pdd = target->pdds[i]; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 71bea1fcb838..ba326b43bec5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1929,6 +1929,10 @@ static void kfd_topology_set_capabilities(struct kfd_topology_device *dev) if (KFD_GC_VERSION(dev->gpu) >= IP_VERSION(11, 0, 0)) dev->node_props.capability |= HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED; + + if (KFD_GC_VERSION(dev->gpu) >= IP_VERSION(12, 0, 0)) + dev->node_props.capability |= + HSA_CAP_TRAP_DEBUG_PRECISE_ALU_OPERATIONS_SUPPORTED; } kfd_topology_set_dbg_firmware_support(dev); diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index f8e9d3c1d117..285a36601dc9 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -854,6 +854,7 @@ enum kfd_dbg_trap_address_watch_mode { /* Additional wave settings */ enum kfd_dbg_trap_flags { KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP = 1, + KFD_DBG_TRAP_FLAG_SINGLE_ALU_OP = 2, }; /* Trap exceptions */ diff --git a/include/uapi/linux/kfd_sysfs.h b/include/uapi/linux/kfd_sysfs.h index a51b7331e0b4..5e8d28617efa 100644 --- a/include/uapi/linux/kfd_sysfs.h +++ b/include/uapi/linux/kfd_sysfs.h @@ -51,15 +51,16 @@ /* Old buggy user mode depends on this being 0 */ #define HSA_CAP_RESERVED_WAS_SRAM_EDCSUPPORTED 0x00080000 -#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000 -#define HSA_CAP_RASEVENTNOTIFY 0x00200000 -#define HSA_CAP_ASIC_REVISION_MASK 0x03c00000 -#define HSA_CAP_ASIC_REVISION_SHIFT 22 -#define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000 -#define HSA_CAP_SVMAPI_SUPPORTED 0x08000000 -#define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000 -#define HSA_CAP_TRAP_DEBUG_FIRMWARE_SUPPORTED 0x20000000 -#define HSA_CAP_RESERVED 0xe00f8000 +#define HSA_CAP_MEM_EDCSUPPORTED 0x00100000 +#define HSA_CAP_RASEVENTNOTIFY 0x00200000 +#define HSA_CAP_ASIC_REVISION_MASK 0x03c00000 +#define HSA_CAP_ASIC_REVISION_SHIFT 22 +#define HSA_CAP_SRAM_EDCSUPPORTED 0x04000000 +#define HSA_CAP_SVMAPI_SUPPORTED 0x08000000 +#define HSA_CAP_FLAGS_COHERENTHOSTACCESS 0x10000000 +#define HSA_CAP_TRAP_DEBUG_FIRMWARE_SUPPORTED 0x20000000 +#define HSA_CAP_TRAP_DEBUG_PRECISE_ALU_OPERATIONS_SUPPORTED 0x40000000 +#define HSA_CAP_RESERVED 0x800f8000 /* debug_prop bits in node properties */ #define HSA_DBG_WATCH_ADDR_MASK_LO_BIT_MASK 0x0000000f -- cgit v1.2.3 From ef283674a17e000bb6b2ff05dd2ac5cbf2e3ae0d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 22 Apr 2024 11:58:57 +0300 Subject: drm/uapi: Move drm_color_ctm_3x4 out from drm_mode.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_color_ctm_3x4 is some undocumented amgdpu private uapi and thus has no business being in drm_mode.h. At least move it to some amdgpu specific header, albeit with the wrong namespace as maybe something somewhere is using this already? Cc: Harry Wentland Cc: Joshua Ashton Cc: Alex Deucher Fixes: 6872a189be50 ("drm/amd/display: Add 3x4 CTM support for plane CTM") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240422085857.17651-1-ville.syrjala@linux.intel.com Reviewed-by: Harry Wentland --- include/uapi/drm/amdgpu_drm.h | 9 +++++++++ include/uapi/drm/drm_mode.h | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 96e32dafd4f0..d5ebafacdd70 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1269,6 +1269,15 @@ struct drm_amdgpu_info_gpuvm_fault { #define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */ #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ +/* FIXME wrong namespace! */ +struct drm_color_ctm_3x4 { + /* + * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude + * (not two's complement!) format. + */ + __u64 matrix[12]; +}; + #if defined(__cplusplus) } #endif diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 1ca5c7e418fd..d390011b89b4 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -846,14 +846,6 @@ struct drm_color_ctm { __u64 matrix[9]; }; -struct drm_color_ctm_3x4 { - /* - * Conversion matrix with 3x4 dimensions in S31.32 sign-magnitude - * (not two's complement!) format. - */ - __u64 matrix[12]; -}; - struct drm_color_lut { /* * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and -- cgit v1.2.3 From 7fb8af6798e8d013017e4607505f58d9942fd671 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 29 Apr 2024 19:43:36 +0300 Subject: drm: deprecate driver date The driver date serves no useful purpose, because it's hardly ever updated. The information is misleading at best. As described in Documentation/gpu/drm-internals.rst: The driver date, formatted as YYYYMMDD, is meant to identify the date of the latest modification to the driver. However, as most drivers fail to update it, its value is mostly useless. The DRM core prints it to the kernel log at initialization time and passes it to userspace through the DRM_IOCTL_VERSION ioctl. Stop printing the driver date at init, and start returning the empty string "" as driver date through the DRM_IOCTL_VERSION ioctl. The driver date initialization in drivers and the struct drm_driver date member can be removed in follow-up. Reviewed-by: Hamza Mahfooz Acked-by: Simon Ser Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240429164336.1406480-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- Documentation/gpu/drm-internals.rst | 10 ++-------- drivers/gpu/drm/drm_drv.c | 4 ++-- drivers/gpu/drm/drm_ioctl.c | 5 +++-- include/drm/drm_drv.h | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst index 335de7fcddee..11d9a5730fb2 100644 --- a/Documentation/gpu/drm-internals.rst +++ b/Documentation/gpu/drm-internals.rst @@ -57,8 +57,8 @@ is larger than the driver minor, the DRM_IOCTL_SET_VERSION call will return an error. Otherwise the driver's set_version() method will be called with the requested version. -Name, Description and Date -~~~~~~~~~~~~~~~~~~~~~~~~~~ +Name and Description +~~~~~~~~~~~~~~~~~~~~ char \*name; char \*desc; char \*date; The driver name is printed to the kernel log at initialization time, @@ -69,12 +69,6 @@ The driver description is a purely informative string passed to userspace through the DRM_IOCTL_VERSION ioctl and otherwise unused by the kernel. -The driver date, formatted as YYYYMMDD, is meant to identify the date of -the latest modification to the driver. However, as most drivers fail to -update it, its value is mostly useless. The DRM core prints it to the -kernel log at initialization time and passes it to userspace through the -DRM_IOCTL_VERSION ioctl. - Module Initialization --------------------- diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index b8186cf16230..93543071a500 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -947,9 +947,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) } drm_panic_register(dev); - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", + DRM_INFO("Initialized %s %d.%d.%d for %s on minor %d\n", driver->name, driver->major, driver->minor, - driver->patchlevel, driver->date, + driver->patchlevel, dev->dev ? dev_name(dev->dev) : "virtual device", dev->primary ? dev->primary->index : dev->accel->index); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index e368fc084c77..89feb7306e47 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -529,9 +529,10 @@ int drm_version(struct drm_device *dev, void *data, version->version_patchlevel = dev->driver->patchlevel; err = drm_copy_field(version->name, &version->name_len, dev->driver->name); + + /* Driver date is deprecated. Return the empty string. */ if (!err) - err = drm_copy_field(version->date, &version->date_len, - dev->driver->date); + err = drm_copy_field(version->date, &version->date_len, ""); if (!err) err = drm_copy_field(version->desc, &version->desc_len, dev->driver->desc); diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h index 8878260d7529..cd37936c3926 100644 --- a/include/drm/drm_drv.h +++ b/include/drm/drm_drv.h @@ -411,7 +411,7 @@ struct drm_driver { char *name; /** @desc: driver description */ char *desc; - /** @date: driver date */ + /** @date: driver date, unused, to be removed */ char *date; /** -- cgit v1.2.3 From 3dbfbd101a5844f851da9ae6e90f59753c10ff42 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 May 2024 23:27:23 +0300 Subject: drm/edid: remove drm_do_get_edid() All users of drm_do_get_edid() have been converted to drm_edid_read_custom(). Remove the unused function to prevent new users from creeping in. Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20240513202723.261440-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_edid.c | 28 ---------------------------- include/drm/drm_edid.h | 4 ---- 2 files changed, 32 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 4f54c91b31b2..0f7c4c5b14b9 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2464,34 +2464,6 @@ fail: return NULL; } -/** - * drm_do_get_edid - get EDID data using a custom EDID block read function - * @connector: connector we're probing - * @read_block: EDID block read function - * @context: private data passed to the block read function - * - * When the I2C adapter connected to the DDC bus is hidden behind a device that - * exposes a different interface to read EDID blocks this function can be used - * to get EDID data using a custom block read function. - * - * As in the general case the DDC bus is accessible by the kernel at the I2C - * level, drivers must make all reasonable efforts to expose it as an I2C - * adapter and use drm_get_edid() instead of abusing this function. - * - * The EDID may be overridden using debugfs override_edid or firmware EDID - * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority - * order. Having either of them bypasses actual EDID reads. - * - * Return: Pointer to valid EDID or NULL if we couldn't find any. - */ -struct edid *drm_do_get_edid(struct drm_connector *connector, - read_block_fn read_block, - void *context) -{ - return _drm_do_get_edid(connector, read_block, context, NULL); -} -EXPORT_SYMBOL_GPL(drm_do_get_edid); - /** * drm_edid_raw - Get a pointer to the raw EDID data. * @drm_edid: drm_edid container diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index b085525e53e2..6bdfa254a1c1 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -423,10 +423,6 @@ static inline void drm_edid_decode_panel_id(u32 panel_id, char vend[4], u16 *pro } bool drm_probe_ddc(struct i2c_adapter *adapter); -struct edid *drm_do_get_edid(struct drm_connector *connector, - int (*get_edid_block)(void *data, u8 *buf, unsigned int block, - size_t len), - void *data); struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); struct edid *drm_get_edid_switcheroo(struct drm_connector *connector, -- cgit v1.2.3 From cdfad4db7756563db7d458216d9e3c2651dddc7d Mon Sep 17 00:00:00 2001 From: Tomasz Rusinowicz Date: Mon, 13 May 2024 14:04:27 +0200 Subject: accel/ivpu: Add NPU profiling support Implement time based Metric Streamer profiling UAPI. This is a generic mechanism allowing user mode tools to sample NPU metrics. These metrics are defined by the FW and transparent to the driver. The user space can check for this feature by checking DRM_IVPU_CAP_METRIC_STREAMER driver capability. Signed-off-by: Tomasz Rusinowicz Signed-off-by: Jacek Lawrynowicz Link: https://patchwork.freedesktop.org/patch/msgid/20240513120431.3187212-9-jacek.lawrynowicz@linux.intel.com --- drivers/accel/ivpu/Makefile | 3 +- drivers/accel/ivpu/ivpu_drv.c | 14 +- drivers/accel/ivpu/ivpu_drv.h | 3 + drivers/accel/ivpu/ivpu_jsm_msg.c | 98 ++++++++++++ drivers/accel/ivpu/ivpu_jsm_msg.h | 8 +- drivers/accel/ivpu/ivpu_ms.c | 309 ++++++++++++++++++++++++++++++++++++++ drivers/accel/ivpu/ivpu_ms.h | 36 +++++ drivers/accel/ivpu/ivpu_pm.c | 4 + include/uapi/drm/ivpu_accel.h | 69 ++++++++- 9 files changed, 540 insertions(+), 4 deletions(-) create mode 100644 drivers/accel/ivpu/ivpu_ms.c create mode 100644 drivers/accel/ivpu/ivpu_ms.h (limited to 'include') diff --git a/drivers/accel/ivpu/Makefile b/drivers/accel/ivpu/Makefile index 95ff7ad16338..1c67a73cfefe 100644 --- a/drivers/accel/ivpu/Makefile +++ b/drivers/accel/ivpu/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -# Copyright (C) 2023 Intel Corporation +# Copyright (C) 2023-2024 Intel Corporation intel_vpu-y := \ ivpu_drv.o \ @@ -13,6 +13,7 @@ intel_vpu-y := \ ivpu_jsm_msg.o \ ivpu_mmu.o \ ivpu_mmu_context.o \ + ivpu_ms.o \ ivpu_pm.o intel_vpu-$(CONFIG_DEBUG_FS) += ivpu_debugfs.o diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index ca4fcef7edf5..a02a1929f5a1 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -26,6 +26,7 @@ #include "ivpu_jsm_msg.h" #include "ivpu_mmu.h" #include "ivpu_mmu_context.h" +#include "ivpu_ms.h" #include "ivpu_pm.h" #ifndef DRIVER_VERSION_STR @@ -100,6 +101,7 @@ static void file_priv_release(struct kref *ref) mutex_unlock(&vdev->context_list_lock); pm_runtime_put_autosuspend(vdev->drm.dev); + mutex_destroy(&file_priv->ms_lock); mutex_destroy(&file_priv->lock); kfree(file_priv); } @@ -122,7 +124,7 @@ static int ivpu_get_capabilities(struct ivpu_device *vdev, struct drm_ivpu_param { switch (args->index) { case DRM_IVPU_CAP_METRIC_STREAMER: - args->value = 0; + args->value = 1; break; case DRM_IVPU_CAP_DMA_MEMORY_RANGE: args->value = 1; @@ -231,10 +233,13 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) goto err_dev_exit; } + INIT_LIST_HEAD(&file_priv->ms_instance_list); + file_priv->vdev = vdev; file_priv->bound = true; kref_init(&file_priv->ref); mutex_init(&file_priv->lock); + mutex_init(&file_priv->ms_lock); mutex_lock(&vdev->context_list_lock); @@ -263,6 +268,7 @@ err_xa_erase: xa_erase_irq(&vdev->context_xa, ctx_id); err_unlock: mutex_unlock(&vdev->context_list_lock); + mutex_destroy(&file_priv->ms_lock); mutex_destroy(&file_priv->lock); kfree(file_priv); err_dev_exit: @@ -278,6 +284,7 @@ static void ivpu_postclose(struct drm_device *dev, struct drm_file *file) ivpu_dbg(vdev, FILE, "file_priv close: ctx %u process %s pid %d\n", file_priv->ctx.id, current->comm, task_pid_nr(current)); + ivpu_ms_cleanup(file_priv); ivpu_file_priv_put(&file_priv); } @@ -288,6 +295,10 @@ static const struct drm_ioctl_desc ivpu_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(IVPU_BO_INFO, ivpu_bo_info_ioctl, 0), DRM_IOCTL_DEF_DRV(IVPU_SUBMIT, ivpu_submit_ioctl, 0), DRM_IOCTL_DEF_DRV(IVPU_BO_WAIT, ivpu_bo_wait_ioctl, 0), + DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_START, ivpu_ms_start_ioctl, 0), + DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_GET_DATA, ivpu_ms_get_data_ioctl, 0), + DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_STOP, ivpu_ms_stop_ioctl, 0), + DRM_IOCTL_DEF_DRV(IVPU_METRIC_STREAMER_GET_INFO, ivpu_ms_get_info_ioctl, 0), }; static int ivpu_wait_for_ready(struct ivpu_device *vdev) @@ -638,6 +649,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev) ivpu_prepare_for_reset(vdev); ivpu_shutdown(vdev); + ivpu_ms_cleanup_all(vdev); ivpu_jobs_abort_all(vdev); ivpu_job_done_consumer_fini(vdev); ivpu_pm_cancel_recovery(vdev); diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 9e9d85ad78ea..55341762b9d9 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -155,6 +155,9 @@ struct ivpu_file_priv { struct mutex lock; /* Protects cmdq */ struct ivpu_cmdq *cmdq[IVPU_NUM_CMDQS_PER_CTX]; struct ivpu_mmu_context ctx; + struct mutex ms_lock; /* Protects ms_instance_list, ms_info_bo */ + struct list_head ms_instance_list; + struct ivpu_bo *ms_info_bo; bool has_mmu_faults; bool bound; }; diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.c b/drivers/accel/ivpu/ivpu_jsm_msg.c index 4b260065ad72..e8dd73d947e4 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.c +++ b/drivers/accel/ivpu/ivpu_jsm_msg.c @@ -440,3 +440,101 @@ int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev) return ret; } + +int ivpu_jsm_metric_streamer_start(struct ivpu_device *vdev, u64 metric_group_mask, + u64 sampling_rate, u64 buffer_addr, u64 buffer_size) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_START }; + struct vpu_jsm_msg resp; + int ret; + + req.payload.metric_streamer_start.metric_group_mask = metric_group_mask; + req.payload.metric_streamer_start.sampling_rate = sampling_rate; + req.payload.metric_streamer_start.buffer_addr = buffer_addr; + req.payload.metric_streamer_start.buffer_size = buffer_size; + + ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_START_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + if (ret) { + ivpu_warn_ratelimited(vdev, "Failed to start metric streamer: ret %d\n", ret); + return ret; + } + + return ret; +} + +int ivpu_jsm_metric_streamer_stop(struct ivpu_device *vdev, u64 metric_group_mask) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_STOP }; + struct vpu_jsm_msg resp; + int ret; + + req.payload.metric_streamer_stop.metric_group_mask = metric_group_mask; + + ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_STOP_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + if (ret) + ivpu_warn_ratelimited(vdev, "Failed to stop metric streamer: ret %d\n", ret); + + return ret; +} + +int ivpu_jsm_metric_streamer_update(struct ivpu_device *vdev, u64 metric_group_mask, + u64 buffer_addr, u64 buffer_size, u64 *bytes_written) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_UPDATE }; + struct vpu_jsm_msg resp; + int ret; + + req.payload.metric_streamer_update.metric_group_mask = metric_group_mask; + req.payload.metric_streamer_update.buffer_addr = buffer_addr; + req.payload.metric_streamer_update.buffer_size = buffer_size; + + ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_UPDATE_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + if (ret) { + ivpu_warn_ratelimited(vdev, "Failed to update metric streamer: ret %d\n", ret); + return ret; + } + + if (buffer_size && resp.payload.metric_streamer_done.bytes_written > buffer_size) { + ivpu_warn_ratelimited(vdev, "MS buffer overflow: bytes_written %#llx > buffer_size %#llx\n", + resp.payload.metric_streamer_done.bytes_written, buffer_size); + return -EOVERFLOW; + } + + *bytes_written = resp.payload.metric_streamer_done.bytes_written; + + return ret; +} + +int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mask, u64 buffer_addr, + u64 buffer_size, u32 *sample_size, u64 *info_size) +{ + struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_METRIC_STREAMER_INFO }; + struct vpu_jsm_msg resp; + int ret; + + req.payload.metric_streamer_start.metric_group_mask = metric_group_mask; + req.payload.metric_streamer_start.buffer_addr = buffer_addr; + req.payload.metric_streamer_start.buffer_size = buffer_size; + + ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_METRIC_STREAMER_INFO_DONE, &resp, + VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); + if (ret) { + ivpu_warn_ratelimited(vdev, "Failed to get metric streamer info: ret %d\n", ret); + return ret; + } + + if (!resp.payload.metric_streamer_done.sample_size) { + ivpu_warn_ratelimited(vdev, "Invalid sample size\n"); + return -EBADMSG; + } + + if (sample_size) + *sample_size = resp.payload.metric_streamer_done.sample_size; + if (info_size) + *info_size = resp.payload.metric_streamer_done.bytes_written; + + return ret; +} diff --git a/drivers/accel/ivpu/ivpu_jsm_msg.h b/drivers/accel/ivpu/ivpu_jsm_msg.h index 357728295fe9..060363409fb3 100644 --- a/drivers/accel/ivpu/ivpu_jsm_msg.h +++ b/drivers/accel/ivpu/ivpu_jsm_msg.h @@ -34,5 +34,11 @@ int ivpu_jsm_hws_set_context_sched_properties(struct ivpu_device *vdev, u32 ctx_ int ivpu_jsm_hws_set_scheduling_log(struct ivpu_device *vdev, u32 engine_idx, u32 host_ssid, u64 vpu_log_buffer_va); int ivpu_jsm_hws_setup_priority_bands(struct ivpu_device *vdev); - +int ivpu_jsm_metric_streamer_start(struct ivpu_device *vdev, u64 metric_group_mask, + u64 sampling_rate, u64 buffer_addr, u64 buffer_size); +int ivpu_jsm_metric_streamer_stop(struct ivpu_device *vdev, u64 metric_group_mask); +int ivpu_jsm_metric_streamer_update(struct ivpu_device *vdev, u64 metric_group_mask, + u64 buffer_addr, u64 buffer_size, u64 *bytes_written); +int ivpu_jsm_metric_streamer_info(struct ivpu_device *vdev, u64 metric_group_mask, u64 buffer_addr, + u64 buffer_size, u32 *sample_size, u64 *info_size); #endif diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c new file mode 100644 index 000000000000..2f9d37f5c208 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (C) 2020-2024 Intel Corporation + */ + +#include + +#include "ivpu_drv.h" +#include "ivpu_gem.h" +#include "ivpu_jsm_msg.h" +#include "ivpu_ms.h" +#include "ivpu_pm.h" + +#define MS_INFO_BUFFER_SIZE SZ_16K +#define MS_NUM_BUFFERS 2 +#define MS_READ_PERIOD_MULTIPLIER 2 +#define MS_MIN_SAMPLE_PERIOD_NS 1000000 + +static struct ivpu_ms_instance * +get_instance_by_mask(struct ivpu_file_priv *file_priv, u64 metric_mask) +{ + struct ivpu_ms_instance *ms; + + lockdep_assert_held(&file_priv->ms_lock); + + list_for_each_entry(ms, &file_priv->ms_instance_list, ms_instance_node) + if (ms->mask == metric_mask) + return ms; + + return NULL; +} + +int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct ivpu_file_priv *file_priv = file->driver_priv; + struct drm_ivpu_metric_streamer_start *args = data; + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_ms_instance *ms; + u64 single_buff_size; + u32 sample_size; + int ret; + + if (!args->metric_group_mask || !args->read_period_samples || + args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) + return -EINVAL; + + mutex_lock(&file_priv->ms_lock); + + if (get_instance_by_mask(file_priv, args->metric_group_mask)) { + ivpu_err(vdev, "Instance already exists (mask %#llx)\n", args->metric_group_mask); + ret = -EALREADY; + goto unlock; + } + + ms = kzalloc(sizeof(*ms), GFP_KERNEL); + if (!ms) { + ret = -ENOMEM; + goto unlock; + } + + ms->mask = args->metric_group_mask; + + ret = ivpu_jsm_metric_streamer_info(vdev, ms->mask, 0, 0, &sample_size, NULL); + if (ret) + goto err_free_ms; + + single_buff_size = sample_size * + ((u64)args->read_period_samples * MS_READ_PERIOD_MULTIPLIER); + ms->bo = ivpu_bo_create_global(vdev, PAGE_ALIGN(single_buff_size * MS_NUM_BUFFERS), + DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE); + if (!ms->bo) { + ivpu_err(vdev, "Failed to allocate MS buffer (size %llu)\n", single_buff_size); + ret = -ENOMEM; + goto err_free_ms; + } + + ms->buff_size = ivpu_bo_size(ms->bo) / MS_NUM_BUFFERS; + ms->active_buff_vpu_addr = ms->bo->vpu_addr; + ms->inactive_buff_vpu_addr = ms->bo->vpu_addr + ms->buff_size; + ms->active_buff_ptr = ivpu_bo_vaddr(ms->bo); + ms->inactive_buff_ptr = ivpu_bo_vaddr(ms->bo) + ms->buff_size; + + ret = ivpu_jsm_metric_streamer_start(vdev, ms->mask, args->sampling_period_ns, + ms->active_buff_vpu_addr, ms->buff_size); + if (ret) + goto err_free_bo; + + args->sample_size = sample_size; + args->max_data_size = ivpu_bo_size(ms->bo); + list_add_tail(&ms->ms_instance_node, &file_priv->ms_instance_list); + goto unlock; + +err_free_bo: + ivpu_bo_free(ms->bo); +err_free_ms: + kfree(ms); +unlock: + mutex_unlock(&file_priv->ms_lock); + return ret; +} + +static int +copy_leftover_bytes(struct ivpu_ms_instance *ms, + void __user *user_ptr, u64 user_size, u64 *user_bytes_copied) +{ + u64 copy_bytes; + + if (ms->leftover_bytes) { + copy_bytes = min(user_size - *user_bytes_copied, ms->leftover_bytes); + if (copy_to_user(user_ptr + *user_bytes_copied, ms->leftover_addr, copy_bytes)) + return -EFAULT; + + ms->leftover_bytes -= copy_bytes; + ms->leftover_addr += copy_bytes; + *user_bytes_copied += copy_bytes; + } + + return 0; +} + +static int +copy_samples_to_user(struct ivpu_device *vdev, struct ivpu_ms_instance *ms, + void __user *user_ptr, u64 user_size, u64 *user_bytes_copied) +{ + u64 bytes_written; + int ret; + + *user_bytes_copied = 0; + + ret = copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied); + if (ret) + return ret; + + if (*user_bytes_copied == user_size) + return 0; + + ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, ms->inactive_buff_vpu_addr, + ms->buff_size, &bytes_written); + if (ret) + return ret; + + swap(ms->active_buff_vpu_addr, ms->inactive_buff_vpu_addr); + swap(ms->active_buff_ptr, ms->inactive_buff_ptr); + + ms->leftover_bytes = bytes_written; + ms->leftover_addr = ms->inactive_buff_ptr; + + return copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied); +} + +int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_ivpu_metric_streamer_get_data *args = data; + struct ivpu_file_priv *file_priv = file->driver_priv; + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_ms_instance *ms; + u64 bytes_written; + int ret; + + if (!args->metric_group_mask) + return -EINVAL; + + mutex_lock(&file_priv->ms_lock); + + ms = get_instance_by_mask(file_priv, args->metric_group_mask); + if (!ms) { + ivpu_err(vdev, "Instance doesn't exist for mask: %#llx\n", args->metric_group_mask); + ret = -EINVAL; + goto unlock; + } + + if (!args->buffer_size) { + ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, 0, 0, &bytes_written); + if (ret) + goto unlock; + args->data_size = bytes_written + ms->leftover_bytes; + goto unlock; + } + + if (!args->buffer_ptr) { + ret = -EINVAL; + goto unlock; + } + + ret = copy_samples_to_user(vdev, ms, u64_to_user_ptr(args->buffer_ptr), + args->buffer_size, &args->data_size); +unlock: + mutex_unlock(&file_priv->ms_lock); + + return ret; +} + +static void free_instance(struct ivpu_file_priv *file_priv, struct ivpu_ms_instance *ms) +{ + lockdep_assert_held(&file_priv->ms_lock); + + list_del(&ms->ms_instance_node); + ivpu_jsm_metric_streamer_stop(file_priv->vdev, ms->mask); + ivpu_bo_free(ms->bo); + kfree(ms); +} + +int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct ivpu_file_priv *file_priv = file->driver_priv; + struct drm_ivpu_metric_streamer_stop *args = data; + struct ivpu_ms_instance *ms; + + if (!args->metric_group_mask) + return -EINVAL; + + mutex_lock(&file_priv->ms_lock); + + ms = get_instance_by_mask(file_priv, args->metric_group_mask); + if (ms) + free_instance(file_priv, ms); + + mutex_unlock(&file_priv->ms_lock); + + return ms ? 0 : -EINVAL; +} + +static inline struct ivpu_bo *get_ms_info_bo(struct ivpu_file_priv *file_priv) +{ + lockdep_assert_held(&file_priv->ms_lock); + + if (file_priv->ms_info_bo) + return file_priv->ms_info_bo; + + file_priv->ms_info_bo = ivpu_bo_create_global(file_priv->vdev, MS_INFO_BUFFER_SIZE, + DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE); + return file_priv->ms_info_bo; +} + +int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_ivpu_metric_streamer_get_data *args = data; + struct ivpu_file_priv *file_priv = file->driver_priv; + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_bo *bo; + u64 info_size; + int ret; + + if (!args->metric_group_mask) + return -EINVAL; + + if (!args->buffer_size) + return ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask, + 0, 0, NULL, &args->data_size); + if (!args->buffer_ptr) + return -EINVAL; + + mutex_lock(&file_priv->ms_lock); + + bo = get_ms_info_bo(file_priv); + if (!bo) { + ret = -ENOMEM; + goto unlock; + } + + ret = ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask, bo->vpu_addr, + ivpu_bo_size(bo), NULL, &info_size); + if (ret) + goto unlock; + + if (args->buffer_size < info_size) { + ret = -ENOSPC; + goto unlock; + } + + if (copy_to_user(u64_to_user_ptr(args->buffer_ptr), ivpu_bo_vaddr(bo), info_size)) + ret = -EFAULT; + + args->data_size = info_size; +unlock: + mutex_unlock(&file_priv->ms_lock); + + return ret; +} + +void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv) +{ + struct ivpu_ms_instance *ms, *tmp; + + mutex_lock(&file_priv->ms_lock); + + if (file_priv->ms_info_bo) { + ivpu_bo_free(file_priv->ms_info_bo); + file_priv->ms_info_bo = NULL; + } + + list_for_each_entry_safe(ms, tmp, &file_priv->ms_instance_list, ms_instance_node) + free_instance(file_priv, ms); + + mutex_unlock(&file_priv->ms_lock); +} + +void ivpu_ms_cleanup_all(struct ivpu_device *vdev) +{ + struct ivpu_file_priv *file_priv; + unsigned long ctx_id; + + mutex_lock(&vdev->context_list_lock); + + xa_for_each(&vdev->context_xa, ctx_id, file_priv) + ivpu_ms_cleanup(file_priv); + + mutex_unlock(&vdev->context_list_lock); +} diff --git a/drivers/accel/ivpu/ivpu_ms.h b/drivers/accel/ivpu/ivpu_ms.h new file mode 100644 index 000000000000..fbd5ebebc3d9 --- /dev/null +++ b/drivers/accel/ivpu/ivpu_ms.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Copyright (C) 2020-2024 Intel Corporation + */ +#ifndef __IVPU_MS_H__ +#define __IVPU_MS_H__ + +#include + +struct drm_device; +struct drm_file; +struct ivpu_bo; +struct ivpu_device; +struct ivpu_file_priv; + +struct ivpu_ms_instance { + struct ivpu_bo *bo; + struct list_head ms_instance_node; + u64 mask; + u64 buff_size; + u64 active_buff_vpu_addr; + u64 inactive_buff_vpu_addr; + void *active_buff_ptr; + void *inactive_buff_ptr; + u64 leftover_bytes; + void *leftover_addr; +}; + +int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv); +void ivpu_ms_cleanup_all(struct ivpu_device *vdev); + +#endif /* __IVPU_MS_H__ */ diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 4f5ea466731f..7b2aa205fdec 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -18,6 +18,7 @@ #include "ivpu_job.h" #include "ivpu_jsm_msg.h" #include "ivpu_mmu.h" +#include "ivpu_ms.h" #include "ivpu_pm.h" static bool ivpu_disable_recovery; @@ -131,6 +132,7 @@ static void ivpu_pm_recovery_work(struct work_struct *work) ivpu_suspend(vdev); ivpu_pm_prepare_cold_boot(vdev); ivpu_jobs_abort_all(vdev); + ivpu_ms_cleanup_all(vdev); ret = ivpu_resume(vdev); if (ret) @@ -333,6 +335,8 @@ void ivpu_pm_reset_prepare_cb(struct pci_dev *pdev) ivpu_hw_reset(vdev); ivpu_pm_prepare_cold_boot(vdev); ivpu_jobs_abort_all(vdev); + ivpu_ms_cleanup_all(vdev); + ivpu_dbg(vdev, PM, "Pre-reset done.\n"); } diff --git a/include/uapi/drm/ivpu_accel.h b/include/uapi/drm/ivpu_accel.h index 19a13468eca5..084fb529e1e9 100644 --- a/include/uapi/drm/ivpu_accel.h +++ b/include/uapi/drm/ivpu_accel.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation */ #ifndef __UAPI_IVPU_DRM_H__ @@ -21,6 +21,10 @@ extern "C" { #define DRM_IVPU_BO_INFO 0x03 #define DRM_IVPU_SUBMIT 0x05 #define DRM_IVPU_BO_WAIT 0x06 +#define DRM_IVPU_METRIC_STREAMER_START 0x07 +#define DRM_IVPU_METRIC_STREAMER_STOP 0x08 +#define DRM_IVPU_METRIC_STREAMER_GET_DATA 0x09 +#define DRM_IVPU_METRIC_STREAMER_GET_INFO 0x0a #define DRM_IOCTL_IVPU_GET_PARAM \ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_GET_PARAM, struct drm_ivpu_param) @@ -40,6 +44,22 @@ extern "C" { #define DRM_IOCTL_IVPU_BO_WAIT \ DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_BO_WAIT, struct drm_ivpu_bo_wait) +#define DRM_IOCTL_IVPU_METRIC_STREAMER_START \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_START, \ + struct drm_ivpu_metric_streamer_start) + +#define DRM_IOCTL_IVPU_METRIC_STREAMER_STOP \ + DRM_IOW(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_STOP, \ + struct drm_ivpu_metric_streamer_stop) + +#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_DATA \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_DATA, \ + struct drm_ivpu_metric_streamer_get_data) + +#define DRM_IOCTL_IVPU_METRIC_STREAMER_GET_INFO \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_IVPU_METRIC_STREAMER_GET_INFO, \ + struct drm_ivpu_metric_streamer_get_data) + /** * DOC: contexts * @@ -336,6 +356,53 @@ struct drm_ivpu_bo_wait { __u32 pad; }; +/** + * struct drm_ivpu_metric_streamer_start - Start collecting metric data + */ +struct drm_ivpu_metric_streamer_start { + /** @metric_group_mask: Indicates metric streamer instance */ + __u64 metric_group_mask; + /** @sampling_period_ns: Sampling period in nanoseconds */ + __u64 sampling_period_ns; + /** + * @read_period_samples: + * + * Number of samples after which user space will try to read the data. + * Reading the data after significantly longer period may cause data loss. + */ + __u32 read_period_samples; + /** @sample_size: Returned size of a single sample in bytes */ + __u32 sample_size; + /** @max_data_size: Returned max @data_size from %DRM_IOCTL_IVPU_METRIC_STREAMER_GET_DATA */ + __u32 max_data_size; +}; + +/** + * struct drm_ivpu_metric_streamer_get_data - Copy collected metric data + */ +struct drm_ivpu_metric_streamer_get_data { + /** @metric_group_mask: Indicates metric streamer instance */ + __u64 metric_group_mask; + /** @buffer_ptr: A pointer to a destination for the copied data */ + __u64 buffer_ptr; + /** @buffer_size: Size of the destination buffer */ + __u64 buffer_size; + /** + * @data_size: Returned size of copied metric data + * + * If the @buffer_size is zero, returns the amount of data ready to be copied. + */ + __u64 data_size; +}; + +/** + * struct drm_ivpu_metric_streamer_stop - Stop collecting metric data + */ +struct drm_ivpu_metric_streamer_stop { + /** @metric_group_mask: Indicates metric streamer instance */ + __u64 metric_group_mask; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From 4b526132cce81cd2430d6548ea031b364538c5c0 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Fri, 10 May 2024 12:38:16 +0300 Subject: drm/panelreplay: dpcd register definition for panelreplay SU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add definitions for panel replay selective update v2: Remove unnecessary Cc from commit message Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Acked-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20240510093823.3146455-6-jouni.hogander@intel.com --- include/drm/display/drm_dp.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 0b032faa8cf2..906949ca3cee 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -548,6 +548,12 @@ # define DP_PANEL_REPLAY_SUPPORT (1 << 0) # define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1) +#define DP_PANEL_PANEL_REPLAY_CAPABILITY 0xb1 +# define DP_PANEL_PANEL_REPLAY_SU_GRANULARITY_REQUIRED (1 << 5) + +#define DP_PANEL_PANEL_REPLAY_X_GRANULARITY 0xb2 +#define DP_PANEL_PANEL_REPLAY_Y_GRANULARITY 0xb4 + /* Link Configuration */ #define DP_LINK_BW_SET 0x100 # define DP_LINK_RATE_TABLE 0x00 /* eDP 1.4 */ -- cgit v1.2.3 From 432ed92bfb5576865cd1fcc4cfed8a84d731b54a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:14 +0300 Subject: drm/i915/pciids: add INTEL_PNV_IDS(), use acronym Most other PCI ID macros use platform acronyms. Follow suit for PNV. Add INTEL_PNV_IDS() to identify all PNVs. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/5f9b34a2cd388244be03263a5147776bfe64d5ac.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 3 +-- drivers/gpu/drm/i915/display/intel_display_device.c | 3 +-- drivers/gpu/drm/i915/i915_pci.c | 4 ++-- include/drm/i915_pciids.h | 8 ++++++-- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 59f4aefc6bc1..f50394a00fca 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -527,8 +527,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_I945G_IDS(&gen3_early_ops), INTEL_I945GM_IDS(&gen3_early_ops), INTEL_VLV_IDS(&gen6_early_ops), - INTEL_PINEVIEW_G_IDS(&gen3_early_ops), - INTEL_PINEVIEW_M_IDS(&gen3_early_ops), + INTEL_PNV_IDS(&gen3_early_ops), INTEL_I965G_IDS(&gen3_early_ops), INTEL_G33_IDS(&gen3_early_ops), INTEL_I965GM_IDS(&gen3_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 56a2e17d7d9e..0e0f5a36507d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -815,8 +815,7 @@ static const struct { INTEL_I965GM_IDS(&i965gm_display), INTEL_GM45_IDS(&gm45_display), INTEL_G45_IDS(&g45_display), - INTEL_PINEVIEW_G_IDS(&pnv_display), - INTEL_PINEVIEW_M_IDS(&pnv_display), + INTEL_PNV_IDS(&pnv_display), INTEL_IRONLAKE_D_IDS(&ilk_d_display), INTEL_IRONLAKE_M_IDS(&ilk_m_display), INTEL_SNB_D_IDS(&snb_display), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 405ca17a990b..406e675c532a 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -810,8 +810,8 @@ static const struct pci_device_id pciidlist[] = { INTEL_I965GM_IDS(&i965gm_info), INTEL_GM45_IDS(&gm45_info), INTEL_G45_IDS(&g45_info), - INTEL_PINEVIEW_G_IDS(&pnv_g_info), - INTEL_PINEVIEW_M_IDS(&pnv_m_info), + INTEL_PNV_G_IDS(&pnv_g_info), + INTEL_PNV_M_IDS(&pnv_m_info), INTEL_IRONLAKE_D_IDS(&ilk_d_info), INTEL_IRONLAKE_M_IDS(&ilk_m_info), INTEL_SNB_D_GT1_IDS(&snb_d_gt1_info), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 85ce33ad6e26..21942a3c823b 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -108,12 +108,16 @@ INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \ INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */ -#define INTEL_PINEVIEW_G_IDS(info) \ +#define INTEL_PNV_G_IDS(info) \ INTEL_VGA_DEVICE(0xa001, info) -#define INTEL_PINEVIEW_M_IDS(info) \ +#define INTEL_PNV_M_IDS(info) \ INTEL_VGA_DEVICE(0xa011, info) +#define INTEL_PNV_IDS(info) \ + INTEL_PNV_G_IDS(info), \ + INTEL_PNV_M_IDS(info) + #define INTEL_IRONLAKE_D_IDS(info) \ INTEL_VGA_DEVICE(0x0042, info) -- cgit v1.2.3 From 41c0f8a36f15fab58cbbcf64f641250230725da8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:15 +0300 Subject: drm/i915/pciids: add INTEL_ILK_IDS(), use acronym Most other PCI ID macros use platform acronyms. Follow suit for ILK. Add INTEL_ILK_IDS() to identify all ILKs. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/27ada56363cfa6a5b093cb31908a4b89aa912621.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 3 +-- drivers/gpu/drm/i915/display/intel_display_device.c | 4 ++-- drivers/gpu/drm/i915/i915_pci.c | 4 ++-- include/drm/i915_pciids.h | 8 ++++++-- 4 files changed, 11 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index f50394a00fca..d8419d310091 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -533,8 +533,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_I965GM_IDS(&gen3_early_ops), INTEL_GM45_IDS(&gen3_early_ops), INTEL_G45_IDS(&gen3_early_ops), - INTEL_IRONLAKE_D_IDS(&gen3_early_ops), - INTEL_IRONLAKE_M_IDS(&gen3_early_ops), + INTEL_ILK_IDS(&gen3_early_ops), INTEL_SNB_D_IDS(&gen6_early_ops), INTEL_SNB_M_IDS(&gen6_early_ops), INTEL_IVB_M_IDS(&gen6_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 0e0f5a36507d..052fd1c290c3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -816,8 +816,8 @@ static const struct { INTEL_GM45_IDS(&gm45_display), INTEL_G45_IDS(&g45_display), INTEL_PNV_IDS(&pnv_display), - INTEL_IRONLAKE_D_IDS(&ilk_d_display), - INTEL_IRONLAKE_M_IDS(&ilk_m_display), + INTEL_ILK_D_IDS(&ilk_d_display), + INTEL_ILK_M_IDS(&ilk_m_display), INTEL_SNB_D_IDS(&snb_display), INTEL_SNB_M_IDS(&snb_display), INTEL_IVB_M_IDS(&ivb_display), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 406e675c532a..651b027e3701 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -812,8 +812,8 @@ static const struct pci_device_id pciidlist[] = { INTEL_G45_IDS(&g45_info), INTEL_PNV_G_IDS(&pnv_g_info), INTEL_PNV_M_IDS(&pnv_m_info), - INTEL_IRONLAKE_D_IDS(&ilk_d_info), - INTEL_IRONLAKE_M_IDS(&ilk_m_info), + INTEL_ILK_D_IDS(&ilk_d_info), + INTEL_ILK_M_IDS(&ilk_m_info), INTEL_SNB_D_GT1_IDS(&snb_d_gt1_info), INTEL_SNB_D_GT2_IDS(&snb_d_gt2_info), INTEL_SNB_M_GT1_IDS(&snb_m_gt1_info), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 21942a3c823b..05f466ca8ce2 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -118,12 +118,16 @@ INTEL_PNV_G_IDS(info), \ INTEL_PNV_M_IDS(info) -#define INTEL_IRONLAKE_D_IDS(info) \ +#define INTEL_ILK_D_IDS(info) \ INTEL_VGA_DEVICE(0x0042, info) -#define INTEL_IRONLAKE_M_IDS(info) \ +#define INTEL_ILK_M_IDS(info) \ INTEL_VGA_DEVICE(0x0046, info) +#define INTEL_ILK_IDS(info) \ + INTEL_ILK_D_IDS(info), \ + INTEL_ILK_M_IDS(info) + #define INTEL_SNB_D_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x0102, info), \ INTEL_VGA_DEVICE(0x010A, info) -- cgit v1.2.3 From 7b43a37348b7a3f07d2d7996539eb85f89e8acac Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:16 +0300 Subject: drm/i915/pciids: add INTEL_SNB_IDS() Add INTEL_SNB_IDS() to identify all SNBs. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/ffcb2d954ad9bca78ccd39836dc0a3dc7c6c0253.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 3 +-- drivers/gpu/drm/i915/display/intel_display_device.c | 3 +-- include/drm/i915_pciids.h | 4 ++++ 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index d8419d310091..23ded9260302 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -534,8 +534,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_GM45_IDS(&gen3_early_ops), INTEL_G45_IDS(&gen3_early_ops), INTEL_ILK_IDS(&gen3_early_ops), - INTEL_SNB_D_IDS(&gen6_early_ops), - INTEL_SNB_M_IDS(&gen6_early_ops), + INTEL_SNB_IDS(&gen6_early_ops), INTEL_IVB_M_IDS(&gen6_early_ops), INTEL_IVB_D_IDS(&gen6_early_ops), INTEL_HSW_IDS(&gen6_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 052fd1c290c3..c40d12ca386a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -818,8 +818,7 @@ static const struct { INTEL_PNV_IDS(&pnv_display), INTEL_ILK_D_IDS(&ilk_d_display), INTEL_ILK_M_IDS(&ilk_m_display), - INTEL_SNB_D_IDS(&snb_display), - INTEL_SNB_M_IDS(&snb_display), + INTEL_SNB_IDS(&snb_display), INTEL_IVB_M_IDS(&ivb_display), INTEL_IVB_D_IDS(&ivb_display), INTEL_HSW_IDS(&hsw_display), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 05f466ca8ce2..0d48c493dcce 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -151,6 +151,10 @@ INTEL_SNB_M_GT1_IDS(info), \ INTEL_SNB_M_GT2_IDS(info) +#define INTEL_SNB_IDS(info) \ + INTEL_SNB_D_IDS(info), \ + INTEL_SNB_M_IDS(info) + #define INTEL_IVB_M_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x0156, info) /* GT1 mobile */ -- cgit v1.2.3 From 5c8c22adc802b2abe6fc7933087d5a029545fdff Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:17 +0300 Subject: drm/i915/pciids: add INTEL_IVB_IDS() Add INTEL_IVB_IDS() to identify all IVBs except IVB Q transcode. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/ed89a25b2c6bce318fe59e883d18b62d9453196b.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 3 +-- drivers/gpu/drm/i915/display/intel_display_device.c | 3 +-- include/drm/i915_pciids.h | 4 ++++ 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 23ded9260302..6549507003ec 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -535,8 +535,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_G45_IDS(&gen3_early_ops), INTEL_ILK_IDS(&gen3_early_ops), INTEL_SNB_IDS(&gen6_early_ops), - INTEL_IVB_M_IDS(&gen6_early_ops), - INTEL_IVB_D_IDS(&gen6_early_ops), + INTEL_IVB_IDS(&gen6_early_ops), INTEL_HSW_IDS(&gen6_early_ops), INTEL_BDW_IDS(&gen8_early_ops), INTEL_CHV_IDS(&chv_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index c40d12ca386a..bb681c8ed8a0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -819,8 +819,7 @@ static const struct { INTEL_ILK_D_IDS(&ilk_d_display), INTEL_ILK_M_IDS(&ilk_m_display), INTEL_SNB_IDS(&snb_display), - INTEL_IVB_M_IDS(&ivb_display), - INTEL_IVB_D_IDS(&ivb_display), + INTEL_IVB_IDS(&ivb_display), INTEL_HSW_IDS(&hsw_display), INTEL_VLV_IDS(&vlv_display), INTEL_BDW_IDS(&bdw_display), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 0d48c493dcce..16778d92346b 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -177,6 +177,10 @@ INTEL_IVB_D_GT1_IDS(info), \ INTEL_IVB_D_GT2_IDS(info) +#define INTEL_IVB_IDS(info) \ + INTEL_IVB_M_IDS(info), \ + INTEL_IVB_D_IDS(info) + #define INTEL_IVB_Q_IDS(info) \ INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */ -- cgit v1.2.3 From aa3d586e16242ada8e865f79249e4b6ac0c7704c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:18 +0300 Subject: drm/i915/pciids: don't include WHL/CML PCI IDs in CFL It's confusing for INTEL_CFL_IDS() to include all WHL and CML PCI IDs. Even if we treat them the same in a lot of places, CML is a platform of its own, and the lists of PCI IDs should not conflate them. Largely go by the idea that if a platform has a name, group its PCI IDs together. That said, AML is special, having both KBL and CFL variants. Leave that alone. v2: Also split out WHL not just CML (Rodrigo) Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/7cca91dc78ed2b5982f14e400f03a1704645e475.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 2 ++ .../gpu/drm/i915/display/intel_display_device.c | 2 ++ include/drm/i915_pciids.h | 30 ++++++++++++---------- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 6549507003ec..2b698a3f56ef 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -543,6 +543,8 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_BXT_IDS(&gen9_early_ops), INTEL_KBL_IDS(&gen9_early_ops), INTEL_CFL_IDS(&gen9_early_ops), + INTEL_WHL_IDS(&gen9_early_ops), + INTEL_CML_IDS(&gen9_early_ops), INTEL_GLK_IDS(&gen9_early_ops), INTEL_CNL_IDS(&gen9_early_ops), INTEL_ICL_11_IDS(&gen11_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index bb681c8ed8a0..23909a8e2dc8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -829,6 +829,8 @@ static const struct { INTEL_GLK_IDS(&glk_display), INTEL_KBL_IDS(&skl_display), INTEL_CFL_IDS(&skl_display), + INTEL_WHL_IDS(&skl_display), + INTEL_CML_IDS(&skl_display), INTEL_ICL_11_IDS(&icl_display), INTEL_EHL_IDS(&jsl_ehl_display), INTEL_JSL_IDS(&jsl_ehl_display), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 16778d92346b..0c5a20d59801 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -488,6 +488,12 @@ INTEL_VGA_DEVICE(0x9BCA, info), \ INTEL_VGA_DEVICE(0x9BCC, info) +#define INTEL_CML_IDS(info) \ + INTEL_CML_GT1_IDS(info), \ + INTEL_CML_GT2_IDS(info), \ + INTEL_CML_U_GT1_IDS(info), \ + INTEL_CML_U_GT2_IDS(info) + #define INTEL_KBL_IDS(info) \ INTEL_KBL_GT1_IDS(info), \ INTEL_KBL_GT2_IDS(info), \ @@ -527,6 +533,15 @@ INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \ INTEL_VGA_DEVICE(0x3EA8, info) /* ULT GT3 */ +#define INTEL_CFL_IDS(info) \ + INTEL_CFL_S_GT1_IDS(info), \ + INTEL_CFL_S_GT2_IDS(info), \ + INTEL_CFL_H_GT1_IDS(info), \ + INTEL_CFL_H_GT2_IDS(info), \ + INTEL_CFL_U_GT2_IDS(info), \ + INTEL_CFL_U_GT3_IDS(info), \ + INTEL_AML_CFL_GT2_IDS(info) + /* WHL/CFL U GT1 */ #define INTEL_WHL_U_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x3EA1, info), \ @@ -541,21 +556,10 @@ #define INTEL_WHL_U_GT3_IDS(info) \ INTEL_VGA_DEVICE(0x3EA2, info) -#define INTEL_CFL_IDS(info) \ - INTEL_CFL_S_GT1_IDS(info), \ - INTEL_CFL_S_GT2_IDS(info), \ - INTEL_CFL_H_GT1_IDS(info), \ - INTEL_CFL_H_GT2_IDS(info), \ - INTEL_CFL_U_GT2_IDS(info), \ - INTEL_CFL_U_GT3_IDS(info), \ +#define INTEL_WHL_IDS(info) \ INTEL_WHL_U_GT1_IDS(info), \ INTEL_WHL_U_GT2_IDS(info), \ - INTEL_WHL_U_GT3_IDS(info), \ - INTEL_AML_CFL_GT2_IDS(info), \ - INTEL_CML_GT1_IDS(info), \ - INTEL_CML_GT2_IDS(info), \ - INTEL_CML_U_GT1_IDS(info), \ - INTEL_CML_U_GT2_IDS(info) + INTEL_WHL_U_GT3_IDS(info) /* CNL */ #define INTEL_CNL_PORT_F_IDS(info) \ -- cgit v1.2.3 From bfbda472276704d7b7f065a646a67b30b7a89730 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:19 +0300 Subject: drm/i915/pciids: remove 11 from INTEL_ICL_IDS() Most other PCI ID macros do not encode the gen in the name. Follow suit for ICL. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/36973674bf333dfdd7cd32ae656754bfa150022b.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 2 +- drivers/gpu/drm/i915/display/intel_display_device.c | 2 +- drivers/gpu/drm/i915/i915_pci.c | 2 +- include/drm/i915_pciids.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 2b698a3f56ef..c150bb6f1a39 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -547,7 +547,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_CML_IDS(&gen9_early_ops), INTEL_GLK_IDS(&gen9_early_ops), INTEL_CNL_IDS(&gen9_early_ops), - INTEL_ICL_11_IDS(&gen11_early_ops), + INTEL_ICL_IDS(&gen11_early_ops), INTEL_EHL_IDS(&gen11_early_ops), INTEL_JSL_IDS(&gen11_early_ops), INTEL_TGL_12_IDS(&gen11_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 23909a8e2dc8..e47896002c13 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -831,7 +831,7 @@ static const struct { INTEL_CFL_IDS(&skl_display), INTEL_WHL_IDS(&skl_display), INTEL_CML_IDS(&skl_display), - INTEL_ICL_11_IDS(&icl_display), + INTEL_ICL_IDS(&icl_display), INTEL_EHL_IDS(&jsl_ehl_display), INTEL_JSL_IDS(&jsl_ehl_display), INTEL_TGL_12_IDS(&tgl_display), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 651b027e3701..9e6d9072de35 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -857,7 +857,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_CML_GT2_IDS(&cml_gt2_info), INTEL_CML_U_GT1_IDS(&cml_gt1_info), INTEL_CML_U_GT2_IDS(&cml_gt2_info), - INTEL_ICL_11_IDS(&icl_info), + INTEL_ICL_IDS(&icl_info), INTEL_EHL_IDS(&ehl_info), INTEL_JSL_IDS(&jsl_info), INTEL_TGL_12_IDS(&tgl_info), diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 0c5a20d59801..ecfd7f71e2e7 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -597,7 +597,7 @@ INTEL_VGA_DEVICE(0x8A70, info), \ INTEL_VGA_DEVICE(0x8A71, info) -#define INTEL_ICL_11_IDS(info) \ +#define INTEL_ICL_IDS(info) \ INTEL_ICL_PORT_F_IDS(info), \ INTEL_VGA_DEVICE(0x8A51, info), \ INTEL_VGA_DEVICE(0x8A5D, info) -- cgit v1.2.3 From 7858cc0b55e3d44cb0a5a033207c78fc2d5f4df9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:20 +0300 Subject: drm/i915/pciids: remove 12 from INTEL_TGL_IDS() Most other PCI ID macros do not encode the gen in the name. Follow suit for TGL. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/044a5c553dc4564431bbef197d5e2dd085624fc2.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 2 +- drivers/gpu/drm/i915/display/intel_display_device.c | 2 +- drivers/gpu/drm/i915/i915_pci.c | 2 +- drivers/gpu/drm/i915/intel_device_info.c | 2 +- include/drm/i915_pciids.h | 10 +++++----- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index c150bb6f1a39..b2b9cc3b9545 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -550,7 +550,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_ICL_IDS(&gen11_early_ops), INTEL_EHL_IDS(&gen11_early_ops), INTEL_JSL_IDS(&gen11_early_ops), - INTEL_TGL_12_IDS(&gen11_early_ops), + INTEL_TGL_IDS(&gen11_early_ops), INTEL_RKL_IDS(&gen11_early_ops), INTEL_ADLS_IDS(&gen11_early_ops), INTEL_ADLP_IDS(&gen11_early_ops), diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index e47896002c13..fb4c4054207e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -834,7 +834,7 @@ static const struct { INTEL_ICL_IDS(&icl_display), INTEL_EHL_IDS(&jsl_ehl_display), INTEL_JSL_IDS(&jsl_ehl_display), - INTEL_TGL_12_IDS(&tgl_display), + INTEL_TGL_IDS(&tgl_display), INTEL_DG1_IDS(&dg1_display), INTEL_RKL_IDS(&rkl_display), INTEL_ADLS_IDS(&adl_s_display), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 9e6d9072de35..fe5cb3fcfe73 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -860,7 +860,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_ICL_IDS(&icl_info), INTEL_EHL_IDS(&ehl_info), INTEL_JSL_IDS(&jsl_info), - INTEL_TGL_12_IDS(&tgl_info), + INTEL_TGL_IDS(&tgl_info), INTEL_RKL_IDS(&rkl_info), INTEL_ADLS_IDS(&adl_s_info), INTEL_ADLP_IDS(&adl_p_info), diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index a0a43ea07f11..64651a54a245 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -173,7 +173,7 @@ static const u16 subplatform_portf_ids[] = { }; static const u16 subplatform_uy_ids[] = { - INTEL_TGL_12_GT2_IDS(0), + INTEL_TGL_GT2_IDS(0), }; static const u16 subplatform_n_ids[] = { diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index ecfd7f71e2e7..42913d2eb655 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -620,12 +620,12 @@ INTEL_VGA_DEVICE(0x4E71, info) /* TGL */ -#define INTEL_TGL_12_GT1_IDS(info) \ +#define INTEL_TGL_GT1_IDS(info) \ INTEL_VGA_DEVICE(0x9A60, info), \ INTEL_VGA_DEVICE(0x9A68, info), \ INTEL_VGA_DEVICE(0x9A70, info) -#define INTEL_TGL_12_GT2_IDS(info) \ +#define INTEL_TGL_GT2_IDS(info) \ INTEL_VGA_DEVICE(0x9A40, info), \ INTEL_VGA_DEVICE(0x9A49, info), \ INTEL_VGA_DEVICE(0x9A59, info), \ @@ -635,9 +635,9 @@ INTEL_VGA_DEVICE(0x9AD9, info), \ INTEL_VGA_DEVICE(0x9AF8, info) -#define INTEL_TGL_12_IDS(info) \ - INTEL_TGL_12_GT1_IDS(info), \ - INTEL_TGL_12_GT2_IDS(info) +#define INTEL_TGL_IDS(info) \ + INTEL_TGL_GT1_IDS(info), \ + INTEL_TGL_GT2_IDS(info) /* RKL */ #define INTEL_RKL_IDS(info) \ -- cgit v1.2.3 From d2c4b1db1c4f9e59ccb2d65aa1840420a059bf46 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 14:22:21 +0300 Subject: drm/i915/pciids: don't include RPL-U PCI IDs in RPL-P It's confusing for INTEL_RPLP_IDS() to include INTEL_RPLU_IDS(). Even if we treat them the same elsewhere, the lists of PCI IDs should not. Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Reviewed-by: Rodrigo Vivi Acked-by: Bjorn Helgaas Link: https://patchwork.freedesktop.org/patch/msgid/28fe0910efb93a28c400728af14beff015667f42.1715340032.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 1 + drivers/gpu/drm/i915/display/intel_display_device.c | 1 + drivers/gpu/drm/i915/i915_pci.c | 1 + drivers/gpu/drm/i915/intel_device_info.c | 1 + include/drm/i915_pciids.h | 1 - 5 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index b2b9cc3b9545..fd74d7f26f01 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -556,6 +556,7 @@ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_ADLP_IDS(&gen11_early_ops), INTEL_ADLN_IDS(&gen11_early_ops), INTEL_RPLS_IDS(&gen11_early_ops), + INTEL_RPLU_IDS(&gen11_early_ops), INTEL_RPLP_IDS(&gen11_early_ops), }; diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index fb4c4054207e..89069cff06b4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -841,6 +841,7 @@ static const struct { INTEL_RPLS_IDS(&adl_s_display), INTEL_ADLP_IDS(&xe_lpd_display), INTEL_ADLN_IDS(&xe_lpd_display), + INTEL_RPLU_IDS(&xe_lpd_display), INTEL_RPLP_IDS(&xe_lpd_display), INTEL_DG2_IDS(&xe_hpd_display), diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index fe5cb3fcfe73..0edd550d8555 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -867,6 +867,7 @@ static const struct pci_device_id pciidlist[] = { INTEL_ADLN_IDS(&adl_p_info), INTEL_DG1_IDS(&dg1_info), INTEL_RPLS_IDS(&adl_s_info), + INTEL_RPLU_IDS(&adl_p_info), INTEL_RPLP_IDS(&adl_p_info), INTEL_DG2_IDS(&dg2_info), INTEL_ATS_M_IDS(&ats_m_info), diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 64651a54a245..a39497971994 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -182,6 +182,7 @@ static const u16 subplatform_n_ids[] = { static const u16 subplatform_rpl_ids[] = { INTEL_RPLS_IDS(0), + INTEL_RPLU_IDS(0), INTEL_RPLP_IDS(0), }; diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 42913d2eb655..04f6ca3dc5c1 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -717,7 +717,6 @@ /* RPL-P */ #define INTEL_RPLP_IDS(info) \ - INTEL_RPLU_IDS(info), \ INTEL_VGA_DEVICE(0xA720, info), \ INTEL_VGA_DEVICE(0xA7A0, info), \ INTEL_VGA_DEVICE(0xA7A8, info), \ -- cgit v1.2.3 From 0b03829fdece47beba9ecb7dbcbde4585ee3663e Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 14 May 2024 10:20:51 -0700 Subject: drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq() The mipi_dsi_dcs_write_seq() macro makes a call to mipi_dsi_dcs_write_buffer() which returns a type ssize_t. The macro then stores it in an int and checks to see if it's negative. This could theoretically be a problem if "ssize_t" is larger than "int". To see the issue, imagine that "ssize_t" is 32-bits and "int" is 16-bits, you could see a problem if there was some code out there that looked like: mipi_dsi_dcs_write_seq(dsi, cmd, <32767 bytes as arguments>); ...since we'd get back that 32768 bytes were transferred and 32768 stored in a 16-bit int would look negative. Though there are no callsites where we'd actually hit this (even if "int" was only 16-bit), it's cleaner to make the types match so let's fix it. Fixes: 2a9e9daf7523 ("drm/mipi-dsi: Introduce mipi_dsi_dcs_write_seq macro") Reviewed-by: Neil Armstrong Reviewed-by: Linus Walleij Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20240514102056.v5.1.I30fa4c8348ea316c886ef8a522a52fed617f930d@changeid Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240514102056.v5.1.I30fa4c8348ea316c886ef8a522a52fed617f930d@changeid --- include/drm/drm_mipi_dsi.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 82b1cc434ea3..70ce0b8cbc68 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -333,18 +333,18 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, * @cmd: Command * @seq: buffer containing data to be transmitted */ -#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ - do { \ - static const u8 d[] = { cmd, seq }; \ - struct device *dev = &dsi->dev; \ - int ret; \ - ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) { \ - dev_err_ratelimited( \ - dev, "sending command %#02x failed: %d\n", \ - cmd, ret); \ - return ret; \ - } \ +#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ + do { \ + static const u8 d[] = { cmd, seq }; \ + struct device *dev = &dsi->dev; \ + ssize_t ret; \ + ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0) { \ + dev_err_ratelimited( \ + dev, "sending command %#02x failed: %zd\n", \ + cmd, ret); \ + return ret; \ + } \ } while (0) /** -- cgit v1.2.3 From 24acbcce5cc673886c2f4f9b3f6f89a9c6a53b7e Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 14 May 2024 10:20:52 -0700 Subject: drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq() The mipi_dsi_generic_write_seq() macro makes a call to mipi_dsi_generic_write() which returns a type ssize_t. The macro then stores it in an int and checks to see if it's negative. This could theoretically be a problem if "ssize_t" is larger than "int". To see the issue, imagine that "ssize_t" is 32-bits and "int" is 16-bits, you could see a problem if there was some code out there that looked like: mipi_dsi_generic_write_seq(dsi, <32768 bytes as arguments>); ...since we'd get back that 32768 bytes were transferred and 32768 stored in a 16-bit int would look negative. Though there are no callsites where we'd actually hit this (even if "int" was only 16-bit), it's cleaner to make the types match so let's fix it. Fixes: a9015ce59320 ("drm/mipi-dsi: Add a mipi_dsi_dcs_write_seq() macro") Reviewed-by: Neil Armstrong Reviewed-by: Linus Walleij Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20240514102056.v5.2.Iadb65b8add19ed3ae3ed6425011beb97e380a912@changeid Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240514102056.v5.2.Iadb65b8add19ed3ae3ed6425011beb97e380a912@changeid --- include/drm/drm_mipi_dsi.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 70ce0b8cbc68..e0f56564bf97 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -314,17 +314,17 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, * @dsi: DSI peripheral device * @seq: buffer containing the payload */ -#define mipi_dsi_generic_write_seq(dsi, seq...) \ - do { \ - static const u8 d[] = { seq }; \ - struct device *dev = &dsi->dev; \ - int ret; \ - ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) { \ - dev_err_ratelimited(dev, "transmit data failed: %d\n", \ - ret); \ - return ret; \ - } \ +#define mipi_dsi_generic_write_seq(dsi, seq...) \ + do { \ + static const u8 d[] = { seq }; \ + struct device *dev = &dsi->dev; \ + ssize_t ret; \ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0) { \ + dev_err_ratelimited(dev, "transmit data failed: %zd\n", \ + ret); \ + return ret; \ + } \ } while (0) /** -- cgit v1.2.3 From 7d3f6acaf87c7db6dcd868694a2f65e7040478dc Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 14 May 2024 10:20:53 -0700 Subject: drm/mipi-dsi: mipi_dsi_*_write functions don't need to ratelimit prints We really don't expect these errors to be printed over and over again. When a driver hits the error it should bail out. Just use a normal error print. This gives a nice space savings for users of these functions: $ scripts/bloat-o-meter \ .../before/panel-novatek-nt36672e.ko \ .../after/panel-novatek-nt36672e.ko add/remove: 0/1 grow/shrink: 0/1 up/down: 0/-16760 (-16760) Function old new delta nt36672e_1080x2408_60hz_init 17080 10640 -6440 nt36672e_1080x2408_60hz_init._rs 10320 - -10320 Total: Before=31815, After=15055, chg -52.68% Reviewed-by: Neil Armstrong Reviewed-by: Linus Walleij Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20240514102056.v5.3.I9982cd5d8014de7a4513f5619f66f88da49ce4ec@changeid Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240514102056.v5.3.I9982cd5d8014de7a4513f5619f66f88da49ce4ec@changeid --- include/drm/drm_mipi_dsi.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index e0f56564bf97..67967be48dbd 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -314,17 +314,16 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, * @dsi: DSI peripheral device * @seq: buffer containing the payload */ -#define mipi_dsi_generic_write_seq(dsi, seq...) \ - do { \ - static const u8 d[] = { seq }; \ - struct device *dev = &dsi->dev; \ - ssize_t ret; \ - ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) { \ - dev_err_ratelimited(dev, "transmit data failed: %zd\n", \ - ret); \ - return ret; \ - } \ +#define mipi_dsi_generic_write_seq(dsi, seq...) \ + do { \ + static const u8 d[] = { seq }; \ + struct device *dev = &dsi->dev; \ + ssize_t ret; \ + ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0) { \ + dev_err(dev, "transmit data failed: %zd\n", ret); \ + return ret; \ + } \ } while (0) /** @@ -340,8 +339,7 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, ssize_t ret; \ ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ if (ret < 0) { \ - dev_err_ratelimited( \ - dev, "sending command %#02x failed: %zd\n", \ + dev_err(dev, "sending command %#02x failed: %zd\n", \ cmd, ret); \ return ret; \ } \ -- cgit v1.2.3 From 3b724909a380fddb44dfa0072fc459c698a52658 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 14 May 2024 10:20:54 -0700 Subject: drm/mipi-dsi: Reduce driver bloat of mipi_dsi_*_write_seq() Through a cooperative effort between Hsin-Yi Wang and Dmitry Baryshkov, we have realized the dev_err() in the mipi_dsi_*_write_seq() macros was causing quite a bit of bloat to the kernel. Let's hoist this call into drm_mipi_dsi.c by adding a "chatty" version of the functions that includes the print. While doing this, add a bit more comments to these macros making it clear that they print errors and also that they return out of _the caller's_ function. Without any changes to clients this gives a nice savings. Specifically the macro was inlined and thus the error report call was inlined into every call to mipi_dsi_dcs_write_seq() and mipi_dsi_generic_write_seq(). By using a call to a "chatty" function, the usage is reduced to one call in the chatty function and a function call at the invoking site. Building with my build system shows one example: $ scripts/bloat-o-meter \ .../before/panel-novatek-nt36672e.ko \ .../after/panel-novatek-nt36672e.ko add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-4404 (-4404) Function old new delta nt36672e_1080x2408_60hz_init 10640 6236 -4404 Total: Before=15055, After=10651, chg -29.25% Note that given the change in location of the print it's harder to include the "cmd" in the printout for mipi_dsi_dcs_write_seq() since, theoretically, someone could call the new chatty function with a zero-size array and it would be illegal to dereference data[0]. There's a printk format to print the whole buffer and this is probably more useful for debugging anyway. Given that we're doing this for mipi_dsi_dcs_write_seq(), let's also print the buffer for mipi_dsi_generic_write_seq() in the error case. It should be noted that the current consensus of DRM folks is that the mipi_dsi_*_write_seq() should be deprecated due to the non-intuitive return behavior. A future patch will formally mark them as deprecated and provide an alternative. Reviewed-by: Dmitry Baryshkov Reviewed-by: Neil Armstrong Reviewed-by: Linus Walleij Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20240514102056.v5.4.Id15fae80582bc74a0d4f1338987fa375738f45b9@changeid Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240514102056.v5.4.Id15fae80582bc74a0d4f1338987fa375738f45b9@changeid --- drivers/gpu/drm/drm_mipi_dsi.c | 56 ++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 47 +++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 795001bb7ff1..4d2685d5a6e0 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -764,6 +764,34 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, } EXPORT_SYMBOL(mipi_dsi_generic_write); +/** + * mipi_dsi_generic_write_chatty() - mipi_dsi_generic_write() w/ an error log + * @dsi: DSI peripheral device + * @payload: buffer containing the payload + * @size: size of payload buffer + * + * Like mipi_dsi_generic_write() but includes a dev_err() + * call for you and returns 0 upon success, not the number of bytes sent. + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, + const void *payload, size_t size) +{ + struct device *dev = &dsi->dev; + ssize_t ret; + + ret = mipi_dsi_generic_write(dsi, payload, size); + if (ret < 0) { + dev_err(dev, "sending generic data %*ph failed: %zd\n", + (int)size, payload, ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_generic_write_chatty); + /** * mipi_dsi_generic_read() - receive data using a generic read packet * @dsi: DSI peripheral device @@ -852,6 +880,34 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); +/** + * mipi_dsi_dcs_write_buffer_chatty - mipi_dsi_dcs_write_buffer() w/ an error log + * @dsi: DSI peripheral device + * @data: buffer containing data to be transmitted + * @len: size of transmission buffer + * + * Like mipi_dsi_dcs_write_buffer() but includes a dev_err() + * call for you and returns 0 upon success, not the number of bytes sent. + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, + const void *data, size_t len) +{ + struct device *dev = &dsi->dev; + ssize_t ret; + + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); + if (ret < 0) { + dev_err(dev, "sending dcs data %*ph failed: %zd\n", + (int)len, data, ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty); + /** * mipi_dsi_dcs_write() - send DCS write command * @dsi: DSI peripheral device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 67967be48dbd..6d68d9927f46 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -256,6 +256,8 @@ int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, size_t size); +int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, + const void *payload, size_t size); ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size); @@ -279,6 +281,8 @@ enum mipi_dsi_dcs_tear_mode { ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len); +int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, + const void *data, size_t len); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, const void *data, size_t len); ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, @@ -311,38 +315,39 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, /** * mipi_dsi_generic_write_seq - transmit data using a generic write packet + * + * This macro will print errors for you and will RETURN FROM THE CALLING + * FUNCTION (yes this is non-intuitive) upon error. + * * @dsi: DSI peripheral device * @seq: buffer containing the payload */ -#define mipi_dsi_generic_write_seq(dsi, seq...) \ - do { \ - static const u8 d[] = { seq }; \ - struct device *dev = &dsi->dev; \ - ssize_t ret; \ - ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) { \ - dev_err(dev, "transmit data failed: %zd\n", ret); \ - return ret; \ - } \ +#define mipi_dsi_generic_write_seq(dsi, seq...) \ + do { \ + static const u8 d[] = { seq }; \ + int ret; \ + ret = mipi_dsi_generic_write_chatty(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0) \ + return ret; \ } while (0) /** * mipi_dsi_dcs_write_seq - transmit a DCS command with payload + * + * This macro will print errors for you and will RETURN FROM THE CALLING + * FUNCTION (yes this is non-intuitive) upon error. + * * @dsi: DSI peripheral device * @cmd: Command * @seq: buffer containing data to be transmitted */ -#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ - do { \ - static const u8 d[] = { cmd, seq }; \ - struct device *dev = &dsi->dev; \ - ssize_t ret; \ - ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \ - if (ret < 0) { \ - dev_err(dev, "sending command %#02x failed: %zd\n", \ - cmd, ret); \ - return ret; \ - } \ +#define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \ + do { \ + static const u8 d[] = { cmd, seq }; \ + int ret; \ + ret = mipi_dsi_dcs_write_buffer_chatty(dsi, d, ARRAY_SIZE(d)); \ + if (ret < 0) \ + return ret; \ } while (0) /** -- cgit v1.2.3 From 966e397e4f6032b73438f8d775756541513e7daf Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 14 May 2024 10:20:55 -0700 Subject: drm/mipi-dsi: Introduce mipi_dsi_*_write_seq_multi() The current mipi_dsi_*_write_seq() macros are non-intutitive because they contain a hidden "return" statement that will return out of the _caller_ of the macro. Let's mark them as deprecated and instead introduce some new macros that are more intuitive. These new macros are less optimal when an error occurs but should behave more optimally when there is no error. Specifically these new macros cause smaller code to get generated and the code size savings (less to fetch from RAM, less cache space used, less RAM used) are important. Since the error case isn't something we need to optimize for and these new macros are easier to understand and more flexible, they should be used. After converting to use these new functions, one example shows some nice savings while also being easier to understand. $ scripts/bloat-o-meter \ ...after/panel-novatek-nt36672e.ko \ ...ctx/panel-novatek-nt36672e.ko add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-988 (-988) Function old new delta nt36672e_1080x2408_60hz_init 6236 5248 -988 Total: Before=10651, After=9663, chg -9.28% Reviewed-by: Neil Armstrong Reviewed-by: Linus Walleij Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20240514102056.v5.5.Ie94246c30fe95101e0e26dd5f96e976dbeb8f242@changeid Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240514102056.v5.5.Ie94246c30fe95101e0e26dd5f96e976dbeb8f242@changeid --- Documentation/gpu/todo.rst | 18 ++++++++++++ drivers/gpu/drm/drm_mipi_dsi.c | 56 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 62 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) (limited to 'include') diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst index e2a0585915b3..2734b8a34541 100644 --- a/Documentation/gpu/todo.rst +++ b/Documentation/gpu/todo.rst @@ -494,6 +494,24 @@ Contact: Douglas Anderson Level: Starter/Intermediate +Transition away from using mipi_dsi_*_write_seq() +------------------------------------------------- + +The macros mipi_dsi_generic_write_seq() and mipi_dsi_dcs_write_seq() are +non-intuitive because, if there are errors, they return out of the *caller's* +function. We should move all callers to use mipi_dsi_generic_write_seq_multi() +and mipi_dsi_dcs_write_seq_multi() macros instead. + +Once all callers are transitioned, the macros and the functions that they call, +mipi_dsi_generic_write_chatty() and mipi_dsi_dcs_write_buffer_chatty(), can +probably be removed. Alternatively, if people feel like the _multi() variants +are overkill for some use cases, we could keep the mipi_dsi_*_write_seq() +variants but change them not to return out of the caller. + +Contact: Douglas Anderson + +Level: Starter + Core refactorings ================= diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 4d2685d5a6e0..26c7383406c1 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -792,6 +792,34 @@ int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_generic_write_chatty); +/** + * mipi_dsi_generic_write_multi() - mipi_dsi_generic_write_chatty() w/ accum_err + * @ctx: Context for multiple DSI transactions + * @payload: buffer containing the payload + * @size: size of payload buffer + * + * Like mipi_dsi_generic_write_chatty() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, + const void *payload, size_t size) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_generic_write(dsi, payload, size); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending generic data %*ph failed: %d\n", + (int)size, payload, ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_generic_write_multi); + /** * mipi_dsi_generic_read() - receive data using a generic read packet * @dsi: DSI peripheral device @@ -908,6 +936,34 @@ int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_chatty); +/** + * mipi_dsi_dcs_write_buffer_multi - mipi_dsi_dcs_write_buffer_chatty() w/ accum_err + * @ctx: Context for multiple DSI transactions + * @data: buffer containing data to be transmitted + * @len: size of transmission buffer + * + * Like mipi_dsi_dcs_write_buffer_chatty() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, + const void *data, size_t len) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending dcs data %*ph failed: %d\n", + (int)len, data, ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer_multi); + /** * mipi_dsi_dcs_write() - send DCS write command * @dsi: DSI peripheral device diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 6d68d9927f46..5e9cad541bd6 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -197,6 +197,27 @@ struct mipi_dsi_device { struct drm_dsc_config *dsc; }; +/** + * struct mipi_dsi_multi_context - Context to call multiple MIPI DSI funcs in a row + */ +struct mipi_dsi_multi_context { + /** + * @dsi: Pointer to the MIPI DSI device + */ + struct mipi_dsi_device *dsi; + + /** + * @accum_err: Storage for the accumulated error over the multiple calls + * + * Init to 0. If a function encounters an error then the error code + * will be stored here. If you call a function and this points to a + * non-zero value then the function will be a noop. This allows calling + * a function many times in a row and just checking the error at the + * end to see if any of them failed. + */ + int accum_err; +}; + #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:" #define to_mipi_dsi_device(__dev) container_of_const(__dev, struct mipi_dsi_device, dev) @@ -258,6 +279,8 @@ ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, size_t size); int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, const void *payload, size_t size); +void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, + const void *payload, size_t size); ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size); @@ -283,6 +306,8 @@ ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, const void *data, size_t len); int mipi_dsi_dcs_write_buffer_chatty(struct mipi_dsi_device *dsi, const void *data, size_t len); +void mipi_dsi_dcs_write_buffer_multi(struct mipi_dsi_multi_context *ctx, + const void *data, size_t len); ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, const void *data, size_t len); ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, @@ -319,6 +344,9 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, * This macro will print errors for you and will RETURN FROM THE CALLING * FUNCTION (yes this is non-intuitive) upon error. * + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED. + * Please replace calls of it with mipi_dsi_generic_write_seq_multi(). + * * @dsi: DSI peripheral device * @seq: buffer containing the payload */ @@ -331,12 +359,30 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, return ret; \ } while (0) +/** + * mipi_dsi_generic_write_seq_multi - transmit data using a generic write packet + * + * This macro will print errors for you and error handling is optimized for + * callers that call this multiple times in a row. + * + * @ctx: Context for multiple DSI transactions + * @seq: buffer containing the payload + */ +#define mipi_dsi_generic_write_seq_multi(ctx, seq...) \ + do { \ + static const u8 d[] = { seq }; \ + mipi_dsi_generic_write_multi(ctx, d, ARRAY_SIZE(d)); \ + } while (0) + /** * mipi_dsi_dcs_write_seq - transmit a DCS command with payload * * This macro will print errors for you and will RETURN FROM THE CALLING * FUNCTION (yes this is non-intuitive) upon error. * + * Because of the non-intuitive return behavior, THIS MACRO IS DEPRECATED. + * Please replace calls of it with mipi_dsi_dcs_write_seq_multi(). + * * @dsi: DSI peripheral device * @cmd: Command * @seq: buffer containing data to be transmitted @@ -350,6 +396,22 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, return ret; \ } while (0) +/** + * mipi_dsi_dcs_write_seq_multi - transmit a DCS command with payload + * + * This macro will print errors for you and error handling is optimized for + * callers that call this multiple times in a row. + * + * @ctx: Context for multiple DSI transactions + * @cmd: Command + * @seq: buffer containing data to be transmitted + */ +#define mipi_dsi_dcs_write_seq_multi(ctx, cmd, seq...) \ + do { \ + static const u8 d[] = { cmd, seq }; \ + mipi_dsi_dcs_write_buffer_multi(ctx, d, ARRAY_SIZE(d)); \ + } while (0) + /** * struct mipi_dsi_driver - DSI driver * @driver: device driver model driver -- cgit v1.2.3 From 0f1bb41bf39695c84c83ce6f69e125b562d1d7ab Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Tue, 14 May 2024 15:59:39 +0100 Subject: drm/i915: Support replaying GPU hangs with captured context image When debugging GPU hangs Mesa developers are finding it useful to replay the captured error state against the simulator. But due various simulator limitations which prevent replicating all hangs, one step further is being able to replay against a real GPU. This is almost doable today with the missing part being able to upload the captured context image into the driver state prior to executing the uploaded hanging batch and all the buffers. To enable this last part we add a new context parameter called I915_CONTEXT_PARAM_CONTEXT_IMAGE. It follows the existing SSEU configuration pattern of being able to select which context to apply against, paired with the actual image and its size. Since this is adding a new concept of debug only uapi, we hide it behind a new kconfig option and also require activation with a module parameter. Together with a warning banner printed at driver load, all those combined should be sufficient to guard against inadvertently enabling the feature. In terms of implementation we allow the legacy context set param to be used since that removes the need to record the per context data in the proto context, while still allowing flexibility of specifying context images for any context. Mesa MR using the uapi can be seen at: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27594 v2: * Fix whitespace alignment as per checkpatch. * Added warning on userspace misuse. * Rebase for extracting ce->default_state shadowing. v3: * Rebase for I915_CONTEXT_PARAM_LOW_LATENCY. Signed-off-by: Tvrtko Ursulin Cc: Lionel Landwerlin Cc: Carlos Santa Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Tested-by: Carlos Santa Signed-off-by: Tvrtko Ursulin Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20240514145939.87427-2-tursulin@igalia.com --- drivers/gpu/drm/i915/Kconfig.debug | 17 ++++ drivers/gpu/drm/i915/gem/i915_gem_context.c | 113 ++++++++++++++++++++++++ drivers/gpu/drm/i915/gt/intel_context.c | 2 + drivers/gpu/drm/i915/gt/intel_context.h | 22 +++++ drivers/gpu/drm/i915/gt/intel_context_types.h | 1 + drivers/gpu/drm/i915/gt/intel_lrc.c | 3 +- drivers/gpu/drm/i915/gt/intel_ring_submission.c | 3 +- drivers/gpu/drm/i915/i915_params.c | 5 ++ drivers/gpu/drm/i915/i915_params.h | 3 +- include/uapi/drm/i915_drm.h | 27 ++++++ 10 files changed, 193 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index d8397065c3f0..1852e0804942 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -16,6 +16,23 @@ config DRM_I915_WERROR If in doubt, say "N". +config DRM_I915_REPLAY_GPU_HANGS_API + bool "Enable GPU hang replay userspace API" + depends on DRM_I915 + depends on EXPERT + default n + help + Choose this option if you want to enable special and unstable + userspace API used for replaying GPU hangs on a running system. + + This API is intended to be used by userspace graphics stack developers + and provides no stability guarantees. + + The API needs to be activated at boot time using the + enable_debug_only_api module parameter. + + If in doubt, say "N". + config DRM_I915_DEBUG bool "Enable additional driver debugging" depends on DRM_I915 diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 81f65cab1330..c0543c35cd6a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -78,6 +78,7 @@ #include "gt/intel_engine_user.h" #include "gt/intel_gpu_commands.h" #include "gt/intel_ring.h" +#include "gt/shmem_utils.h" #include "pxp/intel_pxp.h" @@ -957,6 +958,7 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv, case I915_CONTEXT_PARAM_NO_ZEROMAP: case I915_CONTEXT_PARAM_BAN_PERIOD: case I915_CONTEXT_PARAM_RINGSIZE: + case I915_CONTEXT_PARAM_CONTEXT_IMAGE: default: ret = -EINVAL; break; @@ -2104,6 +2106,95 @@ static int get_protected(struct i915_gem_context *ctx, return 0; } +static int set_context_image(struct i915_gem_context *ctx, + struct drm_i915_gem_context_param *args) +{ + struct i915_gem_context_param_context_image user; + struct intel_context *ce; + struct file *shmem_state; + unsigned long lookup; + void *state; + int ret = 0; + + if (!IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)) + return -EINVAL; + + if (!ctx->i915->params.enable_debug_only_api) + return -EINVAL; + + if (args->size < sizeof(user)) + return -EINVAL; + + if (copy_from_user(&user, u64_to_user_ptr(args->value), sizeof(user))) + return -EFAULT; + + if (user.mbz) + return -EINVAL; + + if (user.flags & ~(I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX)) + return -EINVAL; + + lookup = 0; + if (user.flags & I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX) + lookup |= LOOKUP_USER_INDEX; + + ce = lookup_user_engine(ctx, lookup, &user.engine); + if (IS_ERR(ce)) + return PTR_ERR(ce); + + if (user.size < ce->engine->context_size) { + ret = -EINVAL; + goto out_ce; + } + + if (drm_WARN_ON_ONCE(&ctx->i915->drm, + test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) { + /* + * This is racy but for a debug only API, if userspace is keen + * to create and configure contexts, while simultaneously using + * them from a second thread, let them suffer by potentially not + * executing with the context image they just raced to apply. + */ + ret = -EBUSY; + goto out_ce; + } + + state = kmalloc(ce->engine->context_size, GFP_KERNEL); + if (!state) { + ret = -ENOMEM; + goto out_ce; + } + + if (copy_from_user(state, u64_to_user_ptr(user.image), + ce->engine->context_size)) { + ret = -EFAULT; + goto out_state; + } + + shmem_state = shmem_create_from_data(ce->engine->name, + state, ce->engine->context_size); + if (IS_ERR(shmem_state)) { + ret = PTR_ERR(shmem_state); + goto out_state; + } + + if (intel_context_set_own_state(ce)) { + ret = -EBUSY; + fput(shmem_state); + goto out_state; + } + + ce->default_state = shmem_state; + + args->size = sizeof(user); + +out_state: + kfree(state); +out_ce: + intel_context_put(ce); + return ret; +} + static int ctx_setparam(struct drm_i915_file_private *fpriv, struct i915_gem_context *ctx, struct drm_i915_gem_context_param *args) @@ -2156,6 +2247,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv, ret = set_persistence(ctx, args); break; + case I915_CONTEXT_PARAM_CONTEXT_IMAGE: + ret = set_context_image(ctx, args); + break; + case I915_CONTEXT_PARAM_PROTECTED_CONTENT: case I915_CONTEXT_PARAM_NO_ZEROMAP: case I915_CONTEXT_PARAM_BAN_PERIOD: @@ -2500,6 +2595,7 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_BAN_PERIOD: case I915_CONTEXT_PARAM_ENGINES: case I915_CONTEXT_PARAM_RINGSIZE: + case I915_CONTEXT_PARAM_CONTEXT_IMAGE: default: ret = -EINVAL; break; @@ -2612,5 +2708,22 @@ int __init i915_gem_context_module_init(void) if (!slab_luts) return -ENOMEM; + if (IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API)) { + pr_notice("**************************************************************\n"); + pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); + pr_notice("** **\n"); + if (i915_modparams.enable_debug_only_api) + pr_notice("** i915.enable_debug_only_api is intended to be set **\n"); + else + pr_notice("** CONFIG_DRM_I915_REPLAY_GPU_HANGS_API builds are intended **\n"); + pr_notice("** for specific userspace graphics stack developers only! **\n"); + pr_notice("** **\n"); + pr_notice("** If you are seeing this message please report this to the **\n"); + pr_notice("** provider of your kernel build. **\n"); + pr_notice("** **\n"); + pr_notice("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); + pr_notice("**************************************************************\n"); + } + return 0; } diff --git a/drivers/gpu/drm/i915/gt/intel_context.c b/drivers/gpu/drm/i915/gt/intel_context.c index a2f1245741bb..b1b8695ba7c9 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.c +++ b/drivers/gpu/drm/i915/gt/intel_context.c @@ -27,6 +27,8 @@ static void rcu_context_free(struct rcu_head *rcu) struct intel_context *ce = container_of(rcu, typeof(*ce), rcu); trace_intel_context_free(ce); + if (intel_context_has_own_state(ce)) + fput(ce->default_state); kmem_cache_free(slab_ce, ce); } diff --git a/drivers/gpu/drm/i915/gt/intel_context.h b/drivers/gpu/drm/i915/gt/intel_context.h index 25564c01507e..9f523999acd1 100644 --- a/drivers/gpu/drm/i915/gt/intel_context.h +++ b/drivers/gpu/drm/i915/gt/intel_context.h @@ -375,6 +375,28 @@ intel_context_clear_nopreempt(struct intel_context *ce) clear_bit(CONTEXT_NOPREEMPT, &ce->flags); } +#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API) +static inline bool intel_context_has_own_state(const struct intel_context *ce) +{ + return test_bit(CONTEXT_OWN_STATE, &ce->flags); +} + +static inline bool intel_context_set_own_state(struct intel_context *ce) +{ + return test_and_set_bit(CONTEXT_OWN_STATE, &ce->flags); +} +#else +static inline bool intel_context_has_own_state(const struct intel_context *ce) +{ + return false; +} + +static inline bool intel_context_set_own_state(struct intel_context *ce) +{ + return true; +} +#endif + u64 intel_context_get_total_runtime_ns(struct intel_context *ce); u64 intel_context_get_avg_runtime_ns(struct intel_context *ce); diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h b/drivers/gpu/drm/i915/gt/intel_context_types.h index 6ae8abfeccdb..98c7f6052069 100644 --- a/drivers/gpu/drm/i915/gt/intel_context_types.h +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h @@ -133,6 +133,7 @@ struct intel_context { #define CONTEXT_IS_PARKING 12 #define CONTEXT_EXITING 13 #define CONTEXT_LOW_LATENCY 14 +#define CONTEXT_OWN_STATE 15 struct { u64 timeout_us; diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index d4ffb352403c..7bd5d2c29056 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -1130,7 +1130,8 @@ int lrc_alloc(struct intel_context *ce, struct intel_engine_cs *engine) GEM_BUG_ON(ce->state); - ce->default_state = engine->default_state; + if (!intel_context_has_own_state(ce)) + ce->default_state = engine->default_state; vma = __lrc_alloc_state(ce, engine); if (IS_ERR(vma)) diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 8625e88e785f..72277bc8322e 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -569,7 +569,8 @@ static int ring_context_alloc(struct intel_context *ce) { struct intel_engine_cs *engine = ce->engine; - ce->default_state = engine->default_state; + if (!intel_context_has_own_state(ce)) + ce->default_state = engine->default_state; /* One ringbuffer to rule them all */ GEM_BUG_ON(!engine->legacy.ring); diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 8c00169e3ab7..316e55f3e87b 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -131,6 +131,11 @@ i915_param_named_unsafe(lmem_size, uint, 0400, i915_param_named_unsafe(lmem_bar_size, uint, 0400, "Set the lmem bar size(in MiB)."); +#if IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API) +i915_param_named(enable_debug_only_api, bool, 0400, + "Enable support for unstable debug only userspace API. (default:false)"); +#endif + static void _param_print_bool(struct drm_printer *p, const char *name, bool val) { diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 2eb3f2115ff2..0fbcb5b6d7bf 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -63,7 +63,8 @@ struct drm_printer; /* leave bools at the end to not create holes */ \ param(bool, enable_hangcheck, true, 0600) \ param(bool, error_capture, true, IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) ? 0600 : 0) \ - param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) + param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 0) \ + param(bool, enable_debug_only_api, false, IS_ENABLED(CONFIG_DRM_I915_REPLAY_GPU_HANGS_API) ? 0400 : 0) #define MEMBER(T, member, ...) T member; struct i915_params { diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index d4d86e566e07..535cb68fdb5c 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -2163,6 +2163,15 @@ struct drm_i915_gem_context_param { * supports this per context flag. */ #define I915_CONTEXT_PARAM_LOW_LATENCY 0xe + +/* + * I915_CONTEXT_PARAM_CONTEXT_IMAGE: + * + * Allows userspace to provide own context images. + * + * Note that this is a debug API not available on production kernel builds. + */ +#define I915_CONTEXT_PARAM_CONTEXT_IMAGE 0xf /* Must be kept compact -- no holes and well documented */ /** @value: Context parameter value to be set or queried */ @@ -2564,6 +2573,24 @@ struct i915_context_param_engines { struct i915_engine_class_instance engines[N__]; \ } __attribute__((packed)) name__ +struct i915_gem_context_param_context_image { + /** @engine: Engine class & instance to be configured. */ + struct i915_engine_class_instance engine; + + /** @flags: One of the supported flags or zero. */ + __u32 flags; +#define I915_CONTEXT_IMAGE_FLAG_ENGINE_INDEX (1u << 0) + + /** @size: Size of the image blob pointed to by @image. */ + __u32 size; + + /** @mbz: Must be zero. */ + __u32 mbz; + + /** @image: Userspace memory containing the context image. */ + __u64 image; +} __attribute__((packed)); + /** * struct drm_i915_gem_context_create_ext_setparam - Context parameter * to set or query during context creation. -- cgit v1.2.3 From f79d6d28d8fe77b14beeaebe5393d9f294f8d09d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 12 May 2024 02:00:19 +0300 Subject: drm/mipi-dsi: wrap more functions for streamline handling Follow the pattern of mipi_dsi_dcs_*_multi() and wrap several existing MIPI DSI functions to use the context for processing. This simplifies and streamlines driver code to use simpler code pattern. Note, msleep function is also wrapped in this way as it is frequently called inbetween other mipi_dsi_dcs_*() functions. Signed-off-by: Dmitry Baryshkov Reviewed-by: Douglas Anderson Reviewed-by: Neil Armstrong Link: https://lore.kernel.org/r/20240512-dsi-panels-upd-api-v2-2-e31ca14d102e@linaro.org Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240512-dsi-panels-upd-api-v2-2-e31ca14d102e@linaro.org --- drivers/gpu/drm/drm_mipi_dsi.c | 210 +++++++++++++++++++++++++++++++++++++++++ include/drm/drm_mipi_dsi.h | 21 +++++ 2 files changed, 231 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 26c7383406c1..a471c46f5ca6 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -1429,6 +1429,216 @@ int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, } EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); +/** + * mipi_dsi_picture_parameter_set_multi() - transmit the DSC PPS to the peripheral + * @ctx: Context for multiple DSI transactions + * @pps: VESA DSC 1.1 Picture Parameter Set + * + * Like mipi_dsi_picture_parameter_set() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, + const struct drm_dsc_picture_parameter_set *pps) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_picture_parameter_set(dsi, pps); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending PPS failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_picture_parameter_set_multi); + +/** + * mipi_dsi_compression_mode_ext_multi() - enable/disable DSC on the peripheral + * @ctx: Context for multiple DSI transactions + * @enable: Whether to enable or disable the DSC + * @algo: Selected compression algorithm + * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries + * + * Like mipi_dsi_compression_mode_ext() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, + bool enable, + enum mipi_dsi_compression_algo algo, + unsigned int pps_selector) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_compression_mode_ext(dsi, enable, algo, pps_selector); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending COMPRESSION_MODE failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_compression_mode_ext_multi); + +/** + * mipi_dsi_dcs_nop_multi() - send DCS NOP packet + * @ctx: Context for multiple DSI transactions + * + * Like mipi_dsi_dcs_nop() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_nop(dsi); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS NOP failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_nop_multi); + +/** + * mipi_dsi_dcs_enter_sleep_mode_multi() - send DCS ENTER_SLEEP_MODE packet + * @ctx: Context for multiple DSI transactions + * + * Like mipi_dsi_dcs_enter_sleep_mode() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_enter_sleep_mode(dsi); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS ENTER_SLEEP_MODE failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode_multi); + +/** + * mipi_dsi_dcs_exit_sleep_mode_multi() - send DCS EXIT_SLEEP_MODE packet + * @ctx: Context for multiple DSI transactions + * + * Like mipi_dsi_dcs_exit_sleep_mode() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS EXIT_SLEEP_MODE failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode_multi); + +/** + * mipi_dsi_dcs_set_display_off_multi() - send DCS SET_DISPLAY_OFF packet + * @ctx: Context for multiple DSI transactions + * + * Like mipi_dsi_dcs_set_display_off() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_set_display_off(dsi); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS SET_DISPLAY_OFF failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off_multi); + +/** + * mipi_dsi_dcs_set_display_on_multi() - send DCS SET_DISPLAY_ON packet + * @ctx: Context for multiple DSI transactions + * + * Like mipi_dsi_dcs_set_display_on() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS SET_DISPLAY_ON failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on_multi); + +/** + * mipi_dsi_dcs_set_tear_on_multi() - send DCS SET_TEAR_ON packet + * @ctx: Context for multiple DSI transactions + * @mode: the Tearing Effect Output Line mode + * + * Like mipi_dsi_dcs_set_tear_on() but deals with errors in a way that + * makes it convenient to make several calls in a row. + */ +void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, + enum mipi_dsi_dcs_tear_mode mode) +{ + struct mipi_dsi_device *dsi = ctx->dsi; + struct device *dev = &dsi->dev; + ssize_t ret; + + if (ctx->accum_err) + return; + + ret = mipi_dsi_dcs_set_tear_on(dsi, mode); + if (ret < 0) { + ctx->accum_err = ret; + dev_err(dev, "sending DCS SET_TEAR_ON failed: %d\n", + ctx->accum_err); + } +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on_multi); + static int mipi_dsi_drv_probe(struct device *dev) { struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 5e9cad541bd6..bd5a0b6d0711 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -275,6 +275,13 @@ int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable, int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi, const struct drm_dsc_picture_parameter_set *pps); +void mipi_dsi_compression_mode_ext_multi(struct mipi_dsi_multi_context *ctx, + bool enable, + enum mipi_dsi_compression_algo algo, + unsigned int pps_selector); +void mipi_dsi_picture_parameter_set_multi(struct mipi_dsi_multi_context *ctx, + const struct drm_dsc_picture_parameter_set *pps); + ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, size_t size); int mipi_dsi_generic_write_chatty(struct mipi_dsi_device *dsi, @@ -284,6 +291,12 @@ void mipi_dsi_generic_write_multi(struct mipi_dsi_multi_context *ctx, ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, size_t num_params, void *data, size_t size); +#define mipi_dsi_msleep(ctx, delay) \ + do { \ + if (!ctx.accum_err) \ + msleep(delay); \ + } while (0) + /** * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking @@ -338,6 +351,14 @@ int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, u16 *brightness); +void mipi_dsi_dcs_nop_multi(struct mipi_dsi_multi_context *ctx); +void mipi_dsi_dcs_enter_sleep_mode_multi(struct mipi_dsi_multi_context *ctx); +void mipi_dsi_dcs_exit_sleep_mode_multi(struct mipi_dsi_multi_context *ctx); +void mipi_dsi_dcs_set_display_off_multi(struct mipi_dsi_multi_context *ctx); +void mipi_dsi_dcs_set_display_on_multi(struct mipi_dsi_multi_context *ctx); +void mipi_dsi_dcs_set_tear_on_multi(struct mipi_dsi_multi_context *ctx, + enum mipi_dsi_dcs_tear_mode mode); + /** * mipi_dsi_generic_write_seq - transmit data using a generic write packet * -- cgit v1.2.3 From 36b75080e68b4a27ae1c40beffb3d6131f8eeeff Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Sun, 12 May 2024 19:23:26 -0300 Subject: drm/v3d: Create a new V3D parameter for the maximum number of perfcnt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maximum number of performance counters can change from version to version and it's important for userspace to know this value, as it needs to use the counters for performance queries. Therefore, expose the maximum number of performance counters to userspace as a parameter. Signed-off-by: Maíra Canal Reviewed-by: Iago Toral Quiroga Link: https://patchwork.freedesktop.org/patch/msgid/20240512222655.2792754-4-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.c | 3 +++ include/uapi/drm/v3d_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 6b9dd26df9fe..d2c1d5053132 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -94,6 +94,9 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, case DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE: args->value = 1; return 0; + case DRM_V3D_PARAM_MAX_PERF_COUNTERS: + args->value = v3d->max_counters; + return 0; default: DRM_DEBUG("Unknown parameter %d\n", args->param); return -EINVAL; diff --git a/include/uapi/drm/v3d_drm.h b/include/uapi/drm/v3d_drm.h index dce1835eced4..215b01bb69c3 100644 --- a/include/uapi/drm/v3d_drm.h +++ b/include/uapi/drm/v3d_drm.h @@ -286,6 +286,7 @@ enum drm_v3d_param { DRM_V3D_PARAM_SUPPORTS_PERFMON, DRM_V3D_PARAM_SUPPORTS_MULTISYNC_EXT, DRM_V3D_PARAM_SUPPORTS_CPU_QUEUE, + DRM_V3D_PARAM_MAX_PERF_COUNTERS, }; struct drm_v3d_get_param { -- cgit v1.2.3 From f33fe58298e686e7cc2d24f747c980457812b566 Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Sun, 12 May 2024 19:23:27 -0300 Subject: drm/v3d: Create new IOCTL to expose performance counters information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Userspace usually needs some information about the performance counters available. Although we could replicate this information in the kernel and user-space, let's use the kernel as the "single source of truth" to avoid issues in the future (e.g. list of performance counters is updated in user-space, but not in the kernel, generating invalid requests). Therefore, create a new IOCTL to expose the performance counters information, that is name, category, and description. Signed-off-by: Maíra Canal Reviewed-by: Iago Toral Quiroga Link: https://patchwork.freedesktop.org/patch/msgid/20240512222655.2792754-5-mcanal@igalia.com --- drivers/gpu/drm/v3d/v3d_drv.c | 1 + drivers/gpu/drm/v3d/v3d_drv.h | 2 ++ drivers/gpu/drm/v3d/v3d_perfmon.c | 33 +++++++++++++++++++++++++++++++++ include/uapi/drm/v3d_drm.h | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index d2c1d5053132..f7477488b1cc 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -211,6 +211,7 @@ static const struct drm_ioctl_desc v3d_drm_ioctls[] = { DRM_IOCTL_DEF_DRV(V3D_PERFMON_DESTROY, v3d_perfmon_destroy_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(V3D_PERFMON_GET_VALUES, v3d_perfmon_get_values_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CPU, v3d_submit_cpu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH), + DRM_IOCTL_DEF_DRV(V3D_PERFMON_GET_COUNTER, v3d_perfmon_get_counter_ioctl, DRM_RENDER_ALLOW), }; static const struct drm_driver v3d_drm_driver = { diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index bd1e38f7d10a..44cfddedebde 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -582,6 +582,8 @@ int v3d_perfmon_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int v3d_perfmon_get_counter_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); /* v3d_sysfs.c */ int v3d_sysfs_init(struct device *dev); diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index f268d9466c0f..73e2bb8bdb7f 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -217,3 +217,36 @@ int v3d_perfmon_get_values_ioctl(struct drm_device *dev, void *data, return ret; } + +int v3d_perfmon_get_counter_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_v3d_perfmon_get_counter *req = data; + struct v3d_dev *v3d = to_v3d_dev(dev); + const struct v3d_perf_counter_desc *counter; + + for (int i = 0; i < ARRAY_SIZE(req->reserved); i++) { + if (req->reserved[i] != 0) + return -EINVAL; + } + + /* Make sure that the counter ID is valid */ + if (req->counter >= v3d->max_counters) + return -EINVAL; + + if (v3d->ver >= 71) { + WARN_ON(v3d->max_counters != ARRAY_SIZE(v3d_v71_performance_counters)); + counter = &v3d_v71_performance_counters[req->counter]; + } else if (v3d->ver >= 42) { + WARN_ON(v3d->max_counters != ARRAY_SIZE(v3d_v42_performance_counters)); + counter = &v3d_v42_performance_counters[req->counter]; + } else { + return -EOPNOTSUPP; + } + + strscpy(req->name, counter->name, sizeof(req->name)); + strscpy(req->category, counter->category, sizeof(req->category)); + strscpy(req->description, counter->description, sizeof(req->description)); + + return 0; +} diff --git a/include/uapi/drm/v3d_drm.h b/include/uapi/drm/v3d_drm.h index 215b01bb69c3..0860ddb3d0b6 100644 --- a/include/uapi/drm/v3d_drm.h +++ b/include/uapi/drm/v3d_drm.h @@ -42,6 +42,7 @@ extern "C" { #define DRM_V3D_PERFMON_DESTROY 0x09 #define DRM_V3D_PERFMON_GET_VALUES 0x0a #define DRM_V3D_SUBMIT_CPU 0x0b +#define DRM_V3D_PERFMON_GET_COUNTER 0x0c #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl) #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo) @@ -58,6 +59,8 @@ extern "C" { #define DRM_IOCTL_V3D_PERFMON_GET_VALUES DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_VALUES, \ struct drm_v3d_perfmon_get_values) #define DRM_IOCTL_V3D_SUBMIT_CPU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CPU, struct drm_v3d_submit_cpu) +#define DRM_IOCTL_V3D_PERFMON_GET_COUNTER DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_PERFMON_GET_COUNTER, \ + struct drm_v3d_perfmon_get_counter) #define DRM_V3D_SUBMIT_CL_FLUSH_CACHE 0x01 #define DRM_V3D_SUBMIT_EXTENSION 0x02 @@ -718,6 +721,40 @@ struct drm_v3d_perfmon_get_values { __u64 values_ptr; }; +#define DRM_V3D_PERFCNT_MAX_NAME 64 +#define DRM_V3D_PERFCNT_MAX_CATEGORY 32 +#define DRM_V3D_PERFCNT_MAX_DESCRIPTION 256 + +/** + * struct drm_v3d_perfmon_get_counter - ioctl to get the description of a + * performance counter + * + * As userspace needs to retrieve information about the performance counters + * available, this IOCTL allows users to get information about a performance + * counter (name, category and description). + */ +struct drm_v3d_perfmon_get_counter { + /* + * Counter ID + * + * Must be smaller than the maximum number of performance counters, which + * can be retrieve through DRM_V3D_PARAM_MAX_PERF_COUNTERS. + */ + __u8 counter; + + /* Name of the counter */ + __u8 name[DRM_V3D_PERFCNT_MAX_NAME]; + + /* Category of the counter */ + __u8 category[DRM_V3D_PERFCNT_MAX_CATEGORY]; + + /* Description of the counter */ + __u8 description[DRM_V3D_PERFCNT_MAX_DESCRIPTION]; + + /* mbz */ + __u8 reserved[7]; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From 673087d8b023faf34b84e8faf63bbeea3da87bab Mon Sep 17 00:00:00 2001 From: Maíra Canal Date: Sun, 12 May 2024 19:23:29 -0300 Subject: drm/v3d: Deprecate the use of the Performance Counters enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Performance Counters enum used to identify the index of each performance counter and provide the total number of performance counters (V3D_PERFCNT_NUM). But, this enum is only valid for V3D 4.2, not for V3D 7.1. As we implemented a new flexible structure to retrieve performance counters information, we can deprecate this enum. Signed-off-by: Maíra Canal Reviewed-by: Iago Toral Quiroga Link: https://patchwork.freedesktop.org/patch/msgid/20240512222655.2792754-7-mcanal@igalia.com --- include/uapi/drm/v3d_drm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/v3d_drm.h b/include/uapi/drm/v3d_drm.h index 0860ddb3d0b6..87fc5bb0a61e 100644 --- a/include/uapi/drm/v3d_drm.h +++ b/include/uapi/drm/v3d_drm.h @@ -603,6 +603,16 @@ struct drm_v3d_submit_cpu { __u64 extensions; }; +/* The performance counters index represented by this enum are deprecated and + * must no longer be used. These counters are only valid for V3D 4.2. + * + * In order to check for performance counter information, + * use DRM_IOCTL_V3D_PERFMON_GET_COUNTER. + * + * Don't use V3D_PERFCNT_NUM to retrieve the maximum number of performance + * counters. You should use DRM_IOCTL_V3D_GET_PARAM with the following + * parameter: DRM_V3D_PARAM_MAX_PERF_COUNTERS. + */ enum { V3D_PERFCNT_FEP_VALID_PRIMTS_NO_PIXELS, V3D_PERFCNT_FEP_VALID_PRIMS, -- cgit v1.2.3 From 995f7dafd110eecbeef1e02846d897d64839d838 Mon Sep 17 00:00:00 2001 From: Francois Dugast Date: Tue, 16 Apr 2024 14:50:37 +0000 Subject: drm/xe/uapi: Expose the L3 bank mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The L3 bank mask is already generated and stored internally with the rest of the GT topology. In user space, the compute runtime now needs this information to be added to the device properties therefore the topology mask query is extended to provide a new mask which represents the L3 banks enabled on the GT. The changes in the compute runtime are ready and approved, see link below. v2: Rewrite commit message and add a link to the compute runtime PR (Francois Dugast) Cc: Matt Roper Cc: Robert Krzemien Cc: Mateusz Jablonski Link: https://github.com/intel/compute-runtime/pull/722 Signed-off-by: Francois Dugast Acked-by: Mateusz Jablonski Reviewed-by: José Roberto de Souza Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20240416145037.7-2-francois.dugast@intel.com --- drivers/gpu/drm/xe/xe_query.c | 9 ++++++++- include/uapi/drm/xe_drm.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c index 29f847debb5c..995effcb904b 100644 --- a/drivers/gpu/drm/xe/xe_query.c +++ b/drivers/gpu/drm/xe/xe_query.c @@ -455,9 +455,10 @@ static int query_hwconfig(struct xe_device *xe, static size_t calc_topo_query_size(struct xe_device *xe) { return xe->info.gt_count * - (3 * sizeof(struct drm_xe_query_topology_mask) + + (4 * sizeof(struct drm_xe_query_topology_mask) + sizeof_field(struct xe_gt, fuse_topo.g_dss_mask) + sizeof_field(struct xe_gt, fuse_topo.c_dss_mask) + + sizeof_field(struct xe_gt, fuse_topo.l3_bank_mask) + sizeof_field(struct xe_gt, fuse_topo.eu_mask_per_dss)); } @@ -511,6 +512,12 @@ static int query_gt_topology(struct xe_device *xe, if (err) return err; + topo.type = DRM_XE_TOPO_L3_BANK; + err = copy_mask(&query_ptr, &topo, gt->fuse_topo.l3_bank_mask, + sizeof(gt->fuse_topo.l3_bank_mask)); + if (err) + return err; + topo.type = DRM_XE_TOPO_EU_PER_DSS; err = copy_mask(&query_ptr, &topo, gt->fuse_topo.eu_mask_per_dss, diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 1446c3bae515..d7b0903c22b2 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -508,6 +508,7 @@ struct drm_xe_query_gt_list { * containing the following in mask: * ``DSS_COMPUTE ff ff ff ff 00 00 00 00`` * means 32 DSS are available for compute. + * - %DRM_XE_TOPO_L3_BANK - To query the mask of enabled L3 banks * - %DRM_XE_TOPO_EU_PER_DSS - To query the mask of Execution Units (EU) * available per Dual Sub Slices (DSS). For example a query response * containing the following in mask: @@ -520,6 +521,7 @@ struct drm_xe_query_topology_mask { #define DRM_XE_TOPO_DSS_GEOMETRY 1 #define DRM_XE_TOPO_DSS_COMPUTE 2 +#define DRM_XE_TOPO_L3_BANK 3 #define DRM_XE_TOPO_EU_PER_DSS 4 /** @type: type of mask */ __u16 type; -- cgit v1.2.3 From 8a0a7b98d4b6eeeab337ec25daa4bc0a5e710a15 Mon Sep 17 00:00:00 2001 From: Wayne Lin Date: Thu, 7 Mar 2024 14:29:57 +0800 Subject: drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Why] Commit: - commit 5aa1dfcdf0a4 ("drm/mst: Refactor the flow for payload allocation/removement") accidently overwrite the commit - commit 54d217406afe ("drm: use mgr->dev in drm_dbg_kms in drm_dp_add_payload_part2") which cause regression. [How] Recover the original NULL fix and remove the unnecessary input parameter 'state' for drm_dp_add_payload_part2(). Fixes: 5aa1dfcdf0a4 ("drm/mst: Refactor the flow for payload allocation/removement") Reported-by: Leon Weiß Link: https://lore.kernel.org/r/38c253ea42072cc825dc969ac4e6b9b600371cc8.camel@ruhr-uni-bochum.de/ Cc: lyude@redhat.com Cc: imre.deak@intel.com Cc: stable@vger.kernel.org Cc: regressions@lists.linux.dev Reviewed-by: Harry Wentland Acked-by: Jani Nikula Signed-off-by: Wayne Lin Signed-off-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/msgid/20240307062957.2323620-1-Wayne.Lin@amd.com --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- drivers/gpu/drm/display/drm_dp_mst_topology.c | 4 +--- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- drivers/gpu/drm/nouveau/dispnv50/disp.c | 2 +- include/drm/display/drm_dp_mst_helper.h | 1 - 5 files changed, 4 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index c27063305a13..2c36f3d00ca2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -363,7 +363,7 @@ void dm_helpers_dp_mst_send_payload_allocation( mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state); new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port); - ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload); + ret = drm_dp_add_payload_part2(mst_mgr, new_payload); if (ret) { amdgpu_dm_set_mst_status(&aconnector->mst_status, diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index 3577786b5db2..7f8e1cfbe19d 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -3421,7 +3421,6 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part2); /** * drm_dp_add_payload_part2() - Execute payload update part 2 * @mgr: Manager to use. - * @state: The global atomic state * @payload: The payload to update * * If @payload was successfully assigned a starting time slot by drm_dp_add_payload_part1(), this @@ -3430,14 +3429,13 @@ EXPORT_SYMBOL(drm_dp_remove_payload_part2); * Returns: 0 on success, negative error code on failure. */ int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr, - struct drm_atomic_state *state, struct drm_dp_mst_atomic_payload *payload) { int ret = 0; /* Skip failed payloads */ if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) { - drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", + drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n", payload->port->connector->name); return -EIO; } diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c772ba19c547..715d2f59f565 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1241,7 +1241,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state, if (first_mst_stream) intel_ddi_wait_for_fec_status(encoder, pipe_config, true); - drm_dp_add_payload_part2(&intel_dp->mst_mgr, &state->base, + drm_dp_add_payload_part2(&intel_dp->mst_mgr, drm_atomic_get_mst_payload_state(mst_state, connector->port)); if (DISPLAY_VER(dev_priv) >= 12) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 0c3d88ad0b0e..88728a0b2c25 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -915,7 +915,7 @@ nv50_msto_cleanup(struct drm_atomic_state *state, msto->disabled = false; drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload); } else if (msto->enabled) { - drm_dp_add_payload_part2(mgr, state, new_payload); + drm_dp_add_payload_part2(mgr, new_payload); msto->enabled = false; } } diff --git a/include/drm/display/drm_dp_mst_helper.h b/include/drm/display/drm_dp_mst_helper.h index 3546b58a121b..cfe096389d94 100644 --- a/include/drm/display/drm_dp_mst_helper.h +++ b/include/drm/display/drm_dp_mst_helper.h @@ -871,7 +871,6 @@ int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, struct drm_dp_mst_atomic_payload *payload); int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr, - struct drm_atomic_state *state, struct drm_dp_mst_atomic_payload *payload); void drm_dp_remove_payload_part1(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_topology_state *mst_state, -- cgit v1.2.3 From cfa7772880f845f5d6dbee69c441c6efbffa425b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 15 May 2024 19:56:50 +0300 Subject: drm/i915/pciids: switch to xe driver style PCI ID macros The PCI ID macros in xe_pciids.h allow passing in the macro to operate on each PCI ID, making it more flexible. Convert i915_pciids.h to the same pattern. INTEL_IVB_Q_IDS() for Quanta transcode remains a special case, and unconditionally uses INTEL_QUANTA_VGA_DEVICE(). Cc: Bjorn Helgaas Cc: linux-pci@vger.kernel.org Cc: Lucas De Marchi Cc: Rodrigo Vivi Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20240515165651.1230465-1-jani.nikula@intel.com Signed-off-by: Jani Nikula --- arch/x86/kernel/early-quirks.c | 80 +- .../gpu/drm/i915/display/intel_display_device.c | 86 +- drivers/gpu/drm/i915/i915_pci.c | 150 +-- drivers/gpu/drm/i915/intel_device_info.c | 88 +- include/drm/i915_pciids.h | 1348 ++++++++++---------- 5 files changed, 876 insertions(+), 876 deletions(-) (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index fd74d7f26f01..1c137771c5d2 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -518,46 +518,46 @@ static const struct intel_early_ops gen11_early_ops __initconst = { /* Intel integrated GPUs for which we need to reserve "stolen memory" */ static const struct pci_device_id intel_early_ids[] __initconst = { - INTEL_I830_IDS(&i830_early_ops), - INTEL_I845G_IDS(&i845_early_ops), - INTEL_I85X_IDS(&i85x_early_ops), - INTEL_I865G_IDS(&i865_early_ops), - INTEL_I915G_IDS(&gen3_early_ops), - INTEL_I915GM_IDS(&gen3_early_ops), - INTEL_I945G_IDS(&gen3_early_ops), - INTEL_I945GM_IDS(&gen3_early_ops), - INTEL_VLV_IDS(&gen6_early_ops), - INTEL_PNV_IDS(&gen3_early_ops), - INTEL_I965G_IDS(&gen3_early_ops), - INTEL_G33_IDS(&gen3_early_ops), - INTEL_I965GM_IDS(&gen3_early_ops), - INTEL_GM45_IDS(&gen3_early_ops), - INTEL_G45_IDS(&gen3_early_ops), - INTEL_ILK_IDS(&gen3_early_ops), - INTEL_SNB_IDS(&gen6_early_ops), - INTEL_IVB_IDS(&gen6_early_ops), - INTEL_HSW_IDS(&gen6_early_ops), - INTEL_BDW_IDS(&gen8_early_ops), - INTEL_CHV_IDS(&chv_early_ops), - INTEL_SKL_IDS(&gen9_early_ops), - INTEL_BXT_IDS(&gen9_early_ops), - INTEL_KBL_IDS(&gen9_early_ops), - INTEL_CFL_IDS(&gen9_early_ops), - INTEL_WHL_IDS(&gen9_early_ops), - INTEL_CML_IDS(&gen9_early_ops), - INTEL_GLK_IDS(&gen9_early_ops), - INTEL_CNL_IDS(&gen9_early_ops), - INTEL_ICL_IDS(&gen11_early_ops), - INTEL_EHL_IDS(&gen11_early_ops), - INTEL_JSL_IDS(&gen11_early_ops), - INTEL_TGL_IDS(&gen11_early_ops), - INTEL_RKL_IDS(&gen11_early_ops), - INTEL_ADLS_IDS(&gen11_early_ops), - INTEL_ADLP_IDS(&gen11_early_ops), - INTEL_ADLN_IDS(&gen11_early_ops), - INTEL_RPLS_IDS(&gen11_early_ops), - INTEL_RPLU_IDS(&gen11_early_ops), - INTEL_RPLP_IDS(&gen11_early_ops), + INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_early_ops), + INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845_early_ops), + INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_early_ops), + INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865_early_ops), + INTEL_I915G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_I945G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_VLV_IDS(INTEL_VGA_DEVICE, &gen6_early_ops), + INTEL_PNV_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_I965G_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_G33_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_G45_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_ILK_IDS(INTEL_VGA_DEVICE, &gen3_early_ops), + INTEL_SNB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops), + INTEL_IVB_IDS(INTEL_VGA_DEVICE, &gen6_early_ops), + INTEL_HSW_IDS(INTEL_VGA_DEVICE, &gen6_early_ops), + INTEL_BDW_IDS(INTEL_VGA_DEVICE, &gen8_early_ops), + INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_early_ops), + INTEL_SKL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_BXT_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_KBL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_CFL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_WHL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_CML_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_GLK_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_CNL_IDS(INTEL_VGA_DEVICE, &gen9_early_ops), + INTEL_ICL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_EHL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_JSL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_TGL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_RKL_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), + INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &gen11_early_ops), }; struct resource intel_graphics_stolen_res __ro_after_init = DEFINE_RES_MEM(0, 0); diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 89069cff06b4..950e66cdba0a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -788,7 +788,7 @@ __diag_pop(); static bool has_no_display(struct pci_dev *pdev) { static const struct pci_device_id ids[] = { - INTEL_IVB_Q_IDS(0), + INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, 0), {} }; @@ -802,48 +802,48 @@ static const struct { u32 devid; const struct intel_display_device_info *info; } intel_display_ids[] = { - INTEL_I830_IDS(&i830_display), - INTEL_I845G_IDS(&i845_display), - INTEL_I85X_IDS(&i85x_display), - INTEL_I865G_IDS(&i865g_display), - INTEL_I915G_IDS(&i915g_display), - INTEL_I915GM_IDS(&i915gm_display), - INTEL_I945G_IDS(&i945g_display), - INTEL_I945GM_IDS(&i945gm_display), - INTEL_I965G_IDS(&i965g_display), - INTEL_G33_IDS(&g33_display), - INTEL_I965GM_IDS(&i965gm_display), - INTEL_GM45_IDS(&gm45_display), - INTEL_G45_IDS(&g45_display), - INTEL_PNV_IDS(&pnv_display), - INTEL_ILK_D_IDS(&ilk_d_display), - INTEL_ILK_M_IDS(&ilk_m_display), - INTEL_SNB_IDS(&snb_display), - INTEL_IVB_IDS(&ivb_display), - INTEL_HSW_IDS(&hsw_display), - INTEL_VLV_IDS(&vlv_display), - INTEL_BDW_IDS(&bdw_display), - INTEL_CHV_IDS(&chv_display), - INTEL_SKL_IDS(&skl_display), - INTEL_BXT_IDS(&bxt_display), - INTEL_GLK_IDS(&glk_display), - INTEL_KBL_IDS(&skl_display), - INTEL_CFL_IDS(&skl_display), - INTEL_WHL_IDS(&skl_display), - INTEL_CML_IDS(&skl_display), - INTEL_ICL_IDS(&icl_display), - INTEL_EHL_IDS(&jsl_ehl_display), - INTEL_JSL_IDS(&jsl_ehl_display), - INTEL_TGL_IDS(&tgl_display), - INTEL_DG1_IDS(&dg1_display), - INTEL_RKL_IDS(&rkl_display), - INTEL_ADLS_IDS(&adl_s_display), - INTEL_RPLS_IDS(&adl_s_display), - INTEL_ADLP_IDS(&xe_lpd_display), - INTEL_ADLN_IDS(&xe_lpd_display), - INTEL_RPLU_IDS(&xe_lpd_display), - INTEL_RPLP_IDS(&xe_lpd_display), - INTEL_DG2_IDS(&xe_hpd_display), + INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_display), + INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845_display), + INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_display), + INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865g_display), + INTEL_I915G_IDS(INTEL_VGA_DEVICE, &i915g_display), + INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &i915gm_display), + INTEL_I945G_IDS(INTEL_VGA_DEVICE, &i945g_display), + INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &i945gm_display), + INTEL_I965G_IDS(INTEL_VGA_DEVICE, &i965g_display), + INTEL_G33_IDS(INTEL_VGA_DEVICE, &g33_display), + INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &i965gm_display), + INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gm45_display), + INTEL_G45_IDS(INTEL_VGA_DEVICE, &g45_display), + INTEL_PNV_IDS(INTEL_VGA_DEVICE, &pnv_display), + INTEL_ILK_D_IDS(INTEL_VGA_DEVICE, &ilk_d_display), + INTEL_ILK_M_IDS(INTEL_VGA_DEVICE, &ilk_m_display), + INTEL_SNB_IDS(INTEL_VGA_DEVICE, &snb_display), + INTEL_IVB_IDS(INTEL_VGA_DEVICE, &ivb_display), + INTEL_HSW_IDS(INTEL_VGA_DEVICE, &hsw_display), + INTEL_VLV_IDS(INTEL_VGA_DEVICE, &vlv_display), + INTEL_BDW_IDS(INTEL_VGA_DEVICE, &bdw_display), + INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_display), + INTEL_SKL_IDS(INTEL_VGA_DEVICE, &skl_display), + INTEL_BXT_IDS(INTEL_VGA_DEVICE, &bxt_display), + INTEL_GLK_IDS(INTEL_VGA_DEVICE, &glk_display), + INTEL_KBL_IDS(INTEL_VGA_DEVICE, &skl_display), + INTEL_CFL_IDS(INTEL_VGA_DEVICE, &skl_display), + INTEL_WHL_IDS(INTEL_VGA_DEVICE, &skl_display), + INTEL_CML_IDS(INTEL_VGA_DEVICE, &skl_display), + INTEL_ICL_IDS(INTEL_VGA_DEVICE, &icl_display), + INTEL_EHL_IDS(INTEL_VGA_DEVICE, &jsl_ehl_display), + INTEL_JSL_IDS(INTEL_VGA_DEVICE, &jsl_ehl_display), + INTEL_TGL_IDS(INTEL_VGA_DEVICE, &tgl_display), + INTEL_DG1_IDS(INTEL_VGA_DEVICE, &dg1_display), + INTEL_RKL_IDS(INTEL_VGA_DEVICE, &rkl_display), + INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &adl_s_display), + INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &adl_s_display), + INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &xe_lpd_display), + INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &xe_lpd_display), + INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &xe_lpd_display), + INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &xe_lpd_display), + INTEL_DG2_IDS(INTEL_VGA_DEVICE, &xe_hpd_display), /* * Do not add any GMD_ID-based platforms to this list. They will diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 0edd550d8555..2e33b56e1cc6 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -797,81 +797,81 @@ __diag_pop(); * PCI ID matches, otherwise we'll use the wrong info struct above. */ static const struct pci_device_id pciidlist[] = { - INTEL_I830_IDS(&i830_info), - INTEL_I845G_IDS(&i845g_info), - INTEL_I85X_IDS(&i85x_info), - INTEL_I865G_IDS(&i865g_info), - INTEL_I915G_IDS(&i915g_info), - INTEL_I915GM_IDS(&i915gm_info), - INTEL_I945G_IDS(&i945g_info), - INTEL_I945GM_IDS(&i945gm_info), - INTEL_I965G_IDS(&i965g_info), - INTEL_G33_IDS(&g33_info), - INTEL_I965GM_IDS(&i965gm_info), - INTEL_GM45_IDS(&gm45_info), - INTEL_G45_IDS(&g45_info), - INTEL_PNV_G_IDS(&pnv_g_info), - INTEL_PNV_M_IDS(&pnv_m_info), - INTEL_ILK_D_IDS(&ilk_d_info), - INTEL_ILK_M_IDS(&ilk_m_info), - INTEL_SNB_D_GT1_IDS(&snb_d_gt1_info), - INTEL_SNB_D_GT2_IDS(&snb_d_gt2_info), - INTEL_SNB_M_GT1_IDS(&snb_m_gt1_info), - INTEL_SNB_M_GT2_IDS(&snb_m_gt2_info), - INTEL_IVB_Q_IDS(&ivb_q_info), /* must be first IVB */ - INTEL_IVB_M_GT1_IDS(&ivb_m_gt1_info), - INTEL_IVB_M_GT2_IDS(&ivb_m_gt2_info), - INTEL_IVB_D_GT1_IDS(&ivb_d_gt1_info), - INTEL_IVB_D_GT2_IDS(&ivb_d_gt2_info), - INTEL_HSW_GT1_IDS(&hsw_gt1_info), - INTEL_HSW_GT2_IDS(&hsw_gt2_info), - INTEL_HSW_GT3_IDS(&hsw_gt3_info), - INTEL_VLV_IDS(&vlv_info), - INTEL_BDW_GT1_IDS(&bdw_gt1_info), - INTEL_BDW_GT2_IDS(&bdw_gt2_info), - INTEL_BDW_GT3_IDS(&bdw_gt3_info), - INTEL_BDW_RSVD_IDS(&bdw_rsvd_info), - INTEL_CHV_IDS(&chv_info), - INTEL_SKL_GT1_IDS(&skl_gt1_info), - INTEL_SKL_GT2_IDS(&skl_gt2_info), - INTEL_SKL_GT3_IDS(&skl_gt3_info), - INTEL_SKL_GT4_IDS(&skl_gt4_info), - INTEL_BXT_IDS(&bxt_info), - INTEL_GLK_IDS(&glk_info), - INTEL_KBL_GT1_IDS(&kbl_gt1_info), - INTEL_KBL_GT2_IDS(&kbl_gt2_info), - INTEL_KBL_GT3_IDS(&kbl_gt3_info), - INTEL_KBL_GT4_IDS(&kbl_gt3_info), - INTEL_AML_KBL_GT2_IDS(&kbl_gt2_info), - INTEL_CFL_S_GT1_IDS(&cfl_gt1_info), - INTEL_CFL_S_GT2_IDS(&cfl_gt2_info), - INTEL_CFL_H_GT1_IDS(&cfl_gt1_info), - INTEL_CFL_H_GT2_IDS(&cfl_gt2_info), - INTEL_CFL_U_GT2_IDS(&cfl_gt2_info), - INTEL_CFL_U_GT3_IDS(&cfl_gt3_info), - INTEL_WHL_U_GT1_IDS(&cfl_gt1_info), - INTEL_WHL_U_GT2_IDS(&cfl_gt2_info), - INTEL_AML_CFL_GT2_IDS(&cfl_gt2_info), - INTEL_WHL_U_GT3_IDS(&cfl_gt3_info), - INTEL_CML_GT1_IDS(&cml_gt1_info), - INTEL_CML_GT2_IDS(&cml_gt2_info), - INTEL_CML_U_GT1_IDS(&cml_gt1_info), - INTEL_CML_U_GT2_IDS(&cml_gt2_info), - INTEL_ICL_IDS(&icl_info), - INTEL_EHL_IDS(&ehl_info), - INTEL_JSL_IDS(&jsl_info), - INTEL_TGL_IDS(&tgl_info), - INTEL_RKL_IDS(&rkl_info), - INTEL_ADLS_IDS(&adl_s_info), - INTEL_ADLP_IDS(&adl_p_info), - INTEL_ADLN_IDS(&adl_p_info), - INTEL_DG1_IDS(&dg1_info), - INTEL_RPLS_IDS(&adl_s_info), - INTEL_RPLU_IDS(&adl_p_info), - INTEL_RPLP_IDS(&adl_p_info), - INTEL_DG2_IDS(&dg2_info), - INTEL_ATS_M_IDS(&ats_m_info), - INTEL_MTL_IDS(&mtl_info), + INTEL_I830_IDS(INTEL_VGA_DEVICE, &i830_info), + INTEL_I845G_IDS(INTEL_VGA_DEVICE, &i845g_info), + INTEL_I85X_IDS(INTEL_VGA_DEVICE, &i85x_info), + INTEL_I865G_IDS(INTEL_VGA_DEVICE, &i865g_info), + INTEL_I915G_IDS(INTEL_VGA_DEVICE, &i915g_info), + INTEL_I915GM_IDS(INTEL_VGA_DEVICE, &i915gm_info), + INTEL_I945G_IDS(INTEL_VGA_DEVICE, &i945g_info), + INTEL_I945GM_IDS(INTEL_VGA_DEVICE, &i945gm_info), + INTEL_I965G_IDS(INTEL_VGA_DEVICE, &i965g_info), + INTEL_G33_IDS(INTEL_VGA_DEVICE, &g33_info), + INTEL_I965GM_IDS(INTEL_VGA_DEVICE, &i965gm_info), + INTEL_GM45_IDS(INTEL_VGA_DEVICE, &gm45_info), + INTEL_G45_IDS(INTEL_VGA_DEVICE, &g45_info), + INTEL_PNV_G_IDS(INTEL_VGA_DEVICE, &pnv_g_info), + INTEL_PNV_M_IDS(INTEL_VGA_DEVICE, &pnv_m_info), + INTEL_ILK_D_IDS(INTEL_VGA_DEVICE, &ilk_d_info), + INTEL_ILK_M_IDS(INTEL_VGA_DEVICE, &ilk_m_info), + INTEL_SNB_D_GT1_IDS(INTEL_VGA_DEVICE, &snb_d_gt1_info), + INTEL_SNB_D_GT2_IDS(INTEL_VGA_DEVICE, &snb_d_gt2_info), + INTEL_SNB_M_GT1_IDS(INTEL_VGA_DEVICE, &snb_m_gt1_info), + INTEL_SNB_M_GT2_IDS(INTEL_VGA_DEVICE, &snb_m_gt2_info), + INTEL_IVB_Q_IDS(INTEL_VGA_DEVICE, &ivb_q_info), /* must be first IVB */ + INTEL_IVB_M_GT1_IDS(INTEL_VGA_DEVICE, &ivb_m_gt1_info), + INTEL_IVB_M_GT2_IDS(INTEL_VGA_DEVICE, &ivb_m_gt2_info), + INTEL_IVB_D_GT1_IDS(INTEL_VGA_DEVICE, &ivb_d_gt1_info), + INTEL_IVB_D_GT2_IDS(INTEL_VGA_DEVICE, &ivb_d_gt2_info), + INTEL_HSW_GT1_IDS(INTEL_VGA_DEVICE, &hsw_gt1_info), + INTEL_HSW_GT2_IDS(INTEL_VGA_DEVICE, &hsw_gt2_info), + INTEL_HSW_GT3_IDS(INTEL_VGA_DEVICE, &hsw_gt3_info), + INTEL_VLV_IDS(INTEL_VGA_DEVICE, &vlv_info), + INTEL_BDW_GT1_IDS(INTEL_VGA_DEVICE, &bdw_gt1_info), + INTEL_BDW_GT2_IDS(INTEL_VGA_DEVICE, &bdw_gt2_info), + INTEL_BDW_GT3_IDS(INTEL_VGA_DEVICE, &bdw_gt3_info), + INTEL_BDW_RSVD_IDS(INTEL_VGA_DEVICE, &bdw_rsvd_info), + INTEL_CHV_IDS(INTEL_VGA_DEVICE, &chv_info), + INTEL_SKL_GT1_IDS(INTEL_VGA_DEVICE, &skl_gt1_info), + INTEL_SKL_GT2_IDS(INTEL_VGA_DEVICE, &skl_gt2_info), + INTEL_SKL_GT3_IDS(INTEL_VGA_DEVICE, &skl_gt3_info), + INTEL_SKL_GT4_IDS(INTEL_VGA_DEVICE, &skl_gt4_info), + INTEL_BXT_IDS(INTEL_VGA_DEVICE, &bxt_info), + INTEL_GLK_IDS(INTEL_VGA_DEVICE, &glk_info), + INTEL_KBL_GT1_IDS(INTEL_VGA_DEVICE, &kbl_gt1_info), + INTEL_KBL_GT2_IDS(INTEL_VGA_DEVICE, &kbl_gt2_info), + INTEL_KBL_GT3_IDS(INTEL_VGA_DEVICE, &kbl_gt3_info), + INTEL_KBL_GT4_IDS(INTEL_VGA_DEVICE, &kbl_gt3_info), + INTEL_AML_KBL_GT2_IDS(INTEL_VGA_DEVICE, &kbl_gt2_info), + INTEL_CFL_S_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info), + INTEL_CFL_S_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info), + INTEL_CFL_H_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info), + INTEL_CFL_H_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info), + INTEL_CFL_U_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info), + INTEL_CFL_U_GT3_IDS(INTEL_VGA_DEVICE, &cfl_gt3_info), + INTEL_WHL_U_GT1_IDS(INTEL_VGA_DEVICE, &cfl_gt1_info), + INTEL_WHL_U_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info), + INTEL_AML_CFL_GT2_IDS(INTEL_VGA_DEVICE, &cfl_gt2_info), + INTEL_WHL_U_GT3_IDS(INTEL_VGA_DEVICE, &cfl_gt3_info), + INTEL_CML_GT1_IDS(INTEL_VGA_DEVICE, &cml_gt1_info), + INTEL_CML_GT2_IDS(INTEL_VGA_DEVICE, &cml_gt2_info), + INTEL_CML_U_GT1_IDS(INTEL_VGA_DEVICE, &cml_gt1_info), + INTEL_CML_U_GT2_IDS(INTEL_VGA_DEVICE, &cml_gt2_info), + INTEL_ICL_IDS(INTEL_VGA_DEVICE, &icl_info), + INTEL_EHL_IDS(INTEL_VGA_DEVICE, &ehl_info), + INTEL_JSL_IDS(INTEL_VGA_DEVICE, &jsl_info), + INTEL_TGL_IDS(INTEL_VGA_DEVICE, &tgl_info), + INTEL_RKL_IDS(INTEL_VGA_DEVICE, &rkl_info), + INTEL_ADLS_IDS(INTEL_VGA_DEVICE, &adl_s_info), + INTEL_ADLP_IDS(INTEL_VGA_DEVICE, &adl_p_info), + INTEL_ADLN_IDS(INTEL_VGA_DEVICE, &adl_p_info), + INTEL_DG1_IDS(INTEL_VGA_DEVICE, &dg1_info), + INTEL_RPLS_IDS(INTEL_VGA_DEVICE, &adl_s_info), + INTEL_RPLU_IDS(INTEL_VGA_DEVICE, &adl_p_info), + INTEL_RPLP_IDS(INTEL_VGA_DEVICE, &adl_p_info), + INTEL_DG2_IDS(INTEL_VGA_DEVICE, &dg2_info), + INTEL_ATS_M_IDS(INTEL_VGA_DEVICE, &ats_m_info), + INTEL_MTL_IDS(INTEL_VGA_DEVICE, &mtl_info), {} }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index a39497971994..82bb34416fb1 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -131,77 +131,77 @@ void intel_device_info_print(const struct intel_device_info *info, #define INTEL_VGA_DEVICE(id, info) (id) static const u16 subplatform_ult_ids[] = { - INTEL_HSW_ULT_GT1_IDS(0), - INTEL_HSW_ULT_GT2_IDS(0), - INTEL_HSW_ULT_GT3_IDS(0), - INTEL_BDW_ULT_GT1_IDS(0), - INTEL_BDW_ULT_GT2_IDS(0), - INTEL_BDW_ULT_GT3_IDS(0), - INTEL_BDW_ULT_RSVD_IDS(0), - INTEL_SKL_ULT_GT1_IDS(0), - INTEL_SKL_ULT_GT2_IDS(0), - INTEL_SKL_ULT_GT3_IDS(0), - INTEL_KBL_ULT_GT1_IDS(0), - INTEL_KBL_ULT_GT2_IDS(0), - INTEL_KBL_ULT_GT3_IDS(0), - INTEL_CFL_U_GT2_IDS(0), - INTEL_CFL_U_GT3_IDS(0), - INTEL_WHL_U_GT1_IDS(0), - INTEL_WHL_U_GT2_IDS(0), - INTEL_WHL_U_GT3_IDS(0), - INTEL_CML_U_GT1_IDS(0), - INTEL_CML_U_GT2_IDS(0), + INTEL_HSW_ULT_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_HSW_ULT_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_HSW_ULT_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULT_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULT_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULT_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULT_RSVD_IDS(INTEL_VGA_DEVICE, 0), + INTEL_SKL_ULT_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_SKL_ULT_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_SKL_ULT_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_KBL_ULT_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_KBL_ULT_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_KBL_ULT_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_CFL_U_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_CFL_U_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_WHL_U_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_WHL_U_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_WHL_U_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_CML_U_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_CML_U_GT2_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_ulx_ids[] = { - INTEL_HSW_ULX_GT1_IDS(0), - INTEL_HSW_ULX_GT2_IDS(0), - INTEL_BDW_ULX_GT1_IDS(0), - INTEL_BDW_ULX_GT2_IDS(0), - INTEL_BDW_ULX_GT3_IDS(0), - INTEL_BDW_ULX_RSVD_IDS(0), - INTEL_SKL_ULX_GT1_IDS(0), - INTEL_SKL_ULX_GT2_IDS(0), - INTEL_KBL_ULX_GT1_IDS(0), - INTEL_KBL_ULX_GT2_IDS(0), - INTEL_AML_KBL_GT2_IDS(0), - INTEL_AML_CFL_GT2_IDS(0), + INTEL_HSW_ULX_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_HSW_ULX_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULX_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULX_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULX_GT3_IDS(INTEL_VGA_DEVICE, 0), + INTEL_BDW_ULX_RSVD_IDS(INTEL_VGA_DEVICE, 0), + INTEL_SKL_ULX_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_SKL_ULX_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_KBL_ULX_GT1_IDS(INTEL_VGA_DEVICE, 0), + INTEL_KBL_ULX_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_AML_KBL_GT2_IDS(INTEL_VGA_DEVICE, 0), + INTEL_AML_CFL_GT2_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_portf_ids[] = { - INTEL_ICL_PORT_F_IDS(0), + INTEL_ICL_PORT_F_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_uy_ids[] = { - INTEL_TGL_GT2_IDS(0), + INTEL_TGL_GT2_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_n_ids[] = { - INTEL_ADLN_IDS(0), + INTEL_ADLN_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_rpl_ids[] = { - INTEL_RPLS_IDS(0), - INTEL_RPLU_IDS(0), - INTEL_RPLP_IDS(0), + INTEL_RPLS_IDS(INTEL_VGA_DEVICE, 0), + INTEL_RPLU_IDS(INTEL_VGA_DEVICE, 0), + INTEL_RPLP_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_rplu_ids[] = { - INTEL_RPLU_IDS(0), + INTEL_RPLU_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_g10_ids[] = { - INTEL_DG2_G10_IDS(0), - INTEL_ATS_M150_IDS(0), + INTEL_DG2_G10_IDS(INTEL_VGA_DEVICE, 0), + INTEL_ATS_M150_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_g11_ids[] = { - INTEL_DG2_G11_IDS(0), - INTEL_ATS_M75_IDS(0), + INTEL_DG2_G11_IDS(INTEL_VGA_DEVICE, 0), + INTEL_ATS_M75_IDS(INTEL_VGA_DEVICE, 0), }; static const u16 subplatform_g12_ids[] = { - INTEL_DG2_G12_IDS(0), + INTEL_DG2_G12_IDS(INTEL_VGA_DEVICE, 0), }; static bool find_devid(u16 id, const u16 *p, unsigned int num) diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 04f6ca3dc5c1..3e39d644ebaa 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -35,752 +35,752 @@ * Don't use C99 here because "class" is reserved and we want to * give userspace flexibility. */ -#define INTEL_VGA_DEVICE(id, info) { \ - 0x8086, id, \ - ~0, ~0, \ - 0x030000, 0xff0000, \ +#define INTEL_VGA_DEVICE(id, info) { \ + 0x8086, id, \ + ~0, ~0, \ + 0x030000, 0xff0000, \ (unsigned long) info } -#define INTEL_QUANTA_VGA_DEVICE(info) { \ - 0x8086, 0x16a, \ - 0x152d, 0x8990, \ - 0x030000, 0xff0000, \ +#define INTEL_QUANTA_VGA_DEVICE(info) { \ + 0x8086, 0x16a, \ + 0x152d, 0x8990, \ + 0x030000, 0xff0000, \ (unsigned long) info } -#define INTEL_I810_IDS(info) \ - INTEL_VGA_DEVICE(0x7121, info), /* I810 */ \ - INTEL_VGA_DEVICE(0x7123, info), /* I810_DC100 */ \ - INTEL_VGA_DEVICE(0x7125, info) /* I810_E */ +#define INTEL_I810_IDS(MACRO__, ...) \ + MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \ + MACRO__(0x7123, ## __VA_ARGS__), /* I810_DC100 */ \ + MACRO__(0x7125, ## __VA_ARGS__) /* I810_E */ -#define INTEL_I815_IDS(info) \ - INTEL_VGA_DEVICE(0x1132, info) /* I815*/ +#define INTEL_I815_IDS(MACRO__, ...) \ + MACRO__(0x1132, ## __VA_ARGS__) /* I815*/ -#define INTEL_I830_IDS(info) \ - INTEL_VGA_DEVICE(0x3577, info) +#define INTEL_I830_IDS(MACRO__, ...) \ + MACRO__(0x3577, ## __VA_ARGS__) -#define INTEL_I845G_IDS(info) \ - INTEL_VGA_DEVICE(0x2562, info) +#define INTEL_I845G_IDS(MACRO__, ...) \ + MACRO__(0x2562, ## __VA_ARGS__) -#define INTEL_I85X_IDS(info) \ - INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \ - INTEL_VGA_DEVICE(0x358e, info) +#define INTEL_I85X_IDS(MACRO__, ...) \ + MACRO__(0x3582, ## __VA_ARGS__), /* I855_GM */ \ + MACRO__(0x358e, ## __VA_ARGS__) -#define INTEL_I865G_IDS(info) \ - INTEL_VGA_DEVICE(0x2572, info) /* I865_G */ +#define INTEL_I865G_IDS(MACRO__, ...) \ + MACRO__(0x2572, ## __VA_ARGS__) /* I865_G */ -#define INTEL_I915G_IDS(info) \ - INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \ - INTEL_VGA_DEVICE(0x258a, info) /* E7221_G */ +#define INTEL_I915G_IDS(MACRO__, ...) \ + MACRO__(0x2582, ## __VA_ARGS__), /* I915_G */ \ + MACRO__(0x258a, ## __VA_ARGS__) /* E7221_G */ -#define INTEL_I915GM_IDS(info) \ - INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */ +#define INTEL_I915GM_IDS(MACRO__, ...) \ + MACRO__(0x2592, ## __VA_ARGS__) /* I915_GM */ -#define INTEL_I945G_IDS(info) \ - INTEL_VGA_DEVICE(0x2772, info) /* I945_G */ +#define INTEL_I945G_IDS(MACRO__, ...) \ + MACRO__(0x2772, ## __VA_ARGS__) /* I945_G */ -#define INTEL_I945GM_IDS(info) \ - INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \ - INTEL_VGA_DEVICE(0x27ae, info) /* I945_GME */ +#define INTEL_I945GM_IDS(MACRO__, ...) \ + MACRO__(0x27a2, ## __VA_ARGS__), /* I945_GM */ \ + MACRO__(0x27ae, ## __VA_ARGS__) /* I945_GME */ -#define INTEL_I965G_IDS(info) \ - INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */ \ - INTEL_VGA_DEVICE(0x2982, info), /* G35_G */ \ - INTEL_VGA_DEVICE(0x2992, info), /* I965_Q */ \ - INTEL_VGA_DEVICE(0x29a2, info) /* I965_G */ +#define INTEL_I965G_IDS(MACRO__, ...) \ + MACRO__(0x2972, ## __VA_ARGS__), /* I946_GZ */ \ + MACRO__(0x2982, ## __VA_ARGS__), /* G35_G */ \ + MACRO__(0x2992, ## __VA_ARGS__), /* I965_Q */ \ + MACRO__(0x29a2, ## __VA_ARGS__) /* I965_G */ -#define INTEL_G33_IDS(info) \ - INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \ - INTEL_VGA_DEVICE(0x29c2, info), /* G33_G */ \ - INTEL_VGA_DEVICE(0x29d2, info) /* Q33_G */ +#define INTEL_G33_IDS(MACRO__, ...) \ + MACRO__(0x29b2, ## __VA_ARGS__), /* Q35_G */ \ + MACRO__(0x29c2, ## __VA_ARGS__), /* G33_G */ \ + MACRO__(0x29d2, ## __VA_ARGS__) /* Q33_G */ -#define INTEL_I965GM_IDS(info) \ - INTEL_VGA_DEVICE(0x2a02, info), /* I965_GM */ \ - INTEL_VGA_DEVICE(0x2a12, info) /* I965_GME */ +#define INTEL_I965GM_IDS(MACRO__, ...) \ + MACRO__(0x2a02, ## __VA_ARGS__), /* I965_GM */ \ + MACRO__(0x2a12, ## __VA_ARGS__) /* I965_GME */ -#define INTEL_GM45_IDS(info) \ - INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */ +#define INTEL_GM45_IDS(MACRO__, ...) \ + MACRO__(0x2a42, ## __VA_ARGS__) /* GM45_G */ -#define INTEL_G45_IDS(info) \ - INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \ - INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \ - INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \ - INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \ - INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \ - INTEL_VGA_DEVICE(0x2e92, info) /* B43_G.1 */ - -#define INTEL_PNV_G_IDS(info) \ - INTEL_VGA_DEVICE(0xa001, info) - -#define INTEL_PNV_M_IDS(info) \ - INTEL_VGA_DEVICE(0xa011, info) - -#define INTEL_PNV_IDS(info) \ - INTEL_PNV_G_IDS(info), \ - INTEL_PNV_M_IDS(info) - -#define INTEL_ILK_D_IDS(info) \ - INTEL_VGA_DEVICE(0x0042, info) - -#define INTEL_ILK_M_IDS(info) \ - INTEL_VGA_DEVICE(0x0046, info) - -#define INTEL_ILK_IDS(info) \ - INTEL_ILK_D_IDS(info), \ - INTEL_ILK_M_IDS(info) - -#define INTEL_SNB_D_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0102, info), \ - INTEL_VGA_DEVICE(0x010A, info) - -#define INTEL_SNB_D_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0112, info), \ - INTEL_VGA_DEVICE(0x0122, info) - -#define INTEL_SNB_D_IDS(info) \ - INTEL_SNB_D_GT1_IDS(info), \ - INTEL_SNB_D_GT2_IDS(info) - -#define INTEL_SNB_M_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0106, info) - -#define INTEL_SNB_M_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0116, info), \ - INTEL_VGA_DEVICE(0x0126, info) - -#define INTEL_SNB_M_IDS(info) \ - INTEL_SNB_M_GT1_IDS(info), \ - INTEL_SNB_M_GT2_IDS(info) - -#define INTEL_SNB_IDS(info) \ - INTEL_SNB_D_IDS(info), \ - INTEL_SNB_M_IDS(info) - -#define INTEL_IVB_M_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0156, info) /* GT1 mobile */ - -#define INTEL_IVB_M_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */ - -#define INTEL_IVB_M_IDS(info) \ - INTEL_IVB_M_GT1_IDS(info), \ - INTEL_IVB_M_GT2_IDS(info) - -#define INTEL_IVB_D_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \ - INTEL_VGA_DEVICE(0x015a, info) /* GT1 server */ - -#define INTEL_IVB_D_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \ - INTEL_VGA_DEVICE(0x016a, info) /* GT2 server */ - -#define INTEL_IVB_D_IDS(info) \ - INTEL_IVB_D_GT1_IDS(info), \ - INTEL_IVB_D_GT2_IDS(info) - -#define INTEL_IVB_IDS(info) \ - INTEL_IVB_M_IDS(info), \ - INTEL_IVB_D_IDS(info) - -#define INTEL_IVB_Q_IDS(info) \ - INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */ - -#define INTEL_HSW_ULT_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \ - INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ - INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \ - INTEL_VGA_DEVICE(0x0A0B, info) /* ULT GT1 reserved */ - -#define INTEL_HSW_ULX_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x0A0E, info) /* ULX GT1 mobile */ - -#define INTEL_HSW_GT1_IDS(info) \ - INTEL_HSW_ULT_GT1_IDS(info), \ - INTEL_HSW_ULX_GT1_IDS(info), \ - INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \ - INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \ - INTEL_VGA_DEVICE(0x040A, info), /* GT1 server */ \ - INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \ - INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \ - INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \ - INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \ - INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \ - INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ - INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \ - INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \ - INTEL_VGA_DEVICE(0x0D0E, info) /* CRW GT1 reserved */ - -#define INTEL_HSW_ULT_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \ - INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ - INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \ - INTEL_VGA_DEVICE(0x0A1B, info) /* ULT GT2 reserved */ \ - -#define INTEL_HSW_ULX_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x0A1E, info) /* ULX GT2 mobile */ \ - -#define INTEL_HSW_GT2_IDS(info) \ - INTEL_HSW_ULT_GT2_IDS(info), \ - INTEL_HSW_ULX_GT2_IDS(info), \ - INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \ - INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \ - INTEL_VGA_DEVICE(0x041A, info), /* GT2 server */ \ - INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \ - INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \ - INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \ - INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \ - INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \ - INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \ - INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \ - INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \ - INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ - INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \ - INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \ - INTEL_VGA_DEVICE(0x0D1E, info) /* CRW GT2 reserved */ - -#define INTEL_HSW_ULT_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \ - INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \ - INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \ - INTEL_VGA_DEVICE(0x0A2E, info) /* ULT GT3 reserved */ - -#define INTEL_HSW_GT3_IDS(info) \ - INTEL_HSW_ULT_GT3_IDS(info), \ - INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \ - INTEL_VGA_DEVICE(0x0426, info), /* GT3 mobile */ \ - INTEL_VGA_DEVICE(0x042A, info), /* GT3 server */ \ - INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \ - INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \ - INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \ - INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \ - INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \ - INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \ - INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \ - INTEL_VGA_DEVICE(0x0D26, info), /* CRW GT3 mobile */ \ - INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \ - INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \ - INTEL_VGA_DEVICE(0x0D2E, info) /* CRW GT3 reserved */ - -#define INTEL_HSW_IDS(info) \ - INTEL_HSW_GT1_IDS(info), \ - INTEL_HSW_GT2_IDS(info), \ - INTEL_HSW_GT3_IDS(info) - -#define INTEL_VLV_IDS(info) \ - INTEL_VGA_DEVICE(0x0f30, info), \ - INTEL_VGA_DEVICE(0x0f31, info), \ - INTEL_VGA_DEVICE(0x0f32, info), \ - INTEL_VGA_DEVICE(0x0f33, info) - -#define INTEL_BDW_ULT_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \ - INTEL_VGA_DEVICE(0x160B, info) /* GT1 Iris */ - -#define INTEL_BDW_ULX_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x160E, info) /* GT1 ULX */ - -#define INTEL_BDW_GT1_IDS(info) \ - INTEL_BDW_ULT_GT1_IDS(info), \ - INTEL_BDW_ULX_GT1_IDS(info), \ - INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \ - INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \ - INTEL_VGA_DEVICE(0x160D, info) /* GT1 Workstation */ - -#define INTEL_BDW_ULT_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \ - INTEL_VGA_DEVICE(0x161B, info) /* GT2 ULT */ - -#define INTEL_BDW_ULX_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x161E, info) /* GT2 ULX */ - -#define INTEL_BDW_GT2_IDS(info) \ - INTEL_BDW_ULT_GT2_IDS(info), \ - INTEL_BDW_ULX_GT2_IDS(info), \ - INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */ \ - INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \ - INTEL_VGA_DEVICE(0x161D, info) /* GT2 Workstation */ - -#define INTEL_BDW_ULT_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \ - INTEL_VGA_DEVICE(0x162B, info) /* Iris */ \ - -#define INTEL_BDW_ULX_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x162E, info) /* ULX */ - -#define INTEL_BDW_GT3_IDS(info) \ - INTEL_BDW_ULT_GT3_IDS(info), \ - INTEL_BDW_ULX_GT3_IDS(info), \ - INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \ - INTEL_VGA_DEVICE(0x162A, info), /* Server */ \ - INTEL_VGA_DEVICE(0x162D, info) /* Workstation */ - -#define INTEL_BDW_ULT_RSVD_IDS(info) \ - INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \ - INTEL_VGA_DEVICE(0x163B, info) /* Iris */ - -#define INTEL_BDW_ULX_RSVD_IDS(info) \ - INTEL_VGA_DEVICE(0x163E, info) /* ULX */ - -#define INTEL_BDW_RSVD_IDS(info) \ - INTEL_BDW_ULT_RSVD_IDS(info), \ - INTEL_BDW_ULX_RSVD_IDS(info), \ - INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \ - INTEL_VGA_DEVICE(0x163A, info), /* Server */ \ - INTEL_VGA_DEVICE(0x163D, info) /* Workstation */ - -#define INTEL_BDW_IDS(info) \ - INTEL_BDW_GT1_IDS(info), \ - INTEL_BDW_GT2_IDS(info), \ - INTEL_BDW_GT3_IDS(info), \ - INTEL_BDW_RSVD_IDS(info) - -#define INTEL_CHV_IDS(info) \ - INTEL_VGA_DEVICE(0x22b0, info), \ - INTEL_VGA_DEVICE(0x22b1, info), \ - INTEL_VGA_DEVICE(0x22b2, info), \ - INTEL_VGA_DEVICE(0x22b3, info) - -#define INTEL_SKL_ULT_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \ - INTEL_VGA_DEVICE(0x1913, info) /* ULT GT1.5 */ - -#define INTEL_SKL_ULX_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \ - INTEL_VGA_DEVICE(0x1915, info) /* ULX GT1.5 */ - -#define INTEL_SKL_GT1_IDS(info) \ - INTEL_SKL_ULT_GT1_IDS(info), \ - INTEL_SKL_ULX_GT1_IDS(info), \ - INTEL_VGA_DEVICE(0x1902, info), /* DT GT1 */ \ - INTEL_VGA_DEVICE(0x190A, info), /* SRV GT1 */ \ - INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \ - INTEL_VGA_DEVICE(0x1917, info) /* DT GT1.5 */ - -#define INTEL_SKL_ULT_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \ - INTEL_VGA_DEVICE(0x1921, info) /* ULT GT2F */ - -#define INTEL_SKL_ULX_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x191E, info) /* ULX GT2 */ - -#define INTEL_SKL_GT2_IDS(info) \ - INTEL_SKL_ULT_GT2_IDS(info), \ - INTEL_SKL_ULX_GT2_IDS(info), \ - INTEL_VGA_DEVICE(0x1912, info), /* DT GT2 */ \ - INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \ - INTEL_VGA_DEVICE(0x191D, info) /* WKS GT2 */ - -#define INTEL_SKL_ULT_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3e */ \ - INTEL_VGA_DEVICE(0x1927, info) /* ULT GT3e */ - -#define INTEL_SKL_GT3_IDS(info) \ - INTEL_SKL_ULT_GT3_IDS(info), \ - INTEL_VGA_DEVICE(0x192A, info), /* SRV GT3 */ \ - INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3e */ \ - INTEL_VGA_DEVICE(0x192D, info) /* SRV GT3e */ - -#define INTEL_SKL_GT4_IDS(info) \ - INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \ - INTEL_VGA_DEVICE(0x193A, info), /* SRV GT4e */ \ - INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4e */ \ - INTEL_VGA_DEVICE(0x193D, info) /* WKS GT4e */ - -#define INTEL_SKL_IDS(info) \ - INTEL_SKL_GT1_IDS(info), \ - INTEL_SKL_GT2_IDS(info), \ - INTEL_SKL_GT3_IDS(info), \ - INTEL_SKL_GT4_IDS(info) - -#define INTEL_BXT_IDS(info) \ - INTEL_VGA_DEVICE(0x0A84, info), \ - INTEL_VGA_DEVICE(0x1A84, info), \ - INTEL_VGA_DEVICE(0x1A85, info), \ - INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \ - INTEL_VGA_DEVICE(0x5A85, info) /* APL HD Graphics 500 */ - -#define INTEL_GLK_IDS(info) \ - INTEL_VGA_DEVICE(0x3184, info), \ - INTEL_VGA_DEVICE(0x3185, info) - -#define INTEL_KBL_ULT_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \ - INTEL_VGA_DEVICE(0x5913, info) /* ULT GT1.5 */ - -#define INTEL_KBL_ULX_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \ - INTEL_VGA_DEVICE(0x5915, info) /* ULX GT1.5 */ - -#define INTEL_KBL_GT1_IDS(info) \ - INTEL_KBL_ULT_GT1_IDS(info), \ - INTEL_KBL_ULX_GT1_IDS(info), \ - INTEL_VGA_DEVICE(0x5902, info), /* DT GT1 */ \ - INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \ - INTEL_VGA_DEVICE(0x590A, info), /* SRV GT1 */ \ - INTEL_VGA_DEVICE(0x590B, info) /* Halo GT1 */ - -#define INTEL_KBL_ULT_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \ - INTEL_VGA_DEVICE(0x5921, info) /* ULT GT2F */ - -#define INTEL_KBL_ULX_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x591E, info) /* ULX GT2 */ - -#define INTEL_KBL_GT2_IDS(info) \ - INTEL_KBL_ULT_GT2_IDS(info), \ - INTEL_KBL_ULX_GT2_IDS(info), \ - INTEL_VGA_DEVICE(0x5912, info), /* DT GT2 */ \ - INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \ - INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \ - INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */ - -#define INTEL_KBL_ULT_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x5926, info) /* ULT GT3 */ - -#define INTEL_KBL_GT3_IDS(info) \ - INTEL_KBL_ULT_GT3_IDS(info), \ - INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */ - -#define INTEL_KBL_GT4_IDS(info) \ - INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */ +#define INTEL_G45_IDS(MACRO__, ...) \ + MACRO__(0x2e02, ## __VA_ARGS__), /* IGD_E_G */ \ + MACRO__(0x2e12, ## __VA_ARGS__), /* Q45_G */ \ + MACRO__(0x2e22, ## __VA_ARGS__), /* G45_G */ \ + MACRO__(0x2e32, ## __VA_ARGS__), /* G41_G */ \ + MACRO__(0x2e42, ## __VA_ARGS__), /* B43_G */ \ + MACRO__(0x2e92, ## __VA_ARGS__) /* B43_G.1 */ + +#define INTEL_PNV_G_IDS(MACRO__, ...) \ + MACRO__(0xa001, ## __VA_ARGS__) + +#define INTEL_PNV_M_IDS(MACRO__, ...) \ + MACRO__(0xa011, ## __VA_ARGS__) + +#define INTEL_PNV_IDS(MACRO__, ...) \ + INTEL_PNV_G_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_PNV_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_ILK_D_IDS(MACRO__, ...) \ + MACRO__(0x0042, ## __VA_ARGS__) + +#define INTEL_ILK_M_IDS(MACRO__, ...) \ + MACRO__(0x0046, ## __VA_ARGS__) + +#define INTEL_ILK_IDS(MACRO__, ...) \ + INTEL_ILK_D_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_ILK_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_D_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0102, ## __VA_ARGS__), \ + MACRO__(0x010A, ## __VA_ARGS__) + +#define INTEL_SNB_D_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0112, ## __VA_ARGS__), \ + MACRO__(0x0122, ## __VA_ARGS__) + +#define INTEL_SNB_D_IDS(MACRO__, ...) \ + INTEL_SNB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_M_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0106, ## __VA_ARGS__) + +#define INTEL_SNB_M_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0116, ## __VA_ARGS__), \ + MACRO__(0x0126, ## __VA_ARGS__) + +#define INTEL_SNB_M_IDS(MACRO__, ...) \ + INTEL_SNB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_IDS(MACRO__, ...) \ + INTEL_SNB_D_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_M_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0156, ## __VA_ARGS__) /* GT1 mobile */ + +#define INTEL_IVB_M_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0166, ## __VA_ARGS__) /* GT2 mobile */ + +#define INTEL_IVB_M_IDS(MACRO__, ...) \ + INTEL_IVB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_D_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0152, ## __VA_ARGS__), /* GT1 desktop */ \ + MACRO__(0x015a, ## __VA_ARGS__) /* GT1 server */ + +#define INTEL_IVB_D_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0162, ## __VA_ARGS__), /* GT2 desktop */ \ + MACRO__(0x016a, ## __VA_ARGS__) /* GT2 server */ + +#define INTEL_IVB_D_IDS(MACRO__, ...) \ + INTEL_IVB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_IDS(MACRO__, ...) \ + INTEL_IVB_M_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_D_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_Q_IDS(MACRO__, ...) \ + INTEL_QUANTA_VGA_DEVICE(__VA_ARGS__) /* Quanta transcode */ + +#define INTEL_HSW_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0A02, ## __VA_ARGS__), /* ULT GT1 desktop */ \ + MACRO__(0x0A06, ## __VA_ARGS__), /* ULT GT1 mobile */ \ + MACRO__(0x0A0A, ## __VA_ARGS__), /* ULT GT1 server */ \ + MACRO__(0x0A0B, ## __VA_ARGS__) /* ULT GT1 reserved */ + +#define INTEL_HSW_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0A0E, ## __VA_ARGS__) /* ULX GT1 mobile */ + +#define INTEL_HSW_GT1_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0402, ## __VA_ARGS__), /* GT1 desktop */ \ + MACRO__(0x0406, ## __VA_ARGS__), /* GT1 mobile */ \ + MACRO__(0x040A, ## __VA_ARGS__), /* GT1 server */ \ + MACRO__(0x040B, ## __VA_ARGS__), /* GT1 reserved */ \ + MACRO__(0x040E, ## __VA_ARGS__), /* GT1 reserved */ \ + MACRO__(0x0C02, ## __VA_ARGS__), /* SDV GT1 desktop */ \ + MACRO__(0x0C06, ## __VA_ARGS__), /* SDV GT1 mobile */ \ + MACRO__(0x0C0A, ## __VA_ARGS__), /* SDV GT1 server */ \ + MACRO__(0x0C0B, ## __VA_ARGS__), /* SDV GT1 reserved */ \ + MACRO__(0x0C0E, ## __VA_ARGS__), /* SDV GT1 reserved */ \ + MACRO__(0x0D02, ## __VA_ARGS__), /* CRW GT1 desktop */ \ + MACRO__(0x0D06, ## __VA_ARGS__), /* CRW GT1 mobile */ \ + MACRO__(0x0D0A, ## __VA_ARGS__), /* CRW GT1 server */ \ + MACRO__(0x0D0B, ## __VA_ARGS__), /* CRW GT1 reserved */ \ + MACRO__(0x0D0E, ## __VA_ARGS__) /* CRW GT1 reserved */ + +#define INTEL_HSW_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0A12, ## __VA_ARGS__), /* ULT GT2 desktop */ \ + MACRO__(0x0A16, ## __VA_ARGS__), /* ULT GT2 mobile */ \ + MACRO__(0x0A1A, ## __VA_ARGS__), /* ULT GT2 server */ \ + MACRO__(0x0A1B, ## __VA_ARGS__) /* ULT GT2 reserved */ \ + +#define INTEL_HSW_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0A1E, ## __VA_ARGS__) /* ULX GT2 mobile */ \ + +#define INTEL_HSW_GT2_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0412, ## __VA_ARGS__), /* GT2 desktop */ \ + MACRO__(0x0416, ## __VA_ARGS__), /* GT2 mobile */ \ + MACRO__(0x041A, ## __VA_ARGS__), /* GT2 server */ \ + MACRO__(0x041B, ## __VA_ARGS__), /* GT2 reserved */ \ + MACRO__(0x041E, ## __VA_ARGS__), /* GT2 reserved */ \ + MACRO__(0x0C12, ## __VA_ARGS__), /* SDV GT2 desktop */ \ + MACRO__(0x0C16, ## __VA_ARGS__), /* SDV GT2 mobile */ \ + MACRO__(0x0C1A, ## __VA_ARGS__), /* SDV GT2 server */ \ + MACRO__(0x0C1B, ## __VA_ARGS__), /* SDV GT2 reserved */ \ + MACRO__(0x0C1E, ## __VA_ARGS__), /* SDV GT2 reserved */ \ + MACRO__(0x0D12, ## __VA_ARGS__), /* CRW GT2 desktop */ \ + MACRO__(0x0D16, ## __VA_ARGS__), /* CRW GT2 mobile */ \ + MACRO__(0x0D1A, ## __VA_ARGS__), /* CRW GT2 server */ \ + MACRO__(0x0D1B, ## __VA_ARGS__), /* CRW GT2 reserved */ \ + MACRO__(0x0D1E, ## __VA_ARGS__) /* CRW GT2 reserved */ + +#define INTEL_HSW_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x0A22, ## __VA_ARGS__), /* ULT GT3 desktop */ \ + MACRO__(0x0A26, ## __VA_ARGS__), /* ULT GT3 mobile */ \ + MACRO__(0x0A2A, ## __VA_ARGS__), /* ULT GT3 server */ \ + MACRO__(0x0A2B, ## __VA_ARGS__), /* ULT GT3 reserved */ \ + MACRO__(0x0A2E, ## __VA_ARGS__) /* ULT GT3 reserved */ + +#define INTEL_HSW_GT3_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0422, ## __VA_ARGS__), /* GT3 desktop */ \ + MACRO__(0x0426, ## __VA_ARGS__), /* GT3 mobile */ \ + MACRO__(0x042A, ## __VA_ARGS__), /* GT3 server */ \ + MACRO__(0x042B, ## __VA_ARGS__), /* GT3 reserved */ \ + MACRO__(0x042E, ## __VA_ARGS__), /* GT3 reserved */ \ + MACRO__(0x0C22, ## __VA_ARGS__), /* SDV GT3 desktop */ \ + MACRO__(0x0C26, ## __VA_ARGS__), /* SDV GT3 mobile */ \ + MACRO__(0x0C2A, ## __VA_ARGS__), /* SDV GT3 server */ \ + MACRO__(0x0C2B, ## __VA_ARGS__), /* SDV GT3 reserved */ \ + MACRO__(0x0C2E, ## __VA_ARGS__), /* SDV GT3 reserved */ \ + MACRO__(0x0D22, ## __VA_ARGS__), /* CRW GT3 desktop */ \ + MACRO__(0x0D26, ## __VA_ARGS__), /* CRW GT3 mobile */ \ + MACRO__(0x0D2A, ## __VA_ARGS__), /* CRW GT3 server */ \ + MACRO__(0x0D2B, ## __VA_ARGS__), /* CRW GT3 reserved */ \ + MACRO__(0x0D2E, ## __VA_ARGS__) /* CRW GT3 reserved */ + +#define INTEL_HSW_IDS(MACRO__, ...) \ + INTEL_HSW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_GT3_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_VLV_IDS(MACRO__, ...) \ + MACRO__(0x0f30, ## __VA_ARGS__), \ + MACRO__(0x0f31, ## __VA_ARGS__), \ + MACRO__(0x0f32, ## __VA_ARGS__), \ + MACRO__(0x0f33, ## __VA_ARGS__) + +#define INTEL_BDW_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x1606, ## __VA_ARGS__), /* GT1 ULT */ \ + MACRO__(0x160B, ## __VA_ARGS__) /* GT1 Iris */ + +#define INTEL_BDW_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x160E, ## __VA_ARGS__) /* GT1 ULX */ + +#define INTEL_BDW_GT1_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1602, ## __VA_ARGS__), /* GT1 ULT */ \ + MACRO__(0x160A, ## __VA_ARGS__), /* GT1 Server */ \ + MACRO__(0x160D, ## __VA_ARGS__) /* GT1 Workstation */ + +#define INTEL_BDW_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x1616, ## __VA_ARGS__), /* GT2 ULT */ \ + MACRO__(0x161B, ## __VA_ARGS__) /* GT2 ULT */ + +#define INTEL_BDW_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x161E, ## __VA_ARGS__) /* GT2 ULX */ + +#define INTEL_BDW_GT2_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1612, ## __VA_ARGS__), /* GT2 Halo */ \ + MACRO__(0x161A, ## __VA_ARGS__), /* GT2 Server */ \ + MACRO__(0x161D, ## __VA_ARGS__) /* GT2 Workstation */ + +#define INTEL_BDW_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x1626, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x162B, ## __VA_ARGS__) /* Iris */ \ + +#define INTEL_BDW_ULX_GT3_IDS(MACRO__, ...) \ + MACRO__(0x162E, ## __VA_ARGS__) /* ULX */ + +#define INTEL_BDW_GT3_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1622, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x162A, ## __VA_ARGS__), /* Server */ \ + MACRO__(0x162D, ## __VA_ARGS__) /* Workstation */ + +#define INTEL_BDW_ULT_RSVD_IDS(MACRO__, ...) \ + MACRO__(0x1636, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x163B, ## __VA_ARGS__) /* Iris */ + +#define INTEL_BDW_ULX_RSVD_IDS(MACRO__, ...) \ + MACRO__(0x163E, ## __VA_ARGS__) /* ULX */ + +#define INTEL_BDW_RSVD_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1632, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x163A, ## __VA_ARGS__), /* Server */ \ + MACRO__(0x163D, ## __VA_ARGS__) /* Workstation */ + +#define INTEL_BDW_IDS(MACRO__, ...) \ + INTEL_BDW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_RSVD_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_CHV_IDS(MACRO__, ...) \ + MACRO__(0x22b0, ## __VA_ARGS__), \ + MACRO__(0x22b1, ## __VA_ARGS__), \ + MACRO__(0x22b2, ## __VA_ARGS__), \ + MACRO__(0x22b3, ## __VA_ARGS__) + +#define INTEL_SKL_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x1906, ## __VA_ARGS__), /* ULT GT1 */ \ + MACRO__(0x1913, ## __VA_ARGS__) /* ULT GT1.5 */ + +#define INTEL_SKL_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x190E, ## __VA_ARGS__), /* ULX GT1 */ \ + MACRO__(0x1915, ## __VA_ARGS__) /* ULX GT1.5 */ + +#define INTEL_SKL_GT1_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1902, ## __VA_ARGS__), /* DT GT1 */ \ + MACRO__(0x190A, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x190B, ## __VA_ARGS__), /* Halo GT1 */ \ + MACRO__(0x1917, ## __VA_ARGS__) /* DT GT1.5 */ + +#define INTEL_SKL_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x1916, ## __VA_ARGS__), /* ULT GT2 */ \ + MACRO__(0x1921, ## __VA_ARGS__) /* ULT GT2F */ + +#define INTEL_SKL_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x191E, ## __VA_ARGS__) /* ULX GT2 */ + +#define INTEL_SKL_GT2_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1912, ## __VA_ARGS__), /* DT GT2 */ \ + MACRO__(0x191A, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x191B, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x191D, ## __VA_ARGS__) /* WKS GT2 */ + +#define INTEL_SKL_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x1923, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x1926, ## __VA_ARGS__), /* ULT GT3e */ \ + MACRO__(0x1927, ## __VA_ARGS__) /* ULT GT3e */ + +#define INTEL_SKL_GT3_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x192A, ## __VA_ARGS__), /* SRV GT3 */ \ + MACRO__(0x192B, ## __VA_ARGS__), /* Halo GT3e */ \ + MACRO__(0x192D, ## __VA_ARGS__) /* SRV GT3e */ + +#define INTEL_SKL_GT4_IDS(MACRO__, ...) \ + MACRO__(0x1932, ## __VA_ARGS__), /* DT GT4 */ \ + MACRO__(0x193A, ## __VA_ARGS__), /* SRV GT4e */ \ + MACRO__(0x193B, ## __VA_ARGS__), /* Halo GT4e */ \ + MACRO__(0x193D, ## __VA_ARGS__) /* WKS GT4e */ + +#define INTEL_SKL_IDS(MACRO__, ...) \ + INTEL_SKL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT4_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_BXT_IDS(MACRO__, ...) \ + MACRO__(0x0A84, ## __VA_ARGS__), \ + MACRO__(0x1A84, ## __VA_ARGS__), \ + MACRO__(0x1A85, ## __VA_ARGS__), \ + MACRO__(0x5A84, ## __VA_ARGS__), /* APL HD Graphics 505 */ \ + MACRO__(0x5A85, ## __VA_ARGS__) /* APL HD Graphics 500 */ + +#define INTEL_GLK_IDS(MACRO__, ...) \ + MACRO__(0x3184, ## __VA_ARGS__), \ + MACRO__(0x3185, ## __VA_ARGS__) + +#define INTEL_KBL_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x5906, ## __VA_ARGS__), /* ULT GT1 */ \ + MACRO__(0x5913, ## __VA_ARGS__) /* ULT GT1.5 */ + +#define INTEL_KBL_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x590E, ## __VA_ARGS__), /* ULX GT1 */ \ + MACRO__(0x5915, ## __VA_ARGS__) /* ULX GT1.5 */ + +#define INTEL_KBL_GT1_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5902, ## __VA_ARGS__), /* DT GT1 */ \ + MACRO__(0x5908, ## __VA_ARGS__), /* Halo GT1 */ \ + MACRO__(0x590A, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x590B, ## __VA_ARGS__) /* Halo GT1 */ + +#define INTEL_KBL_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x5916, ## __VA_ARGS__), /* ULT GT2 */ \ + MACRO__(0x5921, ## __VA_ARGS__) /* ULT GT2F */ + +#define INTEL_KBL_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x591E, ## __VA_ARGS__) /* ULX GT2 */ + +#define INTEL_KBL_GT2_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5912, ## __VA_ARGS__), /* DT GT2 */ \ + MACRO__(0x5917, ## __VA_ARGS__), /* Mobile GT2 */ \ + MACRO__(0x591A, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x591B, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x591D, ## __VA_ARGS__) /* WKS GT2 */ + +#define INTEL_KBL_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x5926, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_KBL_GT3_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5923, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x5927, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_KBL_GT4_IDS(MACRO__, ...) \ + MACRO__(0x593B, ## __VA_ARGS__) /* Halo GT4 */ /* AML/KBL Y GT2 */ -#define INTEL_AML_KBL_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x591C, info), /* ULX GT2 */ \ - INTEL_VGA_DEVICE(0x87C0, info) /* ULX GT2 */ +#define INTEL_AML_KBL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x591C, ## __VA_ARGS__), /* ULX GT2 */ \ + MACRO__(0x87C0, ## __VA_ARGS__) /* ULX GT2 */ /* AML/CFL Y GT2 */ -#define INTEL_AML_CFL_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x87CA, info) +#define INTEL_AML_CFL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x87CA, ## __VA_ARGS__) /* CML GT1 */ -#define INTEL_CML_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x9BA2, info), \ - INTEL_VGA_DEVICE(0x9BA4, info), \ - INTEL_VGA_DEVICE(0x9BA5, info), \ - INTEL_VGA_DEVICE(0x9BA8, info) +#define INTEL_CML_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9BA2, ## __VA_ARGS__), \ + MACRO__(0x9BA4, ## __VA_ARGS__), \ + MACRO__(0x9BA5, ## __VA_ARGS__), \ + MACRO__(0x9BA8, ## __VA_ARGS__) -#define INTEL_CML_U_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x9B21, info), \ - INTEL_VGA_DEVICE(0x9BAA, info), \ - INTEL_VGA_DEVICE(0x9BAC, info) +#define INTEL_CML_U_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9B21, ## __VA_ARGS__), \ + MACRO__(0x9BAA, ## __VA_ARGS__), \ + MACRO__(0x9BAC, ## __VA_ARGS__) /* CML GT2 */ -#define INTEL_CML_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x9BC2, info), \ - INTEL_VGA_DEVICE(0x9BC4, info), \ - INTEL_VGA_DEVICE(0x9BC5, info), \ - INTEL_VGA_DEVICE(0x9BC6, info), \ - INTEL_VGA_DEVICE(0x9BC8, info), \ - INTEL_VGA_DEVICE(0x9BE6, info), \ - INTEL_VGA_DEVICE(0x9BF6, info) - -#define INTEL_CML_U_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x9B41, info), \ - INTEL_VGA_DEVICE(0x9BCA, info), \ - INTEL_VGA_DEVICE(0x9BCC, info) - -#define INTEL_CML_IDS(info) \ - INTEL_CML_GT1_IDS(info), \ - INTEL_CML_GT2_IDS(info), \ - INTEL_CML_U_GT1_IDS(info), \ - INTEL_CML_U_GT2_IDS(info) - -#define INTEL_KBL_IDS(info) \ - INTEL_KBL_GT1_IDS(info), \ - INTEL_KBL_GT2_IDS(info), \ - INTEL_KBL_GT3_IDS(info), \ - INTEL_KBL_GT4_IDS(info), \ - INTEL_AML_KBL_GT2_IDS(info) +#define INTEL_CML_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9BC2, ## __VA_ARGS__), \ + MACRO__(0x9BC4, ## __VA_ARGS__), \ + MACRO__(0x9BC5, ## __VA_ARGS__), \ + MACRO__(0x9BC6, ## __VA_ARGS__), \ + MACRO__(0x9BC8, ## __VA_ARGS__), \ + MACRO__(0x9BE6, ## __VA_ARGS__), \ + MACRO__(0x9BF6, ## __VA_ARGS__) + +#define INTEL_CML_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9B41, ## __VA_ARGS__), \ + MACRO__(0x9BCA, ## __VA_ARGS__), \ + MACRO__(0x9BCC, ## __VA_ARGS__) + +#define INTEL_CML_IDS(MACRO__, ...) \ + INTEL_CML_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_U_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_KBL_IDS(MACRO__, ...) \ + INTEL_KBL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT4_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_AML_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__) /* CFL S */ -#define INTEL_CFL_S_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */ \ - INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */ \ - INTEL_VGA_DEVICE(0x3E99, info) /* SRV GT1 */ - -#define INTEL_CFL_S_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */ \ - INTEL_VGA_DEVICE(0x3E9A, info) /* SRV GT2 */ +#define INTEL_CFL_S_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3E90, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x3E93, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x3E99, ## __VA_ARGS__) /* SRV GT1 */ + +#define INTEL_CFL_S_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3E91, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E92, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E96, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E98, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E9A, ## __VA_ARGS__) /* SRV GT2 */ /* CFL H */ -#define INTEL_CFL_H_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x3E9C, info) +#define INTEL_CFL_H_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3E9C, ## __VA_ARGS__) -#define INTEL_CFL_H_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x3E94, info), /* Halo GT2 */ \ - INTEL_VGA_DEVICE(0x3E9B, info) /* Halo GT2 */ +#define INTEL_CFL_H_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3E94, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x3E9B, ## __VA_ARGS__) /* Halo GT2 */ /* CFL U GT2 */ -#define INTEL_CFL_U_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x3EA9, info) +#define INTEL_CFL_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3EA9, ## __VA_ARGS__) /* CFL U GT3 */ -#define INTEL_CFL_U_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \ - INTEL_VGA_DEVICE(0x3EA8, info) /* ULT GT3 */ - -#define INTEL_CFL_IDS(info) \ - INTEL_CFL_S_GT1_IDS(info), \ - INTEL_CFL_S_GT2_IDS(info), \ - INTEL_CFL_H_GT1_IDS(info), \ - INTEL_CFL_H_GT2_IDS(info), \ - INTEL_CFL_U_GT2_IDS(info), \ - INTEL_CFL_U_GT3_IDS(info), \ - INTEL_AML_CFL_GT2_IDS(info) +#define INTEL_CFL_U_GT3_IDS(MACRO__, ...) \ + MACRO__(0x3EA5, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA6, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA7, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA8, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_CFL_IDS(MACRO__, ...) \ + INTEL_CFL_S_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_S_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_H_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_H_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_U_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_AML_CFL_GT2_IDS(MACRO__, ## __VA_ARGS__) /* WHL/CFL U GT1 */ -#define INTEL_WHL_U_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x3EA1, info), \ - INTEL_VGA_DEVICE(0x3EA4, info) +#define INTEL_WHL_U_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3EA1, ## __VA_ARGS__), \ + MACRO__(0x3EA4, ## __VA_ARGS__) /* WHL/CFL U GT2 */ -#define INTEL_WHL_U_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x3EA0, info), \ - INTEL_VGA_DEVICE(0x3EA3, info) +#define INTEL_WHL_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3EA0, ## __VA_ARGS__), \ + MACRO__(0x3EA3, ## __VA_ARGS__) /* WHL/CFL U GT3 */ -#define INTEL_WHL_U_GT3_IDS(info) \ - INTEL_VGA_DEVICE(0x3EA2, info) +#define INTEL_WHL_U_GT3_IDS(MACRO__, ...) \ + MACRO__(0x3EA2, ## __VA_ARGS__) -#define INTEL_WHL_IDS(info) \ - INTEL_WHL_U_GT1_IDS(info), \ - INTEL_WHL_U_GT2_IDS(info), \ - INTEL_WHL_U_GT3_IDS(info) +#define INTEL_WHL_IDS(MACRO__, ...) \ + INTEL_WHL_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_WHL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_WHL_U_GT3_IDS(MACRO__, ## __VA_ARGS__) /* CNL */ -#define INTEL_CNL_PORT_F_IDS(info) \ - INTEL_VGA_DEVICE(0x5A44, info), \ - INTEL_VGA_DEVICE(0x5A4C, info), \ - INTEL_VGA_DEVICE(0x5A54, info), \ - INTEL_VGA_DEVICE(0x5A5C, info) - -#define INTEL_CNL_IDS(info) \ - INTEL_CNL_PORT_F_IDS(info), \ - INTEL_VGA_DEVICE(0x5A40, info), \ - INTEL_VGA_DEVICE(0x5A41, info), \ - INTEL_VGA_DEVICE(0x5A42, info), \ - INTEL_VGA_DEVICE(0x5A49, info), \ - INTEL_VGA_DEVICE(0x5A4A, info), \ - INTEL_VGA_DEVICE(0x5A50, info), \ - INTEL_VGA_DEVICE(0x5A51, info), \ - INTEL_VGA_DEVICE(0x5A52, info), \ - INTEL_VGA_DEVICE(0x5A59, info), \ - INTEL_VGA_DEVICE(0x5A5A, info) +#define INTEL_CNL_PORT_F_IDS(MACRO__, ...) \ + MACRO__(0x5A44, ## __VA_ARGS__), \ + MACRO__(0x5A4C, ## __VA_ARGS__), \ + MACRO__(0x5A54, ## __VA_ARGS__), \ + MACRO__(0x5A5C, ## __VA_ARGS__) + +#define INTEL_CNL_IDS(MACRO__, ...) \ + INTEL_CNL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5A40, ## __VA_ARGS__), \ + MACRO__(0x5A41, ## __VA_ARGS__), \ + MACRO__(0x5A42, ## __VA_ARGS__), \ + MACRO__(0x5A49, ## __VA_ARGS__), \ + MACRO__(0x5A4A, ## __VA_ARGS__), \ + MACRO__(0x5A50, ## __VA_ARGS__), \ + MACRO__(0x5A51, ## __VA_ARGS__), \ + MACRO__(0x5A52, ## __VA_ARGS__), \ + MACRO__(0x5A59, ## __VA_ARGS__), \ + MACRO__(0x5A5A, ## __VA_ARGS__) /* ICL */ -#define INTEL_ICL_PORT_F_IDS(info) \ - INTEL_VGA_DEVICE(0x8A50, info), \ - INTEL_VGA_DEVICE(0x8A52, info), \ - INTEL_VGA_DEVICE(0x8A53, info), \ - INTEL_VGA_DEVICE(0x8A54, info), \ - INTEL_VGA_DEVICE(0x8A56, info), \ - INTEL_VGA_DEVICE(0x8A57, info), \ - INTEL_VGA_DEVICE(0x8A58, info), \ - INTEL_VGA_DEVICE(0x8A59, info), \ - INTEL_VGA_DEVICE(0x8A5A, info), \ - INTEL_VGA_DEVICE(0x8A5B, info), \ - INTEL_VGA_DEVICE(0x8A5C, info), \ - INTEL_VGA_DEVICE(0x8A70, info), \ - INTEL_VGA_DEVICE(0x8A71, info) - -#define INTEL_ICL_IDS(info) \ - INTEL_ICL_PORT_F_IDS(info), \ - INTEL_VGA_DEVICE(0x8A51, info), \ - INTEL_VGA_DEVICE(0x8A5D, info) +#define INTEL_ICL_PORT_F_IDS(MACRO__, ...) \ + MACRO__(0x8A50, ## __VA_ARGS__), \ + MACRO__(0x8A52, ## __VA_ARGS__), \ + MACRO__(0x8A53, ## __VA_ARGS__), \ + MACRO__(0x8A54, ## __VA_ARGS__), \ + MACRO__(0x8A56, ## __VA_ARGS__), \ + MACRO__(0x8A57, ## __VA_ARGS__), \ + MACRO__(0x8A58, ## __VA_ARGS__), \ + MACRO__(0x8A59, ## __VA_ARGS__), \ + MACRO__(0x8A5A, ## __VA_ARGS__), \ + MACRO__(0x8A5B, ## __VA_ARGS__), \ + MACRO__(0x8A5C, ## __VA_ARGS__), \ + MACRO__(0x8A70, ## __VA_ARGS__), \ + MACRO__(0x8A71, ## __VA_ARGS__) + +#define INTEL_ICL_IDS(MACRO__, ...) \ + INTEL_ICL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x8A51, ## __VA_ARGS__), \ + MACRO__(0x8A5D, ## __VA_ARGS__) /* EHL */ -#define INTEL_EHL_IDS(info) \ - INTEL_VGA_DEVICE(0x4541, info), \ - INTEL_VGA_DEVICE(0x4551, info), \ - INTEL_VGA_DEVICE(0x4555, info), \ - INTEL_VGA_DEVICE(0x4557, info), \ - INTEL_VGA_DEVICE(0x4570, info), \ - INTEL_VGA_DEVICE(0x4571, info) +#define INTEL_EHL_IDS(MACRO__, ...) \ + MACRO__(0x4541, ## __VA_ARGS__), \ + MACRO__(0x4551, ## __VA_ARGS__), \ + MACRO__(0x4555, ## __VA_ARGS__), \ + MACRO__(0x4557, ## __VA_ARGS__), \ + MACRO__(0x4570, ## __VA_ARGS__), \ + MACRO__(0x4571, ## __VA_ARGS__) /* JSL */ -#define INTEL_JSL_IDS(info) \ - INTEL_VGA_DEVICE(0x4E51, info), \ - INTEL_VGA_DEVICE(0x4E55, info), \ - INTEL_VGA_DEVICE(0x4E57, info), \ - INTEL_VGA_DEVICE(0x4E61, info), \ - INTEL_VGA_DEVICE(0x4E71, info) +#define INTEL_JSL_IDS(MACRO__, ...) \ + MACRO__(0x4E51, ## __VA_ARGS__), \ + MACRO__(0x4E55, ## __VA_ARGS__), \ + MACRO__(0x4E57, ## __VA_ARGS__), \ + MACRO__(0x4E61, ## __VA_ARGS__), \ + MACRO__(0x4E71, ## __VA_ARGS__) /* TGL */ -#define INTEL_TGL_GT1_IDS(info) \ - INTEL_VGA_DEVICE(0x9A60, info), \ - INTEL_VGA_DEVICE(0x9A68, info), \ - INTEL_VGA_DEVICE(0x9A70, info) - -#define INTEL_TGL_GT2_IDS(info) \ - INTEL_VGA_DEVICE(0x9A40, info), \ - INTEL_VGA_DEVICE(0x9A49, info), \ - INTEL_VGA_DEVICE(0x9A59, info), \ - INTEL_VGA_DEVICE(0x9A78, info), \ - INTEL_VGA_DEVICE(0x9AC0, info), \ - INTEL_VGA_DEVICE(0x9AC9, info), \ - INTEL_VGA_DEVICE(0x9AD9, info), \ - INTEL_VGA_DEVICE(0x9AF8, info) - -#define INTEL_TGL_IDS(info) \ - INTEL_TGL_GT1_IDS(info), \ - INTEL_TGL_GT2_IDS(info) +#define INTEL_TGL_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9A60, ## __VA_ARGS__), \ + MACRO__(0x9A68, ## __VA_ARGS__), \ + MACRO__(0x9A70, ## __VA_ARGS__) + +#define INTEL_TGL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9A40, ## __VA_ARGS__), \ + MACRO__(0x9A49, ## __VA_ARGS__), \ + MACRO__(0x9A59, ## __VA_ARGS__), \ + MACRO__(0x9A78, ## __VA_ARGS__), \ + MACRO__(0x9AC0, ## __VA_ARGS__), \ + MACRO__(0x9AC9, ## __VA_ARGS__), \ + MACRO__(0x9AD9, ## __VA_ARGS__), \ + MACRO__(0x9AF8, ## __VA_ARGS__) + +#define INTEL_TGL_IDS(MACRO__, ...) \ + INTEL_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__) /* RKL */ -#define INTEL_RKL_IDS(info) \ - INTEL_VGA_DEVICE(0x4C80, info), \ - INTEL_VGA_DEVICE(0x4C8A, info), \ - INTEL_VGA_DEVICE(0x4C8B, info), \ - INTEL_VGA_DEVICE(0x4C8C, info), \ - INTEL_VGA_DEVICE(0x4C90, info), \ - INTEL_VGA_DEVICE(0x4C9A, info) +#define INTEL_RKL_IDS(MACRO__, ...) \ + MACRO__(0x4C80, ## __VA_ARGS__), \ + MACRO__(0x4C8A, ## __VA_ARGS__), \ + MACRO__(0x4C8B, ## __VA_ARGS__), \ + MACRO__(0x4C8C, ## __VA_ARGS__), \ + MACRO__(0x4C90, ## __VA_ARGS__), \ + MACRO__(0x4C9A, ## __VA_ARGS__) /* DG1 */ -#define INTEL_DG1_IDS(info) \ - INTEL_VGA_DEVICE(0x4905, info), \ - INTEL_VGA_DEVICE(0x4906, info), \ - INTEL_VGA_DEVICE(0x4907, info), \ - INTEL_VGA_DEVICE(0x4908, info), \ - INTEL_VGA_DEVICE(0x4909, info) +#define INTEL_DG1_IDS(MACRO__, ...) \ + MACRO__(0x4905, ## __VA_ARGS__), \ + MACRO__(0x4906, ## __VA_ARGS__), \ + MACRO__(0x4907, ## __VA_ARGS__), \ + MACRO__(0x4908, ## __VA_ARGS__), \ + MACRO__(0x4909, ## __VA_ARGS__) /* ADL-S */ -#define INTEL_ADLS_IDS(info) \ - INTEL_VGA_DEVICE(0x4680, info), \ - INTEL_VGA_DEVICE(0x4682, info), \ - INTEL_VGA_DEVICE(0x4688, info), \ - INTEL_VGA_DEVICE(0x468A, info), \ - INTEL_VGA_DEVICE(0x468B, info), \ - INTEL_VGA_DEVICE(0x4690, info), \ - INTEL_VGA_DEVICE(0x4692, info), \ - INTEL_VGA_DEVICE(0x4693, info) +#define INTEL_ADLS_IDS(MACRO__, ...) \ + MACRO__(0x4680, ## __VA_ARGS__), \ + MACRO__(0x4682, ## __VA_ARGS__), \ + MACRO__(0x4688, ## __VA_ARGS__), \ + MACRO__(0x468A, ## __VA_ARGS__), \ + MACRO__(0x468B, ## __VA_ARGS__), \ + MACRO__(0x4690, ## __VA_ARGS__), \ + MACRO__(0x4692, ## __VA_ARGS__), \ + MACRO__(0x4693, ## __VA_ARGS__) /* ADL-P */ -#define INTEL_ADLP_IDS(info) \ - INTEL_VGA_DEVICE(0x46A0, info), \ - INTEL_VGA_DEVICE(0x46A1, info), \ - INTEL_VGA_DEVICE(0x46A2, info), \ - INTEL_VGA_DEVICE(0x46A3, info), \ - INTEL_VGA_DEVICE(0x46A6, info), \ - INTEL_VGA_DEVICE(0x46A8, info), \ - INTEL_VGA_DEVICE(0x46AA, info), \ - INTEL_VGA_DEVICE(0x462A, info), \ - INTEL_VGA_DEVICE(0x4626, info), \ - INTEL_VGA_DEVICE(0x4628, info), \ - INTEL_VGA_DEVICE(0x46B0, info), \ - INTEL_VGA_DEVICE(0x46B1, info), \ - INTEL_VGA_DEVICE(0x46B2, info), \ - INTEL_VGA_DEVICE(0x46B3, info), \ - INTEL_VGA_DEVICE(0x46C0, info), \ - INTEL_VGA_DEVICE(0x46C1, info), \ - INTEL_VGA_DEVICE(0x46C2, info), \ - INTEL_VGA_DEVICE(0x46C3, info) +#define INTEL_ADLP_IDS(MACRO__, ...) \ + MACRO__(0x46A0, ## __VA_ARGS__), \ + MACRO__(0x46A1, ## __VA_ARGS__), \ + MACRO__(0x46A2, ## __VA_ARGS__), \ + MACRO__(0x46A3, ## __VA_ARGS__), \ + MACRO__(0x46A6, ## __VA_ARGS__), \ + MACRO__(0x46A8, ## __VA_ARGS__), \ + MACRO__(0x46AA, ## __VA_ARGS__), \ + MACRO__(0x462A, ## __VA_ARGS__), \ + MACRO__(0x4626, ## __VA_ARGS__), \ + MACRO__(0x4628, ## __VA_ARGS__), \ + MACRO__(0x46B0, ## __VA_ARGS__), \ + MACRO__(0x46B1, ## __VA_ARGS__), \ + MACRO__(0x46B2, ## __VA_ARGS__), \ + MACRO__(0x46B3, ## __VA_ARGS__), \ + MACRO__(0x46C0, ## __VA_ARGS__), \ + MACRO__(0x46C1, ## __VA_ARGS__), \ + MACRO__(0x46C2, ## __VA_ARGS__), \ + MACRO__(0x46C3, ## __VA_ARGS__) /* ADL-N */ -#define INTEL_ADLN_IDS(info) \ - INTEL_VGA_DEVICE(0x46D0, info), \ - INTEL_VGA_DEVICE(0x46D1, info), \ - INTEL_VGA_DEVICE(0x46D2, info), \ - INTEL_VGA_DEVICE(0x46D3, info), \ - INTEL_VGA_DEVICE(0x46D4, info) +#define INTEL_ADLN_IDS(MACRO__, ...) \ + MACRO__(0x46D0, ## __VA_ARGS__), \ + MACRO__(0x46D1, ## __VA_ARGS__), \ + MACRO__(0x46D2, ## __VA_ARGS__), \ + MACRO__(0x46D3, ## __VA_ARGS__), \ + MACRO__(0x46D4, ## __VA_ARGS__) /* RPL-S */ -#define INTEL_RPLS_IDS(info) \ - INTEL_VGA_DEVICE(0xA780, info), \ - INTEL_VGA_DEVICE(0xA781, info), \ - INTEL_VGA_DEVICE(0xA782, info), \ - INTEL_VGA_DEVICE(0xA783, info), \ - INTEL_VGA_DEVICE(0xA788, info), \ - INTEL_VGA_DEVICE(0xA789, info), \ - INTEL_VGA_DEVICE(0xA78A, info), \ - INTEL_VGA_DEVICE(0xA78B, info) +#define INTEL_RPLS_IDS(MACRO__, ...) \ + MACRO__(0xA780, ## __VA_ARGS__), \ + MACRO__(0xA781, ## __VA_ARGS__), \ + MACRO__(0xA782, ## __VA_ARGS__), \ + MACRO__(0xA783, ## __VA_ARGS__), \ + MACRO__(0xA788, ## __VA_ARGS__), \ + MACRO__(0xA789, ## __VA_ARGS__), \ + MACRO__(0xA78A, ## __VA_ARGS__), \ + MACRO__(0xA78B, ## __VA_ARGS__) /* RPL-U */ -#define INTEL_RPLU_IDS(info) \ - INTEL_VGA_DEVICE(0xA721, info), \ - INTEL_VGA_DEVICE(0xA7A1, info), \ - INTEL_VGA_DEVICE(0xA7A9, info), \ - INTEL_VGA_DEVICE(0xA7AC, info), \ - INTEL_VGA_DEVICE(0xA7AD, info) +#define INTEL_RPLU_IDS(MACRO__, ...) \ + MACRO__(0xA721, ## __VA_ARGS__), \ + MACRO__(0xA7A1, ## __VA_ARGS__), \ + MACRO__(0xA7A9, ## __VA_ARGS__), \ + MACRO__(0xA7AC, ## __VA_ARGS__), \ + MACRO__(0xA7AD, ## __VA_ARGS__) /* RPL-P */ -#define INTEL_RPLP_IDS(info) \ - INTEL_VGA_DEVICE(0xA720, info), \ - INTEL_VGA_DEVICE(0xA7A0, info), \ - INTEL_VGA_DEVICE(0xA7A8, info), \ - INTEL_VGA_DEVICE(0xA7AA, info), \ - INTEL_VGA_DEVICE(0xA7AB, info) +#define INTEL_RPLP_IDS(MACRO__, ...) \ + MACRO__(0xA720, ## __VA_ARGS__), \ + MACRO__(0xA7A0, ## __VA_ARGS__), \ + MACRO__(0xA7A8, ## __VA_ARGS__), \ + MACRO__(0xA7AA, ## __VA_ARGS__), \ + MACRO__(0xA7AB, ## __VA_ARGS__) /* DG2 */ -#define INTEL_DG2_G10_IDS(info) \ - INTEL_VGA_DEVICE(0x5690, info), \ - INTEL_VGA_DEVICE(0x5691, info), \ - INTEL_VGA_DEVICE(0x5692, info), \ - INTEL_VGA_DEVICE(0x56A0, info), \ - INTEL_VGA_DEVICE(0x56A1, info), \ - INTEL_VGA_DEVICE(0x56A2, info), \ - INTEL_VGA_DEVICE(0x56BE, info), \ - INTEL_VGA_DEVICE(0x56BF, info) - -#define INTEL_DG2_G11_IDS(info) \ - INTEL_VGA_DEVICE(0x5693, info), \ - INTEL_VGA_DEVICE(0x5694, info), \ - INTEL_VGA_DEVICE(0x5695, info), \ - INTEL_VGA_DEVICE(0x56A5, info), \ - INTEL_VGA_DEVICE(0x56A6, info), \ - INTEL_VGA_DEVICE(0x56B0, info), \ - INTEL_VGA_DEVICE(0x56B1, info), \ - INTEL_VGA_DEVICE(0x56BA, info), \ - INTEL_VGA_DEVICE(0x56BB, info), \ - INTEL_VGA_DEVICE(0x56BC, info), \ - INTEL_VGA_DEVICE(0x56BD, info) - -#define INTEL_DG2_G12_IDS(info) \ - INTEL_VGA_DEVICE(0x5696, info), \ - INTEL_VGA_DEVICE(0x5697, info), \ - INTEL_VGA_DEVICE(0x56A3, info), \ - INTEL_VGA_DEVICE(0x56A4, info), \ - INTEL_VGA_DEVICE(0x56B2, info), \ - INTEL_VGA_DEVICE(0x56B3, info) - -#define INTEL_DG2_IDS(info) \ - INTEL_DG2_G10_IDS(info), \ - INTEL_DG2_G11_IDS(info), \ - INTEL_DG2_G12_IDS(info) - -#define INTEL_ATS_M150_IDS(info) \ - INTEL_VGA_DEVICE(0x56C0, info), \ - INTEL_VGA_DEVICE(0x56C2, info) - -#define INTEL_ATS_M75_IDS(info) \ - INTEL_VGA_DEVICE(0x56C1, info) - -#define INTEL_ATS_M_IDS(info) \ - INTEL_ATS_M150_IDS(info), \ - INTEL_ATS_M75_IDS(info) +#define INTEL_DG2_G10_IDS(MACRO__, ...) \ + MACRO__(0x5690, ## __VA_ARGS__), \ + MACRO__(0x5691, ## __VA_ARGS__), \ + MACRO__(0x5692, ## __VA_ARGS__), \ + MACRO__(0x56A0, ## __VA_ARGS__), \ + MACRO__(0x56A1, ## __VA_ARGS__), \ + MACRO__(0x56A2, ## __VA_ARGS__), \ + MACRO__(0x56BE, ## __VA_ARGS__), \ + MACRO__(0x56BF, ## __VA_ARGS__) + +#define INTEL_DG2_G11_IDS(MACRO__, ...) \ + MACRO__(0x5693, ## __VA_ARGS__), \ + MACRO__(0x5694, ## __VA_ARGS__), \ + MACRO__(0x5695, ## __VA_ARGS__), \ + MACRO__(0x56A5, ## __VA_ARGS__), \ + MACRO__(0x56A6, ## __VA_ARGS__), \ + MACRO__(0x56B0, ## __VA_ARGS__), \ + MACRO__(0x56B1, ## __VA_ARGS__), \ + MACRO__(0x56BA, ## __VA_ARGS__), \ + MACRO__(0x56BB, ## __VA_ARGS__), \ + MACRO__(0x56BC, ## __VA_ARGS__), \ + MACRO__(0x56BD, ## __VA_ARGS__) + +#define INTEL_DG2_G12_IDS(MACRO__, ...) \ + MACRO__(0x5696, ## __VA_ARGS__), \ + MACRO__(0x5697, ## __VA_ARGS__), \ + MACRO__(0x56A3, ## __VA_ARGS__), \ + MACRO__(0x56A4, ## __VA_ARGS__), \ + MACRO__(0x56B2, ## __VA_ARGS__), \ + MACRO__(0x56B3, ## __VA_ARGS__) + +#define INTEL_DG2_IDS(MACRO__, ...) \ + INTEL_DG2_G10_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_DG2_G11_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_DG2_G12_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_ATS_M150_IDS(MACRO__, ...) \ + MACRO__(0x56C0, ## __VA_ARGS__), \ + MACRO__(0x56C2, ## __VA_ARGS__) + +#define INTEL_ATS_M75_IDS(MACRO__, ...) \ + MACRO__(0x56C1, ## __VA_ARGS__) + +#define INTEL_ATS_M_IDS(MACRO__, ...) \ + INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) /* MTL */ -#define INTEL_MTL_IDS(info) \ - INTEL_VGA_DEVICE(0x7D40, info), \ - INTEL_VGA_DEVICE(0x7D41, info), \ - INTEL_VGA_DEVICE(0x7D45, info), \ - INTEL_VGA_DEVICE(0x7D51, info), \ - INTEL_VGA_DEVICE(0x7D55, info), \ - INTEL_VGA_DEVICE(0x7D60, info), \ - INTEL_VGA_DEVICE(0x7D67, info), \ - INTEL_VGA_DEVICE(0x7DD1, info), \ - INTEL_VGA_DEVICE(0x7DD5, info) +#define INTEL_MTL_IDS(MACRO__, ...) \ + MACRO__(0x7D40, ## __VA_ARGS__), \ + MACRO__(0x7D41, ## __VA_ARGS__), \ + MACRO__(0x7D45, ## __VA_ARGS__), \ + MACRO__(0x7D51, ## __VA_ARGS__), \ + MACRO__(0x7D55, ## __VA_ARGS__), \ + MACRO__(0x7D60, ## __VA_ARGS__), \ + MACRO__(0x7D67, ## __VA_ARGS__), \ + MACRO__(0x7DD1, ## __VA_ARGS__), \ + MACRO__(0x7DD5, ## __VA_ARGS__) #endif /* _I915_PCIIDS_H */ -- cgit v1.2.3 From 3d9d313d518c5bc9e5ab6aeab86c9fa4bece095c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 10 May 2024 18:08:13 +0300 Subject: drm/connector: update edid_blob_ptr documentation Accessing the EDID via edid_blob_ptr causes chicken-and-egg problems. Keep edid_blob_ptr as the userspace interface that should be accessed via dedicated functions. Reviewed-by: Chaitanya Kumar Borah Acked-by: Alex Deucher Link: https://patchwork.freedesktop.org/patch/msgid/b6aa1ea30ae85ef9e9814315d3437e82f0ba6754.1715353572.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/drm_connector.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index fe88d7fc6b8f..58ee9adf9091 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1636,8 +1636,12 @@ struct drm_connector { /** * @edid_blob_ptr: DRM property containing EDID if present. Protected by - * &drm_mode_config.mutex. This should be updated only by calling + * &drm_mode_config.mutex. + * + * This must be updated only by calling drm_edid_connector_update() or * drm_connector_update_edid_property(). + * + * This must not be used by drivers directly. */ struct drm_property_blob *edid_blob_ptr; -- cgit v1.2.3 From 983095eaf6c161ef73d96152bfc1a99ca051cd57 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 25 May 2024 18:00:31 +0200 Subject: dma-buf/fence-array: Add flex array to struct dma_fence_array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an effort to get rid of all multiplications from allocation functions in order to prevent integer overflows [1][2]. The "struct dma_fence_array" can be refactored to add a flex array in order to have the "callback structures allocated behind the array" be more explicit. Do so: - makes the code more readable and safer. - allows using __counted_by() for additional checks - avoids some pointer arithmetic in dma_fence_array_enable_signaling() Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1] Link: https://github.com/KSPP/linux/issues/160 [2] Signed-off-by: Christophe JAILLET Reviewed-by: Kees Cook Reviewed-by: Christian König Link: https://patchwork.freedesktop.org/patch/msgid/8b4e556e07b5dd78bb8a39b67ea0a43b199083c8.1716652811.git.christophe.jaillet@wanadoo.fr Signed-off-by: Christian König --- drivers/dma-buf/dma-fence-array.c | 10 ++++------ include/linux/dma-fence-array.h | 3 +++ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c index 9b3ce8948351..c74ac197d5fe 100644 --- a/drivers/dma-buf/dma-fence-array.c +++ b/drivers/dma-buf/dma-fence-array.c @@ -70,7 +70,7 @@ static void dma_fence_array_cb_func(struct dma_fence *f, static bool dma_fence_array_enable_signaling(struct dma_fence *fence) { struct dma_fence_array *array = to_dma_fence_array(fence); - struct dma_fence_array_cb *cb = (void *)(&array[1]); + struct dma_fence_array_cb *cb = array->callbacks; unsigned i; for (i = 0; i < array->num_fences; ++i) { @@ -168,22 +168,20 @@ struct dma_fence_array *dma_fence_array_create(int num_fences, bool signal_on_any) { struct dma_fence_array *array; - size_t size = sizeof(*array); WARN_ON(!num_fences || !fences); - /* Allocate the callback structures behind the array. */ - size += num_fences * sizeof(struct dma_fence_array_cb); - array = kzalloc(size, GFP_KERNEL); + array = kzalloc(struct_size(array, callbacks, num_fences), GFP_KERNEL); if (!array) return NULL; + array->num_fences = num_fences; + spin_lock_init(&array->lock); dma_fence_init(&array->base, &dma_fence_array_ops, &array->lock, context, seqno); init_irq_work(&array->work, irq_dma_fence_array_work); - array->num_fences = num_fences; atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences); array->fences = fences; diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h index ec7f25def392..29c5650c1038 100644 --- a/include/linux/dma-fence-array.h +++ b/include/linux/dma-fence-array.h @@ -33,6 +33,7 @@ struct dma_fence_array_cb { * @num_pending: fences in the array still pending * @fences: array of the fences * @work: internal irq_work function + * @callbacks: array of callback helpers */ struct dma_fence_array { struct dma_fence base; @@ -43,6 +44,8 @@ struct dma_fence_array { struct dma_fence **fences; struct irq_work work; + + struct dma_fence_array_cb callbacks[] __counted_by(num_fences); }; /** -- cgit v1.2.3 From 582d79f34330db4ccee85620cf95ee7ccb9a0d01 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:57:50 +0200 Subject: drm/connector: Introduce an HDMI connector initialization function A lot of the various HDMI drivers duplicate some logic that depends on the HDMI spec itself and not really a particular hardware implementation. Output BPC or format selection, infoframe generation are good examples of such areas. This creates a lot of boilerplate, with a lot of variations, which makes it hard for userspace to rely on, and makes it difficult to get it right for drivers. In the next patches, we'll add a lot of infrastructure around the drm_connector and drm_connector_state structures, which will allow to abstract away the duplicated logic. This infrastructure comes with a few requirements though, and thus we need a new initialization function. Hopefully, this will make drivers simpler to handle, and their behaviour more consistent. Reviewed-by: Dave Stevenson Reviewed-by: Sui Jingfeng Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-1-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_connector.c | 39 +++++++++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 5 +++++ 2 files changed, 44 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4d2df7f64dc5..8c471bdfbfff 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -452,6 +452,45 @@ int drmm_connector_init(struct drm_device *dev, } EXPORT_SYMBOL(drmm_connector_init); +/** + * drmm_connector_hdmi_init - Init a preallocated HDMI connector + * @dev: DRM device + * @connector: A pointer to the HDMI connector to init + * @funcs: callbacks for this connector + * @connector_type: user visible type of the connector + * @ddc: optional pointer to the associated ddc adapter + * + * Initialises a preallocated HDMI connector. Connectors can be + * subclassed as part of driver connector objects. + * + * Cleanup is automatically handled with a call to + * drm_connector_cleanup() in a DRM-managed action. + * + * The connector structure should be allocated with drmm_kzalloc(). + * + * Returns: + * Zero on success, error code on failure. + */ +int drmm_connector_hdmi_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc) +{ + int ret; + + if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector_type == DRM_MODE_CONNECTOR_HDMIB)) + return -EINVAL; + + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL(drmm_connector_hdmi_init); + /** * drm_connector_attach_edid_property - attach edid property. * @connector: the connector diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 58ee9adf9091..7ef1ff83d885 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1908,6 +1908,11 @@ int drmm_connector_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc); +int drmm_connector_hdmi_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type, + struct i2c_adapter *ddc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); -- cgit v1.2.3 From 54cb39e2293b1e221708d3ac157ecc59086e1b46 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:57:52 +0200 Subject: drm/connector: hdmi: Create an HDMI sub-state The next features we will need to share across drivers will need to store some parameters for drivers to use, such as the selected output format. Let's create a new connector sub-state dedicated to HDMI controllers, that will eventually store everything we need. Reviewed-by: Dave Stevenson Reviewed-by: Sui Jingfeng Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-3-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/Kconfig | 7 +++++ drivers/gpu/drm/display/Makefile | 2 ++ drivers/gpu/drm/display/drm_hdmi_state_helper.c | 41 +++++++++++++++++++++++++ include/drm/display/drm_hdmi_state_helper.h | 16 ++++++++++ include/drm/drm_connector.h | 7 +++++ 5 files changed, 73 insertions(+) create mode 100644 drivers/gpu/drm/display/drm_hdmi_state_helper.c create mode 100644 include/drm/display/drm_hdmi_state_helper.h (limited to 'include') diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig index 864a6488bfdf..14114b597ef4 100644 --- a/drivers/gpu/drm/display/Kconfig +++ b/drivers/gpu/drm/display/Kconfig @@ -70,3 +70,10 @@ config DRM_DISPLAY_HDMI_HELPER depends on DRM_DISPLAY_HELPER help DRM display helpers for HDMI. + +config DRM_DISPLAY_HDMI_STATE_HELPER + bool + depends on DRM_DISPLAY_HELPER + depends on DRM_DISPLAY_HDMI_HELPER + help + DRM KMS state helpers for HDMI. diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile index 17d2cc73ff56..629df2f4d322 100644 --- a/drivers/gpu/drm/display/Makefile +++ b/drivers/gpu/drm/display/Makefile @@ -14,6 +14,8 @@ drm_display_helper-$(CONFIG_DRM_DISPLAY_HDCP_HELPER) += drm_hdcp_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_HELPER) += \ drm_hdmi_helper.o \ drm_scdc_helper.o +drm_display_helper-$(CONFIG_DRM_DISPLAY_HDMI_STATE_HELPER) += \ + drm_hdmi_state_helper.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV) += drm_dp_aux_dev.o drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_AUX_CEC) += drm_dp_cec.o diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c new file mode 100644 index 000000000000..1e92c1108d23 --- /dev/null +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include + +/** + * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources + * @connector: DRM connector + * @new_conn_state: connector state to reset + * + * Initializes all HDMI resources from a @drm_connector_state without + * actually allocating it. This is useful for HDMI drivers, in + * combination with __drm_atomic_helper_connector_reset() or + * drm_atomic_helper_connector_reset(). + */ +void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, + struct drm_connector_state *new_conn_state) +{ +} +EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); + +/** + * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state + * @connector: DRM Connector + * @state: the DRM State object + * + * Provides a default connector state check handler for HDMI connectors. + * Checks that a desired connector update is valid, and updates various + * fields of derived state. + * + * RETURNS: + * Zero on success, or an errno code otherwise. + */ +int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h new file mode 100644 index 000000000000..837899db315a --- /dev/null +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef DRM_HDMI_STATE_HELPER_H_ +#define DRM_HDMI_STATE_HELPER_H_ + +struct drm_atomic_state; +struct drm_connector; +struct drm_connector_state; + +void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, + struct drm_connector_state *new_conn_state); + +int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, + struct drm_atomic_state *state); + +#endif // DRM_HDMI_STATE_HELPER_H_ diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 7ef1ff83d885..5fe3f6a519cd 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1031,6 +1031,13 @@ struct drm_connector_state { * DRM blob property for HDR output metadata */ struct drm_property_blob *hdr_output_metadata; + + /** + * @hdmi: HDMI-related variable and properties. Filled by + * @drm_atomic_helper_connector_hdmi_check(). + */ + struct { + } hdmi; }; /** -- cgit v1.2.3 From aadb3e16b8f30cc1c1efdfe162f400e026385bfb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:57:53 +0200 Subject: drm/connector: hdmi: Add output BPC to the connector state We'll add automatic selection of the output BPC in a following patch, but let's add it to the HDMI connector state already. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-4-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 20 ++++++++++++++++++++ drivers/gpu/drm/drm_atomic.c | 5 +++++ drivers/gpu/drm/drm_connector.c | 20 +++++++++++++++++++- drivers/gpu/drm/tests/drm_connector_test.c | 12 ++++++++---- include/drm/drm_connector.h | 12 +++++++++++- 5 files changed, 63 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 1e92c1108d23..82293d93b5f8 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -18,6 +18,10 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, struct drm_connector_state *new_conn_state) { + unsigned int max_bpc = connector->max_bpc; + + new_conn_state->max_bpc = max_bpc; + new_conn_state->max_requested_bpc = max_bpc; } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); @@ -36,6 +40,22 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_atomic_state *state) { + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_conn_state = + drm_atomic_get_new_connector_state(state, connector); + + if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc) { + struct drm_crtc *crtc = new_conn_state->crtc; + struct drm_crtc_state *crtc_state; + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + + crtc_state->mode_changed = true; + } + return 0; } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a91737adf8e7..4e11cfb4518b 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1143,6 +1143,11 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); drm_printf(p, "\tcolorspace=%s\n", drm_get_colorspace_name(state->colorspace)); + if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { + drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); + } + if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 8c471bdfbfff..e5c840987854 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @funcs: callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter + * @max_bpc: Maximum bits per char the HDMI connector supports * * Initialises a preallocated HDMI connector. Connectors can be * subclassed as part of driver connector objects. @@ -475,7 +476,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, - struct i2c_adapter *ddc) + struct i2c_adapter *ddc, + unsigned int max_bpc) { int ret; @@ -483,10 +485,26 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; + if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) + return -EINVAL; + ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc); if (ret) return ret; + /* + * drm_connector_attach_max_bpc_property() requires the + * connector to have a state. + */ + if (connector->funcs->reset) + connector->funcs->reset(connector); + + drm_connector_attach_max_bpc_property(connector, 8, max_bpc); + connector->max_bpc = max_bpc; + + if (max_bpc > 8) + drm_connector_attach_hdr_output_metadata_property(connector); + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 261d4109946d..2661eb64a5cd 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -184,7 +184,8 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -200,7 +201,8 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, - NULL); + NULL, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -217,7 +219,8 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, connector_type, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -248,7 +251,8 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, connector_type, - &priv->ddc); + &priv->ddc, + 8); KUNIT_EXPECT_LT(test, ret, 0); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5fe3f6a519cd..4ddb438ea2dd 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1037,6 +1037,10 @@ struct drm_connector_state { * @drm_atomic_helper_connector_hdmi_check(). */ struct { + /** + * @output_bpc: Bits per color channel to output. + */ + unsigned int output_bpc; } hdmi; }; @@ -1686,6 +1690,11 @@ struct drm_connector { */ struct drm_property_blob *path_blob_ptr; + /** + * @max_bpc: Maximum bits per color channel the connector supports. + */ + unsigned int max_bpc; + /** * @max_bpc_property: Default connector property for the max bpc to be * driven out of the connector. @@ -1919,7 +1928,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, int connector_type, - struct i2c_adapter *ddc); + struct i2c_adapter *ddc, + unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); -- cgit v1.2.3 From 948f01d5e5595023c2e7cfc0184a322be00ef214 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:57:56 +0200 Subject: drm/connector: hdmi: Add support for output format Just like BPC, we'll add support for automatic selection of the output format for HDMI connectors. Let's add the needed defaults and fields for now. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-7-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 3 ++- drivers/gpu/drm/drm_atomic.c | 2 ++ drivers/gpu/drm/drm_connector.c | 31 ++++++++++++++++++++++ drivers/gpu/drm/tests/drm_connector_test.c | 9 +++++++ drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 22 +++++++++++---- include/drm/drm_connector.h | 20 ++++++++++++++ 6 files changed, 81 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 82293d93b5f8..f6cd0612ea2c 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -45,7 +45,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_connector_state *new_conn_state = drm_atomic_get_new_connector_state(state, connector); - if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc) { + if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || + old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) { struct drm_crtc *crtc = new_conn_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 4e11cfb4518b..8730137baa86 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1146,6 +1146,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); + drm_printf(p, "\toutput_format=%s\n", + drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); } if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index e5c840987854..f554bf703e13 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -459,6 +459,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @funcs: callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter + * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats * @max_bpc: Maximum bits per char the HDMI connector supports * * Initialises a preallocated HDMI connector. Connectors can be @@ -477,6 +478,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc, + unsigned long supported_formats, unsigned int max_bpc) { int ret; @@ -485,6 +487,9 @@ int drmm_connector_hdmi_init(struct drm_device *dev, connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; + if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB))) + return -EINVAL; + if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12)) return -EINVAL; @@ -492,6 +497,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (ret) return ret; + connector->hdmi.supported_formats = supported_formats; + /* * drm_connector_attach_max_bpc_property() requires the * connector to have a state. @@ -1201,6 +1208,30 @@ static const u32 dp_colorspaces = BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); +static const char * const output_format_str[] = { + [HDMI_COLORSPACE_RGB] = "RGB", + [HDMI_COLORSPACE_YUV420] = "YUV 4:2:0", + [HDMI_COLORSPACE_YUV422] = "YUV 4:2:2", + [HDMI_COLORSPACE_YUV444] = "YUV 4:4:4", +}; + +/* + * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format + * @fmt: Output format to compute name of + * + * Returns: the name of the output format, or NULL if the type is not + * valid. + */ +const char * +drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt) +{ + if (fmt >= ARRAY_SIZE(output_format_str)) + return NULL; + + return output_format_str[fmt]; +} +EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name); + /** * DOC: standard connector properties * diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 9465fa33f3b6..37e6efd46d7e 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -187,6 +187,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -204,6 +205,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -221,6 +223,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 9); KUNIT_EXPECT_LT(test, ret, 0); } @@ -238,6 +241,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 0); KUNIT_EXPECT_LT(test, ret, 0); } @@ -260,6 +264,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); @@ -298,6 +303,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 10); KUNIT_EXPECT_EQ(test, ret, 0); @@ -336,6 +342,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) &dummy_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 12); KUNIT_EXPECT_EQ(test, ret, 0); @@ -370,6 +377,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) &dummy_funcs, connector_type, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_EQ(test, ret, 0); } @@ -402,6 +410,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) &dummy_funcs, connector_type, &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), 8); KUNIT_EXPECT_LT(test, ret, 0); } diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index a82f2a52ae0f..69ffaa4507c1 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -149,6 +149,7 @@ static const struct drm_connector_funcs dummy_connector_funcs = { static struct drm_atomic_helper_connector_hdmi_priv * drm_atomic_helper_connector_hdmi_init(struct kunit *test, + unsigned int formats, unsigned int max_bpc) { struct drm_atomic_helper_connector_hdmi_priv *priv; @@ -192,6 +193,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, &dummy_connector_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, + formats, max_bpc); KUNIT_ASSERT_EQ(test, ret, 0); @@ -227,7 +229,9 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -294,7 +298,9 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); ctx = drm_kunit_helper_acquire_ctx_alloc(test); @@ -363,7 +369,9 @@ static void drm_test_check_bpc_8_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 8); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -385,7 +393,9 @@ static void drm_test_check_bpc_10_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 10); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -407,7 +417,9 @@ static void drm_test_check_bpc_12_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, 12); + priv = drm_atomic_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 4ddb438ea2dd..4b6b1117c7d0 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -368,6 +368,9 @@ enum drm_panel_orientation { DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +const char * +drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt); + /** * struct drm_monitor_range_info - Panel's Monitor range in EDID for * &drm_display_info @@ -1041,6 +1044,11 @@ struct drm_connector_state { * @output_bpc: Bits per color channel to output. */ unsigned int output_bpc; + + /** + * @output_format: Pixel format to output in. + */ + enum hdmi_colorspace output_format; } hdmi; }; @@ -1906,6 +1914,17 @@ struct drm_connector { /** @hdr_sink_metadata: HDR Metadata Information read from sink */ struct hdr_sink_metadata hdr_sink_metadata; + + /** + * @hdmi: HDMI-related variable and properties. + */ + struct { + /** + * @supported_formats: Bitmask of @hdmi_colorspace + * supported by the controller. + */ + unsigned long supported_formats; + } hdmi; }; #define obj_to_connector(x) container_of(x, struct drm_connector, base) @@ -1929,6 +1948,7 @@ int drmm_connector_hdmi_init(struct drm_device *dev, const struct drm_connector_funcs *funcs, int connector_type, struct i2c_adapter *ddc, + unsigned long supported_formats, unsigned int max_bpc); void drm_connector_attach_edid_property(struct drm_connector *connector); int drm_connector_register(struct drm_connector *connector); -- cgit v1.2.3 From 40167bcbd19c241fc30a912fa8a8276b9ed1a12e Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:57:58 +0200 Subject: drm/display: hdmi: Add HDMI compute clock helper A lot of HDMI drivers have some variation of the formula to calculate the TMDS character rate from a mode, but few of them actually take all parameters into account. Let's create a helper to provide that rate taking all parameters into account. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-9-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_helper.c | 61 +++++++++++++++++++++++++++++++ include/drm/display/drm_hdmi_helper.h | 4 ++ 2 files changed, 65 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_helper.c b/drivers/gpu/drm/display/drm_hdmi_helper.c index faf5e9efa7d3..74dd4d01dd9b 100644 --- a/drivers/gpu/drm/display/drm_hdmi_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_helper.c @@ -195,3 +195,64 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame, frame->itc = conn_state->content_type != DRM_MODE_CONTENT_TYPE_NO_DATA; } EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type); + +/** + * drm_hdmi_compute_mode_clock() - Computes the TMDS Character Rate + * @mode: Display mode to compute the clock for + * @bpc: Bits per character + * @fmt: Output Pixel Format used + * + * Returns the TMDS Character Rate for a given mode, bpc count and output format. + * + * RETURNS: + * The TMDS Character Rate, in Hertz, or 0 on error. + */ +unsigned long long +drm_hdmi_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc, enum hdmi_colorspace fmt) +{ + unsigned long long clock = mode->clock * 1000ULL; + unsigned int vic = drm_match_cea_mode(mode); + + /* + * CTA-861-G Spec, section 5.4 - Color Coding and Quantization + * mandates that VIC 1 always uses 8 bpc. + */ + if (vic == 1 && bpc != 8) + return 0; + + if (fmt == HDMI_COLORSPACE_YUV422) { + /* + * HDMI 1.0 Spec, section 6.5 - Pixel Encoding states that + * YUV422 sends 24 bits over three channels, with Cb and Cr + * components being sent on odd and even pixels, respectively. + * + * If fewer than 12 bpc are sent, data are left justified. + */ + if (bpc > 12) + return 0; + + /* + * HDMI 1.0 Spec, section 6.5 - Pixel Encoding + * specifies that YUV422 sends two 12-bits components over + * three TMDS channels per pixel clock, which is equivalent to + * three 8-bits components over three channels used by RGB as + * far as the clock rate goes. + */ + bpc = 8; + } + + /* + * HDMI 2.0 Spec, Section 7.1 - YCbCr 4:2:0 Pixel Encoding + * specifies that YUV420 encoding is carried at a TMDS Character Rate + * equal to half the pixel clock rate. + */ + if (fmt == HDMI_COLORSPACE_YUV420) + clock = clock / 2; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + clock = clock * 2; + + return DIV_ROUND_CLOSEST_ULL(clock * bpc, 8); +} +EXPORT_SYMBOL(drm_hdmi_compute_mode_clock); diff --git a/include/drm/display/drm_hdmi_helper.h b/include/drm/display/drm_hdmi_helper.h index 76d234826e22..57e3b18c15ec 100644 --- a/include/drm/display/drm_hdmi_helper.h +++ b/include/drm/display/drm_hdmi_helper.h @@ -24,4 +24,8 @@ drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame, void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame, const struct drm_connector_state *conn_state); +unsigned long long +drm_hdmi_compute_mode_clock(const struct drm_display_mode *mode, + unsigned int bpc, enum hdmi_colorspace fmt); + #endif -- cgit v1.2.3 From f035f4097f1e0a35a457b72427bb0c06ca0c81c4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:58:00 +0200 Subject: drm/connector: hdmi: Calculate TMDS character rate Most HDMI drivers have some code to calculate the TMDS character rate, usually to adjust an internal clock to match what the mode requires. Since the TMDS character rates mostly depends on the resolution, whether we need to repeat pixels or not, the bpc count and the format, we can now derive it from the HDMI connector state that stores all those infos and remove the duplication from drivers. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-11-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 67 ++++++++++++++++++++++ drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 3 + include/drm/drm_connector.h | 5 ++ 4 files changed, 76 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index f6cd0612ea2c..08630561d864 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -3,6 +3,7 @@ #include #include +#include #include /** @@ -25,6 +26,63 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); +static const struct drm_display_mode * +connector_state_get_mode(const struct drm_connector_state *conn_state) +{ + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + + state = conn_state->state; + if (!state) + return NULL; + + crtc = conn_state->crtc; + if (!crtc) + return NULL; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + return NULL; + + return &crtc_state->mode; +} + +static enum drm_mode_status +hdmi_clock_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long clock) +{ + const struct drm_display_info *info = &connector->display_info; + + if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static int +hdmi_compute_clock(const struct drm_connector *connector, + struct drm_connector_state *conn_state, + const struct drm_display_mode *mode, + unsigned int bpc, enum hdmi_colorspace fmt) +{ + enum drm_mode_status status; + unsigned long long clock; + + clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt); + if (!clock) + return -EINVAL; + + status = hdmi_clock_valid(connector, mode, clock); + if (status != MODE_OK) + return -EINVAL; + + conn_state->hdmi.tmds_char_rate = clock; + + return 0; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -44,6 +102,15 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, drm_atomic_get_old_connector_state(state, connector); struct drm_connector_state *new_conn_state = drm_atomic_get_new_connector_state(state, connector); + const struct drm_display_mode *mode = + connector_state_get_mode(new_conn_state); + int ret; + + ret = hdmi_compute_clock(connector, new_conn_state, mode, + new_conn_state->hdmi.output_bpc, + new_conn_state->hdmi.output_format); + if (ret) + return ret; if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) { diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 8730137baa86..26f9e525c0a0 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1148,6 +1148,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); drm_printf(p, "\toutput_format=%s\n", drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); + drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate); } if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 99fed169ea4d..71cfc7450134 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -72,6 +72,9 @@ static int light_up_connector(struct kunit *test, conn_state = drm_atomic_get_connector_state(state, connector); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + conn_state->hdmi.output_bpc = connector->max_bpc; + conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB; + ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); KUNIT_EXPECT_EQ(test, ret, 0); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 4b6b1117c7d0..3bdcf904a11b 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1049,6 +1049,11 @@ struct drm_connector_state { * @output_format: Pixel format to output in. */ enum hdmi_colorspace output_format; + + /** + * @tmds_char_rate: TMDS Character Rate, in Hz. + */ + unsigned long long tmds_char_rate; } hdmi; }; -- cgit v1.2.3 From e5030a74f976b4e808e28e78805c87203ac1a48d Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:58:02 +0200 Subject: drm/connector: hdmi: Add custom hook to filter TMDS character rate Most of the HDMI controllers have an upper TMDS character rate limit they can't exceed. On "embedded"-grade display controllers, it will typically be lower than what high-grade monitors can provide these days, so drivers will filter the TMDS character rate based on the controller capabilities. To make that easier to handle for drivers, let's provide an optional hook to be implemented by drivers so they can tell the HDMI controller helpers if a given TMDS character rate is reachable for them or not. This will then be useful to figure out the best format and bpc count for a given mode. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-13-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 9 +++++++ drivers/gpu/drm/drm_connector.c | 4 +++ drivers/gpu/drm/tests/drm_connector_test.c | 14 ++++++++++ drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 4 +++ include/drm/drm_connector.h | 31 ++++++++++++++++++++++ 5 files changed, 62 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 08630561d864..063421835dba 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -53,11 +53,20 @@ hdmi_clock_valid(const struct drm_connector *connector, const struct drm_display_mode *mode, unsigned long long clock) { + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; const struct drm_display_info *info = &connector->display_info; if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) return MODE_CLOCK_HIGH; + if (funcs && funcs->tmds_char_rate_valid) { + enum drm_mode_status status; + + status = funcs->tmds_char_rate_valid(connector, mode, clock); + if (status != MODE_OK) + return status; + } + return MODE_OK; } diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index f554bf703e13..39e9ff6c4f61 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -457,6 +457,7 @@ EXPORT_SYMBOL(drmm_connector_init); * @dev: DRM device * @connector: A pointer to the HDMI connector to init * @funcs: callbacks for this connector + * @hdmi_funcs: HDMI-related callbacks for this connector * @connector_type: user visible type of the connector * @ddc: optional pointer to the associated ddc adapter * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats @@ -476,6 +477,7 @@ EXPORT_SYMBOL(drmm_connector_init); int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, @@ -512,6 +514,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, if (max_bpc > 8) drm_connector_attach_hdr_output_metadata_property(connector); + connector->hdmi.funcs = hdmi_funcs; + return 0; } EXPORT_SYMBOL(drmm_connector_hdmi_init); diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 8557f722080c..e44dfe2e9455 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -24,6 +24,9 @@ struct drm_connector_init_priv { struct i2c_adapter ddc; }; +static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { +}; + static const struct drm_connector_funcs dummy_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, @@ -189,6 +192,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -207,6 +211,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, BIT(HDMI_COLORSPACE_RGB), @@ -225,6 +230,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -243,6 +249,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -266,6 +273,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -305,6 +313,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -344,6 +353,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -378,6 +388,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, 0, @@ -396,6 +407,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, &priv->ddc, BIT(HDMI_COLORSPACE_YUV422), @@ -415,6 +427,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), @@ -448,6 +461,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, &dummy_funcs, + &dummy_hdmi_funcs, connector_type, &priv->ddc, BIT(HDMI_COLORSPACE_RGB), diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 0731f244f977..23449a4786ce 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -112,6 +112,9 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto return 0; } +static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { +}; + static int dummy_connector_get_modes(struct drm_connector *connector) { struct drm_atomic_helper_connector_hdmi_priv *priv = @@ -194,6 +197,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, conn = &priv->connector; ret = drmm_connector_hdmi_init(drm, conn, &dummy_connector_funcs, + &dummy_connector_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, formats, diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 3bdcf904a11b..ffef967869d9 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -38,6 +38,7 @@ struct drm_connector_helper_funcs; struct drm_modeset_acquire_ctx; struct drm_device; struct drm_crtc; +struct drm_display_mode; struct drm_encoder; struct drm_panel; struct drm_property; @@ -1057,6 +1058,30 @@ struct drm_connector_state { } hdmi; }; +/** + * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions + */ +struct drm_connector_hdmi_funcs { + /** + * @tmds_char_rate_valid: + * + * This callback is invoked at atomic_check time to figure out + * whether a particular TMDS character rate is supported by the + * driver. + * + * The @tmds_char_rate_valid callback is optional. + * + * Returns: + * + * Either &drm_mode_status.MODE_OK or one of the failure reasons + * in &enum drm_mode_status. + */ + enum drm_mode_status + (*tmds_char_rate_valid)(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate); +}; + /** * struct drm_connector_funcs - control connectors on a given device * @@ -1929,6 +1954,11 @@ struct drm_connector { * supported by the controller. */ unsigned long supported_formats; + + /** + * @funcs: HDMI connector Control Functions + */ + const struct drm_connector_hdmi_funcs *funcs; } hdmi; }; @@ -1951,6 +1981,7 @@ int drmm_connector_init(struct drm_device *dev, int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, const struct drm_connector_funcs *funcs, + const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, struct i2c_adapter *ddc, unsigned long supported_formats, -- cgit v1.2.3 From ab52af4ba7c7dc2e226ede5935a0587743b747d3 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:58:07 +0200 Subject: drm/connector: hdmi: Add Broadcast RGB property The i915 driver has a property to force the RGB range of an HDMI output. The vc4 driver then implemented the same property with the same semantics. KWin has support for it, and a PR for mutter is also there to support it. Both drivers implementing the same property with the same semantics, plus the userspace having support for it, is proof enough that it's pretty much a de-facto standard now and we can provide helpers for it. Let's plumb it into the newly created HDMI connector. Reviewed-by: Dave Stevenson Acked-by: Pekka Paalanen Reviewed-by: Sebastian Wick Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-18-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- Documentation/gpu/kms-properties.csv | 1 - drivers/gpu/drm/display/drm_hdmi_state_helper.c | 4 +- drivers/gpu/drm/drm_atomic.c | 2 + drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 88 +++++++++++++++++++++++++ include/drm/drm_connector.h | 36 ++++++++++ 6 files changed, 133 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv index c3c50a277cc9..bfbfbf4f102d 100644 --- a/Documentation/gpu/kms-properties.csv +++ b/Documentation/gpu/kms-properties.csv @@ -17,7 +17,6 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De ,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector ,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB -i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normally in the range 0..1.0 are remapped to the range 16/255..235/255." ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD ,,"""left_margin""",RANGE,"Min=0, Max= SDVO dependent",Connector,TBD diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 1623b96cd97c..57c66beec5bc 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -25,6 +25,7 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, new_conn_state->max_bpc = max_bpc; new_conn_state->max_requested_bpc = max_bpc; + new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO; } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); @@ -332,7 +333,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, if (ret) return ret; - if (old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || + if (old_conn_state->hdmi.broadcast_rgb != new_conn_state->hdmi.broadcast_rgb || + old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) { struct drm_crtc *crtc = new_conn_state->crtc; struct drm_crtc_state *crtc_state; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 26f9e525c0a0..3e57d98d8418 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1145,6 +1145,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { + drm_printf(p, "\tbroadcast_rgb=%s\n", + drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); drm_printf(p, "\toutput_format=%s\n", drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index fc16fddee5c5..22bbb2d83e30 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -776,6 +776,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, state->max_requested_bpc = val; } else if (property == connector->privacy_screen_sw_state_property) { state->privacy_screen_sw_state = val; + } else if (property == connector->broadcast_rgb_property) { + state->hdmi.broadcast_rgb = val; } else if (connector->funcs->atomic_set_property) { return connector->funcs->atomic_set_property(connector, state, property, val); @@ -859,6 +861,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->max_requested_bpc; } else if (property == connector->privacy_screen_sw_state_property) { *val = state->privacy_screen_sw_state; + } else if (property == connector->broadcast_rgb_property) { + *val = state->hdmi.broadcast_rgb; } else if (connector->funcs->atomic_get_property) { return connector->funcs->atomic_get_property(connector, state, property, val); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 39e9ff6c4f61..debb5a77ad89 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1212,6 +1212,29 @@ static const u32 dp_colorspaces = BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); +static const struct drm_prop_enum_list broadcast_rgb_names[] = { + { DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" }, + { DRM_HDMI_BROADCAST_RGB_FULL, "Full" }, + { DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" }, +}; + +/* + * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection + * @broadcast_rgb: Broadcast RGB selection to compute name of + * + * Returns: the name of the Broadcast RGB selection, or NULL if the type + * is not valid. + */ +const char * +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb) +{ + if (broadcast_rgb >= ARRAY_SIZE(broadcast_rgb_names)) + return NULL; + + return broadcast_rgb_names[broadcast_rgb].name; +} +EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name); + static const char * const output_format_str[] = { [HDMI_COLORSPACE_RGB] = "RGB", [HDMI_COLORSPACE_YUV420] = "YUV 4:2:0", @@ -1708,6 +1731,38 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); /** * DOC: HDMI connector properties * + * Broadcast RGB (HDMI specific) + * Indicates the Quantization Range (Full vs Limited) used. The color + * processing pipeline will be adjusted to match the value of the + * property, and the Infoframes will be generated and sent accordingly. + * + * This property is only relevant if the HDMI output format is RGB. If + * it's one of the YCbCr variant, it will be ignored. + * + * The CRTC attached to the connector must be configured by user-space to + * always produce full-range pixels. + * + * The value of this property can be one of the following: + * + * Automatic: + * The quantization range is selected automatically based on the + * mode according to the HDMI specifications (HDMI 1.4b - Section + * 6.6 - Video Quantization Ranges). + * + * Full: + * Full quantization range is forced. + * + * Limited 16:235: + * Limited quantization range is forced. Unlike the name suggests, + * this works for any number of bits-per-component. + * + * Property values other than Automatic can result in colors being off (if + * limited is selected but the display expects full), or a black screen + * (if full is selected but the display expects limited). + * + * Drivers can set up this property by calling + * drm_connector_attach_broadcast_rgb_property(). + * * content type (HDMI specific): * Indicates content type setting to be used in HDMI infoframes to indicate * content type for the external device, so that it adjusts its display @@ -2570,6 +2625,39 @@ int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *conn } EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property); +/** + * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property + * @connector: connector to attach the property on. + * + * This is used to add support for forcing the RGB range on a connector + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = connector->broadcast_rgb_property; + if (!prop) { + prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, + "Broadcast RGB", + broadcast_rgb_names, + ARRAY_SIZE(broadcast_rgb_names)); + if (!prop) + return -EINVAL; + + connector->broadcast_rgb_property = prop; + } + + drm_object_attach_property(&connector->base, prop, + DRM_HDMI_BROADCAST_RGB_AUTO); + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property); + /** * drm_connector_attach_colorspace_property - attach "Colorspace" property * @connector: connector to attach the property on. diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index ffef967869d9..207635715466 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -369,6 +369,29 @@ enum drm_panel_orientation { DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +/** + * enum drm_hdmi_broadcast_rgb - Broadcast RGB Selection for an HDMI @drm_connector + */ +enum drm_hdmi_broadcast_rgb { + /** + * @DRM_HDMI_BROADCAST_RGB_AUTO: The RGB range is selected + * automatically based on the mode. + */ + DRM_HDMI_BROADCAST_RGB_AUTO, + + /** + * @DRM_HDMI_BROADCAST_RGB_FULL: Full range RGB is forced. + */ + DRM_HDMI_BROADCAST_RGB_FULL, + + /** + * @DRM_HDMI_BROADCAST_RGB_LIMITED: Limited range RGB is forced. + */ + DRM_HDMI_BROADCAST_RGB_LIMITED, +}; + +const char * +drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb); const char * drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt); @@ -1041,6 +1064,12 @@ struct drm_connector_state { * @drm_atomic_helper_connector_hdmi_check(). */ struct { + /** + * @broadcast_rgb: Connector property to pass the + * Broadcast RGB selection value. + */ + enum drm_hdmi_broadcast_rgb broadcast_rgb; + /** * @output_bpc: Bits per color channel to output. */ @@ -1757,6 +1786,12 @@ struct drm_connector { */ struct drm_property *privacy_screen_hw_state_property; + /** + * @broadcast_rgb_property: Connector property to set the + * Broadcast RGB selection to output with. + */ + struct drm_property *broadcast_rgb_property; + #define DRM_CONNECTOR_POLL_HPD (1 << 0) #define DRM_CONNECTOR_POLL_CONNECT (1 << 1) #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2) @@ -2096,6 +2131,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector, u32 scaling_mode_mask); int drm_connector_attach_vrr_capable_property( struct drm_connector *connector); +int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector); int drm_connector_attach_colorspace_property(struct drm_connector *connector); int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector); bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state, -- cgit v1.2.3 From 027d435906490812d4568ff371a8b63c24a36bcd Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:58:09 +0200 Subject: drm/connector: hdmi: Add RGB Quantization Range to the connector state HDMI controller drivers will need to figure out the RGB range they need to configure based on a mode and property values. Let's expose that in the HDMI connector state so drivers can just use that value. Reviewed-by: Dave Stevenson Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-20-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 29 +++++++++++++++++++++++++ drivers/gpu/drm/drm_atomic.c | 1 + include/drm/drm_connector.h | 6 +++++ 3 files changed, 36 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 57c66beec5bc..f18020cfe4ea 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -51,6 +51,33 @@ connector_state_get_mode(const struct drm_connector_state *conn_state) return &crtc_state->mode; } +static bool hdmi_is_limited_range(const struct drm_connector *connector, + const struct drm_connector_state *conn_state) +{ + const struct drm_display_info *info = &connector->display_info; + const struct drm_display_mode *mode = + connector_state_get_mode(conn_state); + + /* + * The Broadcast RGB property only applies to RGB format, and + * i915 just assumes limited range for YCbCr output, so let's + * just do the same. + */ + if (conn_state->hdmi.output_format != HDMI_COLORSPACE_RGB) + return true; + + if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL) + return false; + + if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED) + return true; + + if (!info->is_hdmi) + return false; + + return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED; +} + static bool sink_supports_format_bpc(const struct drm_connector *connector, const struct drm_display_info *info, @@ -329,6 +356,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, connector_state_get_mode(new_conn_state); int ret; + new_conn_state->hdmi.is_limited_range = hdmi_is_limited_range(connector, new_conn_state); + ret = hdmi_compute_config(connector, new_conn_state, mode); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3e57d98d8418..07b4b394e3bf 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1147,6 +1147,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { drm_printf(p, "\tbroadcast_rgb=%s\n", drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); + drm_printf(p, "\tis_limited_range=%c\n", state->hdmi.is_limited_range ? 'y' : 'n'); drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); drm_printf(p, "\toutput_format=%s\n", drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 207635715466..dcad2d46fabe 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1070,6 +1070,12 @@ struct drm_connector_state { */ enum drm_hdmi_broadcast_rgb broadcast_rgb; + /** + * @is_full_range: Is the output supposed to use a full + * RGB Quantization Range or not? + */ + bool is_limited_range; + /** * @output_bpc: Bits per color channel to output. */ -- cgit v1.2.3 From f378b77227bc4732922c57f92be89438bb1018a1 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 27 May 2024 15:58:11 +0200 Subject: drm/connector: hdmi: Add Infoframes generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Infoframes in KMS is usually handled by a bunch of low-level helpers that require quite some boilerplate for drivers. This leads to discrepancies with how drivers generate them, and which are actually sent. Now that we have everything needed to generate them in the HDMI connector state, we can generate them in our common logic so that drivers can simply reuse what we precomputed. Cc: Ville Syrjälä Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-22-c5af16c3aae2@kernel.org Signed-off-by: Maxime Ripard --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 336 +++++++++++++++++++++ drivers/gpu/drm/drm_connector.c | 14 + drivers/gpu/drm/tests/drm_connector_test.c | 12 + drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 1 + include/drm/display/drm_hdmi_state_helper.h | 6 + include/drm/drm_connector.h | 111 ++++++- 6 files changed, 479 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index f18020cfe4ea..437270c29210 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -333,6 +333,144 @@ hdmi_compute_config(const struct drm_connector *connector, return -EINVAL; } +static int hdmi_generate_avi_infoframe(const struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + const struct drm_display_mode *mode = + connector_state_get_mode(conn_state); + struct drm_connector_hdmi_infoframe *infoframe = + &conn_state->hdmi.infoframes.avi; + struct hdmi_avi_infoframe *frame = + &infoframe->data.avi; + bool is_limited_range = conn_state->hdmi.is_limited_range; + enum hdmi_quantization_range rgb_quant_range = + is_limited_range ? HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_FULL; + int ret; + + ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode); + if (ret) + return ret; + + frame->colorspace = conn_state->hdmi.output_format; + + /* + * FIXME: drm_hdmi_avi_infoframe_quant_range() doesn't handle + * YUV formats at all at the moment, so if we ever support YUV + * formats this needs to be revised. + */ + drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range); + drm_hdmi_avi_infoframe_colorimetry(frame, conn_state); + drm_hdmi_avi_infoframe_bars(frame, conn_state); + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_spd_infoframe(const struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &conn_state->hdmi.infoframes.spd; + struct hdmi_spd_infoframe *frame = + &infoframe->data.spd; + int ret; + + ret = hdmi_spd_infoframe_init(frame, + connector->hdmi.vendor, + connector->hdmi.product); + if (ret) + return ret; + + frame->sdi = HDMI_SPD_SDI_PC; + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &conn_state->hdmi.infoframes.hdr_drm; + struct hdmi_drm_infoframe *frame = + &infoframe->data.drm; + int ret; + + if (connector->max_bpc < 10) + return 0; + + if (!conn_state->hdr_output_metadata) + return 0; + + ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state); + if (ret) + return ret; + + infoframe->set = true; + + return 0; +} + +static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + const struct drm_display_info *info = &connector->display_info; + const struct drm_display_mode *mode = + connector_state_get_mode(conn_state); + struct drm_connector_hdmi_infoframe *infoframe = + &conn_state->hdmi.infoframes.hdmi; + struct hdmi_vendor_infoframe *frame = + &infoframe->data.vendor.hdmi; + int ret; + + if (!info->has_hdmi_infoframe) + return 0; + + ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode); + if (ret) + return ret; + + infoframe->set = true; + + return 0; +} + +static int +hdmi_generate_infoframes(const struct drm_connector *connector, + struct drm_connector_state *conn_state) +{ + const struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + ret = hdmi_generate_avi_infoframe(connector, conn_state); + if (ret) + return ret; + + ret = hdmi_generate_spd_infoframe(connector, conn_state); + if (ret) + return ret; + + /* + * Audio Infoframes will be generated by ALSA, and updated by + * drm_atomic_helper_connector_hdmi_update_audio_infoframe(). + */ + + ret = hdmi_generate_hdr_infoframe(connector, conn_state); + if (ret) + return ret; + + ret = hdmi_generate_hdmi_vendor_infoframe(connector, conn_state); + if (ret) + return ret; + + return 0; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -362,6 +500,10 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, if (ret) return ret; + ret = hdmi_generate_infoframes(connector, new_conn_state); + if (ret) + return ret; + if (old_conn_state->hdmi.broadcast_rgb != new_conn_state->hdmi.broadcast_rgb || old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc || old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) { @@ -378,3 +520,197 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, return 0; } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check); + +#define HDMI_MAX_INFOFRAME_SIZE 29 + +static int clear_device_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + struct drm_device *dev = connector->dev; + int ret; + + drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type); + + if (!funcs || !funcs->clear_infoframe) { + drm_dbg_kms(dev, "Function not implemented, bailing.\n"); + return 0; + } + + ret = funcs->clear_infoframe(connector, type); + if (ret) { + drm_dbg_kms(dev, "Call failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int clear_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *old_frame) +{ + int ret; + + ret = clear_device_infoframe(connector, old_frame->data.any.type); + if (ret) + return ret; + + return 0; +} + +static int write_device_infoframe(struct drm_connector *connector, + union hdmi_infoframe *frame) +{ + const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs; + struct drm_device *dev = connector->dev; + u8 buffer[HDMI_MAX_INFOFRAME_SIZE]; + int ret; + int len; + + drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type); + + if (!funcs || !funcs->write_infoframe) { + drm_dbg_kms(dev, "Function not implemented, bailing.\n"); + return -EINVAL; + } + + len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer)); + if (len < 0) + return len; + + ret = funcs->write_infoframe(connector, frame->any.type, buffer, len); + if (ret) { + drm_dbg_kms(dev, "Call failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int write_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *new_frame) +{ + int ret; + + ret = write_device_infoframe(connector, &new_frame->data); + if (ret) + return ret; + + return 0; +} + +static int write_or_clear_infoframe(struct drm_connector *connector, + struct drm_connector_hdmi_infoframe *old_frame, + struct drm_connector_hdmi_infoframe *new_frame) +{ + if (new_frame->set) + return write_infoframe(connector, new_frame); + + if (old_frame->set && !new_frame->set) + return clear_infoframe(connector, old_frame); + + return 0; +} + +/** + * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes + * @connector: A pointer to the HDMI connector + * @state: The HDMI connector state to generate the infoframe from + * + * This function is meant for HDMI connector drivers to write their + * infoframes. It will typically be used in a + * @drm_connector_helper_funcs.atomic_enable implementation. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_conn_state = + drm_atomic_get_new_connector_state(state, connector); + struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + mutex_lock(&connector->hdmi.infoframes.lock); + + ret = write_or_clear_infoframe(connector, + &old_conn_state->hdmi.infoframes.avi, + &new_conn_state->hdmi.infoframes.avi); + if (ret) + goto out; + + if (connector->hdmi.infoframes.audio.set) { + ret = write_infoframe(connector, + &connector->hdmi.infoframes.audio); + if (ret) + goto out; + } + + ret = write_or_clear_infoframe(connector, + &old_conn_state->hdmi.infoframes.hdr_drm, + &new_conn_state->hdmi.infoframes.hdr_drm); + if (ret) + goto out; + + ret = write_or_clear_infoframe(connector, + &old_conn_state->hdmi.infoframes.spd, + &new_conn_state->hdmi.infoframes.spd); + if (ret) + goto out; + + if (info->has_hdmi_infoframe) { + ret = write_or_clear_infoframe(connector, + &old_conn_state->hdmi.infoframes.hdmi, + &new_conn_state->hdmi.infoframes.hdmi); + if (ret) + goto out; + } + +out: + mutex_unlock(&connector->hdmi.infoframes.lock); + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes); + +/** + * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe + * @connector: A pointer to the HDMI connector + * @frame: A pointer to the audio infoframe to write + * + * This function is meant for HDMI connector drivers to update their + * audio infoframe. It will typically be used in one of the ALSA hooks + * (most likely prepare). + * + * Returns: + * Zero on success, error code on failure. + */ +int +drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, + struct hdmi_audio_infoframe *frame) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &connector->hdmi.infoframes.audio; + struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + mutex_lock(&connector->hdmi.infoframes.lock); + + memcpy(&infoframe->data, frame, sizeof(infoframe->data)); + infoframe->set = true; + + ret = write_infoframe(connector, infoframe); + + mutex_unlock(&connector->hdmi.infoframes.lock); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index debb5a77ad89..3d73a981004c 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -278,6 +278,7 @@ static int __drm_connector_init(struct drm_device *dev, INIT_LIST_HEAD(&connector->modes); mutex_init(&connector->mutex); mutex_init(&connector->edid_override_mutex); + mutex_init(&connector->hdmi.infoframes.lock); connector->edid_blob_ptr = NULL; connector->epoch_counter = 0; connector->tile_blob_ptr = NULL; @@ -456,6 +457,8 @@ EXPORT_SYMBOL(drmm_connector_init); * drmm_connector_hdmi_init - Init a preallocated HDMI connector * @dev: DRM device * @connector: A pointer to the HDMI connector to init + * @vendor: HDMI Controller Vendor name + * @product: HDMI Controller Product name * @funcs: callbacks for this connector * @hdmi_funcs: HDMI-related callbacks for this connector * @connector_type: user visible type of the connector @@ -476,6 +479,7 @@ EXPORT_SYMBOL(drmm_connector_init); */ int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, + const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, @@ -485,6 +489,13 @@ int drmm_connector_hdmi_init(struct drm_device *dev, { int ret; + if (!vendor || !product) + return -EINVAL; + + if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) || + (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN)) + return -EINVAL; + if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA || connector_type == DRM_MODE_CONNECTOR_HDMIB)) return -EINVAL; @@ -500,6 +511,8 @@ int drmm_connector_hdmi_init(struct drm_device *dev, return ret; connector->hdmi.supported_formats = supported_formats; + strtomem_pad(connector->hdmi.vendor, vendor, 0); + strtomem_pad(connector->hdmi.product, product, 0); /* * drm_connector_attach_max_bpc_property() requires the @@ -652,6 +665,7 @@ void drm_connector_cleanup(struct drm_connector *connector) connector->funcs->atomic_destroy_state(connector, connector->state); + mutex_destroy(&connector->hdmi.infoframes.lock); mutex_destroy(&connector->mutex); memset(connector, 0, sizeof(*connector)); diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index a4ea170a2575..2e631617c391 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -191,6 +191,7 @@ static void drm_test_connector_hdmi_init_valid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -210,6 +211,7 @@ static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -229,6 +231,7 @@ static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -248,6 +251,7 @@ static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -272,6 +276,7 @@ static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -312,6 +317,7 @@ static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -352,6 +358,7 @@ static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -387,6 +394,7 @@ static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -406,6 +414,7 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, @@ -426,6 +435,7 @@ static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, connector_type, @@ -460,6 +470,7 @@ static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) int ret; ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, connector_type, @@ -725,6 +736,7 @@ static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector( int ret; ret = drmm_connector_hdmi_init(&priv->drm, connector, + "Vendor", "Product", &dummy_funcs, &dummy_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 2eda21228d75..2d3abc71dc16 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -206,6 +206,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, conn = &priv->connector; ret = drmm_connector_hdmi_init(drm, conn, + "Vendor", "Product", &dummy_connector_funcs, &dummy_connector_hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h index 837899db315a..eb162ff24de0 100644 --- a/include/drm/display/drm_hdmi_state_helper.h +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -6,6 +6,7 @@ struct drm_atomic_state; struct drm_connector; struct drm_connector_state; +struct hdmi_audio_infoframe; void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, struct drm_connector_state *new_conn_state); @@ -13,4 +14,9 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, struct drm_atomic_state *state); +int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, + struct hdmi_audio_infoframe *frame); +int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, + struct drm_atomic_state *state); + #endif // DRM_HDMI_STATE_HELPER_H_ diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index dcad2d46fabe..e04a8a0d1bbd 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -914,6 +914,21 @@ struct drm_tv_connector_state { unsigned int hue; }; +/** + * struct drm_connector_hdmi_infoframe - HDMI Infoframe container + */ +struct drm_connector_hdmi_infoframe { + /** + * @data: HDMI Infoframe structure + */ + union hdmi_infoframe data; + + /** + * @set: Is the content of @data valid? + */ + bool set; +}; + /** * struct drm_connector_state - mutable connector state */ @@ -1071,7 +1086,36 @@ struct drm_connector_state { enum drm_hdmi_broadcast_rgb broadcast_rgb; /** - * @is_full_range: Is the output supposed to use a full + * @infoframes: HDMI Infoframes matching that state + */ + struct { + /** + * @avi: AVI Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe avi; + + /** + * @hdr_drm: DRM (Dynamic Range and Mastering) + * Infoframes structure matching our state. + */ + struct drm_connector_hdmi_infoframe hdr_drm; + + /** + * @spd: SPD Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe spd; + + /** + * @vendor: HDMI Vendor Infoframes structure + * matching our state. + */ + struct drm_connector_hdmi_infoframe hdmi; + } infoframes; + + /** + * @is_limited_range: Is the output supposed to use a limited * RGB Quantization Range or not? */ bool is_limited_range; @@ -1115,6 +1159,41 @@ struct drm_connector_hdmi_funcs { (*tmds_char_rate_valid)(const struct drm_connector *connector, const struct drm_display_mode *mode, unsigned long long tmds_rate); + + /** + * @clear_infoframe: + * + * This callback is invoked through + * @drm_atomic_helper_connector_hdmi_update_infoframes during a + * commit to clear the infoframes into the hardware. It will be + * called multiple times, once for every disabled infoframe + * type. + * + * The @clear_infoframe callback is optional. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*clear_infoframe)(struct drm_connector *connector, + enum hdmi_infoframe_type type); + + /** + * @write_infoframe: + * + * This callback is invoked through + * @drm_atomic_helper_connector_hdmi_update_infoframes during a + * commit to program the infoframes into the hardware. It will + * be called multiple times, once for every updated infoframe + * type. + * + * The @write_infoframe callback is mandatory. + * + * Returns: + * 0 on success, a negative error code otherwise + */ + int (*write_infoframe)(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len); }; /** @@ -1990,6 +2069,18 @@ struct drm_connector { * @hdmi: HDMI-related variable and properties. */ struct { +#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8 + /** + * @vendor: HDMI Controller Vendor Name + */ + unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring; + +#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16 + /** + * @product: HDMI Controller Product Name + */ + unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring; + /** * @supported_formats: Bitmask of @hdmi_colorspace * supported by the controller. @@ -2000,6 +2091,23 @@ struct drm_connector { * @funcs: HDMI connector Control Functions */ const struct drm_connector_hdmi_funcs *funcs; + + /** + * @infoframes: Current Infoframes output by the connector + */ + struct { + /** + * @lock: Mutex protecting against concurrent access to + * the infoframes, most notably between KMS and ALSA. + */ + struct mutex lock; + + /** + * @audio: Current Audio Infoframes structure. Protected + * by @lock. + */ + struct drm_connector_hdmi_infoframe audio; + } infoframes; } hdmi; }; @@ -2021,6 +2129,7 @@ int drmm_connector_init(struct drm_device *dev, struct i2c_adapter *ddc); int drmm_connector_hdmi_init(struct drm_device *dev, struct drm_connector *connector, + const char *vendor, const char *product, const struct drm_connector_funcs *funcs, const struct drm_connector_hdmi_funcs *hdmi_funcs, int connector_type, -- cgit v1.2.3 From c7ce956bb6d0f32ab921b6ffba1a6a834df96f21 Mon Sep 17 00:00:00 2001 From: MarileneGarcia Date: Sun, 19 May 2024 00:10:27 -0300 Subject: drm/dp: Fix documentation warning It fixes the following warnings when the kernel documentation is generated: ./include/drm/display/drm_dp_helper.h:126: warning: Function parameter or struct member 'mode' not described in 'drm_dp_as_sdp' ./include/drm/display/drm_dp_helper.h:126: warning: Excess struct member 'operation_mode' description in 'drm_dp_as_sdp' Signed-off-by: MarileneGarcia Fixes: 0bbb8f594e33 ("drm/dp: Add Adaptive Sync SDP logging") Reviewed-by: Dmitry Baryshkov Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/r/20240405141640.09b0bdbf@canb.auug.org.au Reviewed-by: Douglas Anderson Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20240519031027.433751-1-marilene.agarcia@gmail.com --- include/drm/display/drm_dp_helper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 8bed890eec2c..8defcc399f42 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -112,7 +112,7 @@ struct drm_dp_vsc_sdp { * @target_rr: Target Refresh * @duration_incr_ms: Successive frame duration increase * @duration_decr_ms: Successive frame duration decrease - * @operation_mode: Adaptive Sync Operation Mode + * @mode: Adaptive Sync Operation Mode */ struct drm_dp_as_sdp { unsigned char sdp_type; -- cgit v1.2.3 From 2f602531db4c5b522073aff1b09d2d5408352a1c Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Tue, 28 May 2024 14:44:52 +0300 Subject: drm/panel replay: Add edp1.5 Panel Replay bits and register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PANEL_REPLAY_CONFIGURATION_2 register and some missing Panel Replay bits. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Acked-by: Maxime Ripard Acked-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20240528114455.175961-3-jouni.hogander@intel.com --- include/drm/display/drm_dp.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 906949ca3cee..79bde372b152 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -544,9 +544,10 @@ /* DFP Capability Extension */ #define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0a3 /* 2.0 */ -#define DP_PANEL_REPLAY_CAP 0x0b0 /* DP 2.0 */ -# define DP_PANEL_REPLAY_SUPPORT (1 << 0) -# define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1) +#define DP_PANEL_REPLAY_CAP 0x0b0 /* DP 2.0 */ +# define DP_PANEL_REPLAY_SUPPORT (1 << 0) +# define DP_PANEL_REPLAY_SU_SUPPORT (1 << 1) +# define DP_PANEL_REPLAY_EARLY_TRANSPORT_SUPPORT (1 << 2) /* eDP 1.5 */ #define DP_PANEL_PANEL_REPLAY_CAPABILITY 0xb1 # define DP_PANEL_PANEL_REPLAY_SU_GRANULARITY_REQUIRED (1 << 5) @@ -734,11 +735,20 @@ #define PANEL_REPLAY_CONFIG 0x1b0 /* DP 2.0 */ # define DP_PANEL_REPLAY_ENABLE (1 << 0) +# define DP_PANEL_REPLAY_VSC_SDP_CRC_EN (1 << 1) /* eDP 1.5 */ # define DP_PANEL_REPLAY_UNRECOVERABLE_ERROR_EN (1 << 3) # define DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN (1 << 4) # define DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN (1 << 5) # define DP_PANEL_REPLAY_SU_ENABLE (1 << 6) +#define PANEL_REPLAY_CONFIG2 0x1b1 /* eDP 1.5 */ +# define DP_PANEL_REPLAY_SINK_REFRESH_RATE_UNLOCK_GRANTED (1 << 0) +# define DP_PANEL_REPLAY_CRC_VERIFICATION (1 << 1) +# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_EN (1 << 2) +# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_VAL_SEL_SHIFT 3 +# define DP_PANEL_REPLAY_SU_Y_GRANULARITY_EXTENDED_VAL_SEL_MASK (0xf << 3) +# define DP_PANEL_REPLAY_SU_REGION_SCANLINE_CAPTURE (1 << 7) + #define DP_PAYLOAD_ALLOCATE_SET 0x1c0 #define DP_PAYLOAD_ALLOCATE_START_TIME_SLOT 0x1c1 #define DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT 0x1c2 -- cgit v1.2.3 From 73fc975318e0ab3385c5b3372c7b296ae58c8d6b Mon Sep 17 00:00:00 2001 From: Durai Manickam KR Date: Wed, 24 Apr 2024 11:03:45 +0530 Subject: drm: atmel-hlcdc: Define XLCDC specific registers The register address of the XLCDC IP used in SAM9X7 SoC family are different from the previous HLCDC. Defining those address space with valid macros. Signed-off-by: Durai Manickam KR [manikandan.m@microchip.com: Remove unused macro definitions] Signed-off-by: Manikandan Muralidharan Acked-by: Lee Jones Acked-by: Sam Ravnborg Signed-off-by: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20240424053351.589830-3-manikandan.m@microchip.com --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 42 ++++++++++++++++++++++++++++ include/linux/mfd/atmel-hlcdc.h | 10 +++++++ 2 files changed, 52 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h index d0ecf0f58cce..c32e5c8809d7 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @@ -15,6 +15,7 @@ #include +/* LCD controller common registers */ #define ATMEL_HLCDC_LAYER_CHER 0x0 #define ATMEL_HLCDC_LAYER_CHDR 0x4 #define ATMEL_HLCDC_LAYER_CHSR 0x8 @@ -128,6 +129,47 @@ #define ATMEL_HLCDC_MAX_LAYERS 6 +/* XLCDC controller specific registers */ +#define ATMEL_XLCDC_LAYER_ENR 0x10 +#define ATMEL_XLCDC_LAYER_EN BIT(0) + +#define ATMEL_XLCDC_LAYER_IER 0x0 +#define ATMEL_XLCDC_LAYER_IDR 0x4 +#define ATMEL_XLCDC_LAYER_ISR 0xc +#define ATMEL_XLCDC_LAYER_OVR_IRQ(p) BIT(2 + (8 * (p))) + +#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p) (((p) * 0x4) + 0x18) + +#define ATMEL_XLCDC_LAYER_DMA_CFG 0 + +#define ATMEL_XLCDC_LAYER_DMA BIT(0) +#define ATMEL_XLCDC_LAYER_REP BIT(1) +#define ATMEL_XLCDC_LAYER_DISCEN BIT(4) + +#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS (4 << 6) +#define ATMEL_XLCDC_LAYER_SFACTA_ONE BIT(9) +#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS (6 << 11) +#define ATMEL_XLCDC_LAYER_DFACTA_ONE BIT(14) + +#define ATMEL_XLCDC_LAYER_A0_SHIFT 16 +#define ATMEL_XLCDC_LAYER_A0(x) \ + ((x) << ATMEL_XLCDC_LAYER_A0_SHIFT) + +#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE BIT(0) +#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE BIT(1) +#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE BIT(5) + +#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE BIT(0) +#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE BIT(16) +#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE BIT(20) + +#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE BIT(0) +#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE BIT(16) +#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE BIT(20) + /** * Atmel HLCDC Layer registers layout structure * diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h index a186119a49b5..80d675a03b39 100644 --- a/include/linux/mfd/atmel-hlcdc.h +++ b/include/linux/mfd/atmel-hlcdc.h @@ -22,6 +22,8 @@ #define ATMEL_HLCDC_DITHER BIT(6) #define ATMEL_HLCDC_DISPDLY BIT(7) #define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8) +#define ATMEL_XLCDC_MODE_MASK GENMASK(10, 8) +#define ATMEL_XLCDC_DPI BIT(11) #define ATMEL_HLCDC_PP BIT(10) #define ATMEL_HLCDC_VSPSU BIT(12) #define ATMEL_HLCDC_VSPHO BIT(13) @@ -34,6 +36,12 @@ #define ATMEL_HLCDC_IDR 0x30 #define ATMEL_HLCDC_IMR 0x34 #define ATMEL_HLCDC_ISR 0x38 +#define ATMEL_XLCDC_ATTRE 0x3c + +#define ATMEL_XLCDC_BASE_UPDATE BIT(0) +#define ATMEL_XLCDC_OVR1_UPDATE BIT(1) +#define ATMEL_XLCDC_OVR3_UPDATE BIT(2) +#define ATMEL_XLCDC_HEO_UPDATE BIT(3) #define ATMEL_HLCDC_CLKPOL BIT(0) #define ATMEL_HLCDC_CLKSEL BIT(2) @@ -48,6 +56,8 @@ #define ATMEL_HLCDC_DISP BIT(2) #define ATMEL_HLCDC_PWM BIT(3) #define ATMEL_HLCDC_SIP BIT(4) +#define ATMEL_XLCDC_SD BIT(5) +#define ATMEL_XLCDC_CM BIT(6) #define ATMEL_HLCDC_SOF BIT(0) #define ATMEL_HLCDC_SYNCDIS BIT(1) -- cgit v1.2.3 From b09469817812ed30c2fda685831a1779437c9c11 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Thu, 30 May 2024 01:37:39 +0530 Subject: drm/display: Add missing aux less alpm wake related bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit eDP1.5 adds some more bits into DP_RECEIVER_ALPM_CAP and DP_RECEIVER_ALPM_CONFIG registers. Add definitions for these. Acked-by: Maxime Ripard Reviewed-by: Ankit Nautiyal Signed-off-by: Jouni Högander Signed-off-by: Animesh Manna Link: https://patchwork.freedesktop.org/patch/msgid/20240529200742.1694401-4-animesh.manna@intel.com --- include/drm/display/drm_dp.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index 79bde372b152..f246fa03a3cb 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -232,6 +232,8 @@ #define DP_RECEIVER_ALPM_CAP 0x02e /* eDP 1.4 */ # define DP_ALPM_CAP (1 << 0) +# define DP_ALPM_PM_STATE_2A_SUPPORT (1 << 1) /* eDP 1.5 */ +# define DP_ALPM_AUX_LESS_CAP (1 << 2) /* eDP 1.5 */ #define DP_SINK_DEVICE_AUX_FRAME_SYNC_CAP 0x02f /* eDP 1.4 */ # define DP_AUX_FRAME_SYNC_CAP (1 << 0) @@ -684,7 +686,8 @@ #define DP_RECEIVER_ALPM_CONFIG 0x116 /* eDP 1.4 */ # define DP_ALPM_ENABLE (1 << 0) -# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1) +# define DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE (1 << 1) /* eDP 1.5 */ +# define DP_ALPM_MODE_AUX_LESS (1 << 2) /* eDP 1.5 */ #define DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF 0x117 /* eDP 1.4 */ # define DP_AUX_FRAME_SYNC_ENABLE (1 << 0) -- cgit v1.2.3 From f498d28977ab76ede14d4a78047e54a215c0a9d9 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 22 May 2024 20:33:43 +0300 Subject: drm/i915: add LNL PCI IDs Although not supported by i915 core, the display code needs to know the LNL PCI IDs. Long term, xe and i915 should probably share the file defining PCI IDs. Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/d2baf7f89ed4df63674dac3d59982de69a7b14d4.1716399081.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/i915_pciids.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 3e39d644ebaa..7ae7ee11ef38 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h @@ -783,4 +783,10 @@ MACRO__(0x7DD1, ## __VA_ARGS__), \ MACRO__(0x7DD5, ## __VA_ARGS__) +/* LNL */ +#define INTEL_LNL_IDS(MACRO__, ...) \ + MACRO__(0x6420, ## __VA_ARGS__), \ + MACRO__(0x64A0, ## __VA_ARGS__), \ + MACRO__(0x64B0, ## __VA_ARGS__) + #endif /* _I915_PCIIDS_H */ -- cgit v1.2.3 From 05255ccbf172cb3e4c18200e077b46cc109698f5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:02 +0300 Subject: drm: move intel-gtt.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Reviewed-by: Andi Shyti Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/ae224504d99cc6428da6dced9dcde2b7953624ef.1717075103.git.jani.nikula@intel.com --- drivers/char/agp/intel-agp.c | 2 +- drivers/char/agp/intel-gtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c | 2 +- drivers/gpu/drm/i915/gt/intel_gt.c | 2 +- include/drm/intel-gtt.h | 39 ------------------------------- include/drm/intel/intel-gtt.h | 39 +++++++++++++++++++++++++++++++ 7 files changed, 44 insertions(+), 44 deletions(-) delete mode 100644 include/drm/intel-gtt.h create mode 100644 include/drm/intel/intel-gtt.h (limited to 'include') diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index c518b3a9db04..eec80db6402d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -12,7 +12,7 @@ #include #include "agp.h" #include "intel-agp.h" -#include +#include static int intel_fetch_size(void) { diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index bf6716ff863b..11f5cf853c46 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -25,7 +25,7 @@ #include #include "agp.h" #include "intel-agp.h" -#include +#include #include /* diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 0d0a0dc9f610..2717699c6591 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "display/intel_display.h" #include "gem/i915_gem_lmem.h" diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c index 866c416afb73..59eed0a0ce90 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c @@ -5,7 +5,7 @@ #include "intel_ggtt_gmch.h" -#include +#include #include diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c index 626b166e67ef..a6c69a706fd7 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt.c +++ b/drivers/gpu/drm/i915/gt/intel_gt.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include "gem/i915_gem_internal.h" #include "gem/i915_gem_lmem.h" diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h deleted file mode 100644 index cb0d5b7200c7..000000000000 --- a/include/drm/intel-gtt.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Common header for intel-gtt.ko and i915.ko */ - -#ifndef _DRM_INTEL_GTT_H -#define _DRM_INTEL_GTT_H - -#include - -struct agp_bridge_data; -struct pci_dev; -struct sg_table; - -void intel_gmch_gtt_get(u64 *gtt_total, - phys_addr_t *mappable_base, - resource_size_t *mappable_end); - -int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, - struct agp_bridge_data *bridge); -void intel_gmch_remove(void); - -bool intel_gmch_enable_gtt(void); - -void intel_gmch_gtt_flush(void); -void intel_gmch_gtt_insert_page(dma_addr_t addr, - unsigned int pg, - unsigned int flags); -void intel_gmch_gtt_insert_sg_entries(struct sg_table *st, - unsigned int pg_start, - unsigned int flags); -void intel_gmch_gtt_clear_range(unsigned int first_entry, unsigned int num_entries); - -/* Special gtt memory types */ -#define AGP_DCACHE_MEMORY 1 -#define AGP_PHYS_MEMORY 2 - -/* flag for GFDT type */ -#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) - -#endif diff --git a/include/drm/intel/intel-gtt.h b/include/drm/intel/intel-gtt.h new file mode 100644 index 000000000000..cb0d5b7200c7 --- /dev/null +++ b/include/drm/intel/intel-gtt.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Common header for intel-gtt.ko and i915.ko */ + +#ifndef _DRM_INTEL_GTT_H +#define _DRM_INTEL_GTT_H + +#include + +struct agp_bridge_data; +struct pci_dev; +struct sg_table; + +void intel_gmch_gtt_get(u64 *gtt_total, + phys_addr_t *mappable_base, + resource_size_t *mappable_end); + +int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, + struct agp_bridge_data *bridge); +void intel_gmch_remove(void); + +bool intel_gmch_enable_gtt(void); + +void intel_gmch_gtt_flush(void); +void intel_gmch_gtt_insert_page(dma_addr_t addr, + unsigned int pg, + unsigned int flags); +void intel_gmch_gtt_insert_sg_entries(struct sg_table *st, + unsigned int pg_start, + unsigned int flags); +void intel_gmch_gtt_clear_range(unsigned int first_entry, unsigned int num_entries); + +/* Special gtt memory types */ +#define AGP_DCACHE_MEMORY 1 +#define AGP_PHYS_MEMORY 2 + +/* flag for GFDT type */ +#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) + +#endif -- cgit v1.2.3 From 0706d57100fd0b2b34d50855726f648b8bfa7d2b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:03 +0300 Subject: drm: move i915_gsc_proxy_mei_interface.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Tomas Winkler Reviewed-by: Andi Shyti Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/461662d528c3f327c81b764b7c883cd4519d8729.1717075103.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 2 +- drivers/gpu/drm/xe/xe_gsc_proxy.c | 2 +- drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 2 +- include/drm/i915_gsc_proxy_mei_interface.h | 53 ------------------------ include/drm/intel/i915_gsc_proxy_mei_interface.h | 53 ++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 56 deletions(-) delete mode 100644 include/drm/i915_gsc_proxy_mei_interface.h create mode 100644 include/drm/intel/i915_gsc_proxy_mei_interface.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c index a7d5465655f9..e7619d81353c 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include "gt/intel_gt.h" #include "gt/intel_gt_print.h" diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c index 1b908d238bd1..bd5d2f656441 100644 --- a/drivers/gpu/drm/xe/xe_gsc_proxy.c +++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c @@ -10,7 +10,7 @@ #include #include -#include +#include #include "abi/gsc_proxy_commands_abi.h" #include "regs/xe_gsc_regs.h" diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c index 89364bdbb129..d5fbaf5d0c8e 100644 --- a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c +++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include /** * mei_gsc_proxy_send - Sends a proxy message to ME FW. diff --git a/include/drm/i915_gsc_proxy_mei_interface.h b/include/drm/i915_gsc_proxy_mei_interface.h deleted file mode 100644 index 850dfbf40607..000000000000 --- a/include/drm/i915_gsc_proxy_mei_interface.h +++ /dev/null @@ -1,53 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright (c) 2022-2023 Intel Corporation - */ - -#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_ -#define _I915_GSC_PROXY_MEI_INTERFACE_H_ - -#include - -struct device; -struct module; - -/** - * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services. - * @owner: Module providing the ops - * @send: sends a proxy message from GSC FW to ME FW - * @recv: receives a proxy message for GSC FW from ME FW - */ -struct i915_gsc_proxy_component_ops { - struct module *owner; - - /** - * @send: Sends a proxy message to ME FW. - * @dev: device struct corresponding to the mei device - * @buf: message buffer to send - * @size: size of the message - * Return: bytes sent on success, negative errno value on failure - */ - int (*send)(struct device *dev, const void *buf, size_t size); - - /** - * @recv: Receives a proxy message from ME FW. - * @dev: device struct corresponding to the mei device - * @buf: message buffer to contain the received message - * @size: size of the buffer - * Return: bytes received on success, negative errno value on failure - */ - int (*recv)(struct device *dev, void *buf, size_t size); -}; - -/** - * struct i915_gsc_proxy_component - Used for communication between i915 and - * MEI drivers for GSC proxy services - * @mei_dev: device that provide the GSC proxy service. - * @ops: Ops implemented by GSC proxy driver, used by i915 driver. - */ -struct i915_gsc_proxy_component { - struct device *mei_dev; - const struct i915_gsc_proxy_component_ops *ops; -}; - -#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */ diff --git a/include/drm/intel/i915_gsc_proxy_mei_interface.h b/include/drm/intel/i915_gsc_proxy_mei_interface.h new file mode 100644 index 000000000000..850dfbf40607 --- /dev/null +++ b/include/drm/intel/i915_gsc_proxy_mei_interface.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright (c) 2022-2023 Intel Corporation + */ + +#ifndef _I915_GSC_PROXY_MEI_INTERFACE_H_ +#define _I915_GSC_PROXY_MEI_INTERFACE_H_ + +#include + +struct device; +struct module; + +/** + * struct i915_gsc_proxy_component_ops - ops for GSC Proxy services. + * @owner: Module providing the ops + * @send: sends a proxy message from GSC FW to ME FW + * @recv: receives a proxy message for GSC FW from ME FW + */ +struct i915_gsc_proxy_component_ops { + struct module *owner; + + /** + * @send: Sends a proxy message to ME FW. + * @dev: device struct corresponding to the mei device + * @buf: message buffer to send + * @size: size of the message + * Return: bytes sent on success, negative errno value on failure + */ + int (*send)(struct device *dev, const void *buf, size_t size); + + /** + * @recv: Receives a proxy message from ME FW. + * @dev: device struct corresponding to the mei device + * @buf: message buffer to contain the received message + * @size: size of the buffer + * Return: bytes received on success, negative errno value on failure + */ + int (*recv)(struct device *dev, void *buf, size_t size); +}; + +/** + * struct i915_gsc_proxy_component - Used for communication between i915 and + * MEI drivers for GSC proxy services + * @mei_dev: device that provide the GSC proxy service. + * @ops: Ops implemented by GSC proxy driver, used by i915 driver. + */ +struct i915_gsc_proxy_component { + struct device *mei_dev; + const struct i915_gsc_proxy_component_ops *ops; +}; + +#endif /* _I915_GSC_PROXY_MEI_INTERFACE_H_ */ -- cgit v1.2.3 From 1bb01bdab03f43e324dcc3a4f0cfc15c5a2e215e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:04 +0300 Subject: drm: move i915_component.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. v2: Also change Documentation/gpu/i915.rst (Andi) Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Tomas Winkler Cc: Jaroslav Kysela Cc: Takashi Iwai Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/a8c07233a8234858eb6711140482ef8db4c91cf4.1717075103.git.jani.nikula@intel.com --- Documentation/gpu/i915.rst | 2 +- drivers/gpu/drm/i915/display/intel_audio.c | 2 +- drivers/gpu/drm/i915/display/intel_hdcp.c | 2 +- drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 2 +- drivers/gpu/drm/xe/xe_gsc_proxy.c | 2 +- drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c | 2 +- drivers/misc/mei/hdcp/mei_hdcp.c | 2 +- drivers/misc/mei/pxp/mei_pxp.c | 2 +- include/drm/i915_component.h | 56 ---------------------------- include/drm/intel/i915_component.h | 56 ++++++++++++++++++++++++++++ include/sound/hdaudio.h | 2 +- 12 files changed, 66 insertions(+), 66 deletions(-) delete mode 100644 include/drm/i915_component.h create mode 100644 include/drm/intel/i915_component.h (limited to 'include') diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 3113e36f14cf..ad59ae579237 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst @@ -150,7 +150,7 @@ High Definition Audio .. kernel-doc:: drivers/gpu/drm/i915/display/intel_audio.c :internal: -.. kernel-doc:: include/drm/i915_component.h +.. kernel-doc:: include/drm/intel/i915_component.h :internal: Intel HDMI LPE Audio Support diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index 4c031e97f9a5..b9bafec06fb8 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include "i915_drv.h" #include "intel_atomic.h" diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 5767070248bb..ba3eca919900 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include "i915_drv.h" #include "i915_reg.h" diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c index e7619d81353c..d8edd7c054c8 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_proxy.c @@ -5,7 +5,7 @@ #include -#include +#include #include #include "gt/intel_gt.h" diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index b00d6c280159..051b6cdcf721 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include "gem/i915_gem_lmem.h" #include "gt/intel_gt_print.h" diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c index bd5d2f656441..8665ca7a727d 100644 --- a/drivers/gpu/drm/xe/xe_gsc_proxy.c +++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "abi/gsc_proxy_commands_abi.h" diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c index d5fbaf5d0c8e..f52fe23a6c0b 100644 --- a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c +++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include /** diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c index f8759a6c9ed3..e43ea536c947 100644 --- a/drivers/misc/mei/hdcp/mei_hdcp.c +++ b/drivers/misc/mei/hdcp/mei_hdcp.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include "mei_hdcp.h" diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index b1e4c23b31a3..5a7a4d8b0e23 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "mei_pxp.h" diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h deleted file mode 100644 index 4ea3b17aa143..000000000000 --- a/include/drm/i915_component.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2014 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef _I915_COMPONENT_H_ -#define _I915_COMPONENT_H_ - -#include - -enum i915_component_type { - I915_COMPONENT_AUDIO = 1, - I915_COMPONENT_HDCP, - I915_COMPONENT_PXP, - I915_COMPONENT_GSC_PROXY, -}; - -/* MAX_PORT is the number of port - * It must be sync with I915_MAX_PORTS defined i915_drv.h - */ -#define MAX_PORTS 9 - -/** - * struct i915_audio_component - Used for direct communication between i915 and hda drivers - */ -struct i915_audio_component { - /** - * @base: the drm_audio_component base class - */ - struct drm_audio_component base; - - /** - * @aud_sample_rate: the array of audio sample rate per port - */ - int aud_sample_rate[MAX_PORTS]; -}; - -#endif /* _I915_COMPONENT_H_ */ diff --git a/include/drm/intel/i915_component.h b/include/drm/intel/i915_component.h new file mode 100644 index 000000000000..4ea3b17aa143 --- /dev/null +++ b/include/drm/intel/i915_component.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _I915_COMPONENT_H_ +#define _I915_COMPONENT_H_ + +#include + +enum i915_component_type { + I915_COMPONENT_AUDIO = 1, + I915_COMPONENT_HDCP, + I915_COMPONENT_PXP, + I915_COMPONENT_GSC_PROXY, +}; + +/* MAX_PORT is the number of port + * It must be sync with I915_MAX_PORTS defined i915_drv.h + */ +#define MAX_PORTS 9 + +/** + * struct i915_audio_component - Used for direct communication between i915 and hda drivers + */ +struct i915_audio_component { + /** + * @base: the drm_audio_component base class + */ + struct drm_audio_component base; + + /** + * @aud_sample_rate: the array of audio sample rate per port + */ + int aud_sample_rate[MAX_PORTS]; +}; + +#endif /* _I915_COMPONENT_H_ */ diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index a73d7f34f4e5..00d1ab6936dd 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include /* codec node id */ typedef u16 hda_nid_t; -- cgit v1.2.3 From a1ed6865df70d0b022f510691059219d0b715d84 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:05 +0300 Subject: drm: move intel_lpe_audio.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Jaroslav Kysela Cc: Takashi Iwai Reviewed-by: Andi Shyti Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/2d645970a65cfd13e01fd8195b35bf9483ae9c2f.1717075103.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/display/intel_lpe_audio.c | 2 +- include/drm/intel/intel_lpe_audio.h | 51 ++++++++++++++++++++++++++ include/drm/intel_lpe_audio.h | 51 -------------------------- sound/x86/intel_hdmi_audio.c | 2 +- 5 files changed, 54 insertions(+), 54 deletions(-) create mode 100644 include/drm/intel/intel_lpe_audio.h delete mode 100644 include/drm/intel_lpe_audio.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 3767be0bdba8..06ec9ce7fe1c 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include "g4x_hdmi.h" #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c index 93e6cac9a4ed..f11626176fe2 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -68,7 +68,7 @@ #include #include -#include +#include #include "i915_drv.h" #include "i915_irq.h" diff --git a/include/drm/intel/intel_lpe_audio.h b/include/drm/intel/intel_lpe_audio.h new file mode 100644 index 000000000000..b6121c8fe539 --- /dev/null +++ b/include/drm/intel/intel_lpe_audio.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2016 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _INTEL_LPE_AUDIO_H_ +#define _INTEL_LPE_AUDIO_H_ + +#include +#include + +struct platform_device; + +#define HDMI_MAX_ELD_BYTES 128 + +struct intel_hdmi_lpe_audio_port_pdata { + u8 eld[HDMI_MAX_ELD_BYTES]; + int port; + int pipe; + int ls_clock; + bool dp_output; +}; + +struct intel_hdmi_lpe_audio_pdata { + struct intel_hdmi_lpe_audio_port_pdata port[3]; /* for ports B,C,D */ + int num_ports; + int num_pipes; + + void (*notify_audio_lpe)(struct platform_device *pdev, int port); /* port: 0==B,1==C,2==D */ + spinlock_t lpe_audio_slock; +}; + +#endif /* _I915_LPE_AUDIO_H_ */ diff --git a/include/drm/intel_lpe_audio.h b/include/drm/intel_lpe_audio.h deleted file mode 100644 index b6121c8fe539..000000000000 --- a/include/drm/intel_lpe_audio.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright © 2016 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef _INTEL_LPE_AUDIO_H_ -#define _INTEL_LPE_AUDIO_H_ - -#include -#include - -struct platform_device; - -#define HDMI_MAX_ELD_BYTES 128 - -struct intel_hdmi_lpe_audio_port_pdata { - u8 eld[HDMI_MAX_ELD_BYTES]; - int port; - int pipe; - int ls_clock; - bool dp_output; -}; - -struct intel_hdmi_lpe_audio_pdata { - struct intel_hdmi_lpe_audio_port_pdata port[3]; /* for ports B,C,D */ - int num_ports; - int num_pipes; - - void (*notify_audio_lpe)(struct platform_device *pdev, int port); /* port: 0==B,1==C,2==D */ - spinlock_t lpe_audio_slock; -}; - -#endif /* _I915_LPE_AUDIO_H_ */ diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 02f5a7f9b728..d41ea09ffbe5 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "intel_hdmi_audio.h" #define INTEL_HDMI_AUDIO_SUSPEND_DELAY_MS 5000 -- cgit v1.2.3 From 03c7918d0d52378d215712ff66c06a980a2119ab Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:06 +0300 Subject: drm: move i915_drm.h under include/drm/intel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. v2: Also fix comment in intel_pci_config.h (Ilpo) Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Bjorn Helgaas Cc: Hans de Goede Cc: Ilpo Järvinen Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/0e344a72e9be596ac2b8b55a26fd674a96f03cdc.1717075103.git.jani.nikula@intel.com --- arch/x86/kernel/early-quirks.c | 2 +- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 2 +- drivers/gpu/drm/i915/gt/intel_ggtt.c | 2 +- drivers/gpu/drm/i915/gt/intel_rps.c | 2 +- drivers/gpu/drm/i915/intel_pci_config.h | 2 +- drivers/gpu/drm/i915/soc/intel_gmch.c | 2 +- drivers/gpu/drm/xe/xe_ggtt.c | 2 +- drivers/platform/x86/intel_ips.c | 2 +- include/drm/i915_drm.h | 102 ----------------------------- include/drm/intel/i915_drm.h | 102 +++++++++++++++++++++++++++++ 10 files changed, 110 insertions(+), 110 deletions(-) delete mode 100644 include/drm/i915_drm.h create mode 100644 include/drm/intel/i915_drm.h (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 1c137771c5d2..ec1a7943c228 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index ad6dd7f3259b..30595b2b63e1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include "gem/i915_gem_lmem.h" #include "gem/i915_gem_region.h" diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index 2717699c6591..206a5e0fedf1 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include "display/intel_display.h" diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index c9cb2a391942..70176be269d3 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -5,7 +5,7 @@ #include -#include +#include #include "display/intel_display.h" #include "display/intel_display_irq.h" diff --git a/drivers/gpu/drm/i915/intel_pci_config.h b/drivers/gpu/drm/i915/intel_pci_config.h index 23b8e519f333..ebe040828e20 100644 --- a/drivers/gpu/drm/i915/intel_pci_config.h +++ b/drivers/gpu/drm/i915/intel_pci_config.h @@ -31,7 +31,7 @@ static inline int intel_mmio_bar(int graphics_ver) } } -/* BSM in include/drm/i915_drm.h */ +/* BSM in include/drm/intel/i915_drm.h */ #define MCHBAR_I915 0x44 #define MCHBAR_I965 0x48 diff --git a/drivers/gpu/drm/i915/soc/intel_gmch.c b/drivers/gpu/drm/i915/soc/intel_gmch.c index 40874ebfb64c..734e9f2801ea 100644 --- a/drivers/gpu/drm/i915/soc/intel_gmch.c +++ b/drivers/gpu/drm/i915/soc/intel_gmch.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include "i915_drv.h" #include "intel_gmch.h" diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index 0d541f55b4fc..96fd8190ab7e 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include "regs/xe_gt_regs.h" #include "regs/xe_gtt_defs.h" diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index ba38649cc142..2a88012958eb 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include #include #include "intel_ips.h" diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h deleted file mode 100644 index adff68538484..000000000000 --- a/include/drm/i915_drm.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ -#ifndef _I915_DRM_H_ -#define _I915_DRM_H_ - -#include - -/* For use by IPS driver */ -unsigned long i915_read_mch_val(void); -bool i915_gpu_raise(void); -bool i915_gpu_lower(void); -bool i915_gpu_busy(void); -bool i915_gpu_turbo_disable(void); - -/* Exported from arch/x86/kernel/early-quirks.c */ -extern struct resource intel_graphics_stolen_res; - -/* - * The Bridge device's PCI config space has information about the - * fb aperture size and the amount of pre-reserved memory. - * This is all handled in the intel-gtt.ko module. i915.ko only - * cares about the vga bit for the vga arbiter. - */ -#define INTEL_GMCH_CTRL 0x52 -#define INTEL_GMCH_VGA_DISABLE (1 << 1) -#define SNB_GMCH_CTRL 0x50 -#define SNB_GMCH_GGMS_SHIFT 8 /* GTT Graphics Memory Size */ -#define SNB_GMCH_GGMS_MASK 0x3 -#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ -#define SNB_GMCH_GMS_MASK 0x1f -#define BDW_GMCH_GGMS_SHIFT 6 -#define BDW_GMCH_GGMS_MASK 0x3 -#define BDW_GMCH_GMS_SHIFT 8 -#define BDW_GMCH_GMS_MASK 0xff - -#define I830_GMCH_CTRL 0x52 - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK 0xF0 -#define I855_GMCH_GMS_STOLEN_0M 0x0 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) -#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) -#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) -#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) -#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) -#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) -#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) - -#define I830_DRB3 0x63 -#define I85X_DRB3 0x43 -#define I865_TOUD 0xc4 - -#define I830_ESMRAMC 0x91 -#define I845_ESMRAMC 0x9e -#define I85X_ESMRAMC 0x61 -#define TSEG_ENABLE (1 << 0) -#define I830_TSEG_SIZE_512K (0 << 1) -#define I830_TSEG_SIZE_1M (1 << 1) -#define I845_TSEG_SIZE_MASK (3 << 1) -#define I845_TSEG_SIZE_512K (2 << 1) -#define I845_TSEG_SIZE_1M (3 << 1) - -#define INTEL_BSM 0x5c -#define INTEL_GEN11_BSM_DW0 0xc0 -#define INTEL_GEN11_BSM_DW1 0xc4 -#define INTEL_BSM_MASK (-(1u << 20)) - -#endif /* _I915_DRM_H_ */ diff --git a/include/drm/intel/i915_drm.h b/include/drm/intel/i915_drm.h new file mode 100644 index 000000000000..adff68538484 --- /dev/null +++ b/include/drm/intel/i915_drm.h @@ -0,0 +1,102 @@ +/* + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +#ifndef _I915_DRM_H_ +#define _I915_DRM_H_ + +#include + +/* For use by IPS driver */ +unsigned long i915_read_mch_val(void); +bool i915_gpu_raise(void); +bool i915_gpu_lower(void); +bool i915_gpu_busy(void); +bool i915_gpu_turbo_disable(void); + +/* Exported from arch/x86/kernel/early-quirks.c */ +extern struct resource intel_graphics_stolen_res; + +/* + * The Bridge device's PCI config space has information about the + * fb aperture size and the amount of pre-reserved memory. + * This is all handled in the intel-gtt.ko module. i915.ko only + * cares about the vga bit for the vga arbiter. + */ +#define INTEL_GMCH_CTRL 0x52 +#define INTEL_GMCH_VGA_DISABLE (1 << 1) +#define SNB_GMCH_CTRL 0x50 +#define SNB_GMCH_GGMS_SHIFT 8 /* GTT Graphics Memory Size */ +#define SNB_GMCH_GGMS_MASK 0x3 +#define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ +#define SNB_GMCH_GMS_MASK 0x1f +#define BDW_GMCH_GGMS_SHIFT 6 +#define BDW_GMCH_GGMS_MASK 0x3 +#define BDW_GMCH_GMS_SHIFT 8 +#define BDW_GMCH_GMS_MASK 0xff + +#define I830_GMCH_CTRL 0x52 + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I855_GMCH_GMS_MASK 0xF0 +#define I855_GMCH_GMS_STOLEN_0M 0x0 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) +#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4) +#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) +#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) +#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) +#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4) +#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4) +#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4) +#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4) + +#define I830_DRB3 0x63 +#define I85X_DRB3 0x43 +#define I865_TOUD 0xc4 + +#define I830_ESMRAMC 0x91 +#define I845_ESMRAMC 0x9e +#define I85X_ESMRAMC 0x61 +#define TSEG_ENABLE (1 << 0) +#define I830_TSEG_SIZE_512K (0 << 1) +#define I830_TSEG_SIZE_1M (1 << 1) +#define I845_TSEG_SIZE_MASK (3 << 1) +#define I845_TSEG_SIZE_512K (2 << 1) +#define I845_TSEG_SIZE_1M (3 << 1) + +#define INTEL_BSM 0x5c +#define INTEL_GEN11_BSM_DW0 0xc0 +#define INTEL_GEN11_BSM_DW1 0xc4 +#define INTEL_BSM_MASK (-(1u << 20)) + +#endif /* _I915_DRM_H_ */ -- cgit v1.2.3 From cce3819a5f5a55e08e5a3c9dcd1f46a3c5276ea8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:07 +0300 Subject: drm: move i915_pxp_tee_interface.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Tomas Winkler Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5c1626978d2552ef5732dcf9427c903046afb9c1.1717075103.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 2 +- drivers/misc/mei/pxp/mei_pxp.c | 2 +- include/drm/i915_pxp_tee_interface.h | 62 ------------------------------ include/drm/intel/i915_pxp_tee_interface.h | 62 ++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 64 deletions(-) delete mode 100644 include/drm/i915_pxp_tee_interface.h create mode 100644 include/drm/intel/i915_pxp_tee_interface.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index 051b6cdcf721..1784153f0cf8 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -5,7 +5,7 @@ #include -#include +#include #include #include "gem/i915_gem_lmem.h" diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index 5a7a4d8b0e23..4268a868255f 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include "mei_pxp.h" diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/i915_pxp_tee_interface.h deleted file mode 100644 index a532d32f58f3..000000000000 --- a/include/drm/i915_pxp_tee_interface.h +++ /dev/null @@ -1,62 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2020 Intel Corporation - */ - -#ifndef _I915_PXP_TEE_INTERFACE_H_ -#define _I915_PXP_TEE_INTERFACE_H_ - -#include -#include -struct scatterlist; - -/** - * struct i915_pxp_component_ops - ops for PXP services. - */ -struct i915_pxp_component_ops { - /** - * @owner: Module providing the ops. - */ - struct module *owner; - - /** - * @send: Send a PXP message. - */ - int (*send)(struct device *dev, const void *message, size_t size, - unsigned long timeout_ms); - /** - * @recv: Receive a PXP message. - */ - int (*recv)(struct device *dev, void *buffer, size_t size, - unsigned long timeout_ms); - /** - * @gsc_command: Send a GSC command. - */ - ssize_t (*gsc_command)(struct device *dev, u8 client_id, u32 fence_id, - struct scatterlist *sg_in, size_t total_in_len, - struct scatterlist *sg_out); - -}; - -/** - * struct i915_pxp_component - Used for communication between i915 and TEE - * drivers for the PXP services - */ -struct i915_pxp_component { - /** - * @tee_dev: device that provide the PXP service from TEE Bus. - */ - struct device *tee_dev; - - /** - * @ops: Ops implemented by TEE driver, used by i915 driver. - */ - const struct i915_pxp_component_ops *ops; - - /** - * @mutex: To protect the above members. - */ - struct mutex mutex; -}; - -#endif /* _I915_TEE_PXP_INTERFACE_H_ */ diff --git a/include/drm/intel/i915_pxp_tee_interface.h b/include/drm/intel/i915_pxp_tee_interface.h new file mode 100644 index 000000000000..a532d32f58f3 --- /dev/null +++ b/include/drm/intel/i915_pxp_tee_interface.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2020 Intel Corporation + */ + +#ifndef _I915_PXP_TEE_INTERFACE_H_ +#define _I915_PXP_TEE_INTERFACE_H_ + +#include +#include +struct scatterlist; + +/** + * struct i915_pxp_component_ops - ops for PXP services. + */ +struct i915_pxp_component_ops { + /** + * @owner: Module providing the ops. + */ + struct module *owner; + + /** + * @send: Send a PXP message. + */ + int (*send)(struct device *dev, const void *message, size_t size, + unsigned long timeout_ms); + /** + * @recv: Receive a PXP message. + */ + int (*recv)(struct device *dev, void *buffer, size_t size, + unsigned long timeout_ms); + /** + * @gsc_command: Send a GSC command. + */ + ssize_t (*gsc_command)(struct device *dev, u8 client_id, u32 fence_id, + struct scatterlist *sg_in, size_t total_in_len, + struct scatterlist *sg_out); + +}; + +/** + * struct i915_pxp_component - Used for communication between i915 and TEE + * drivers for the PXP services + */ +struct i915_pxp_component { + /** + * @tee_dev: device that provide the PXP service from TEE Bus. + */ + struct device *tee_dev; + + /** + * @ops: Ops implemented by TEE driver, used by i915 driver. + */ + const struct i915_pxp_component_ops *ops; + + /** + * @mutex: To protect the above members. + */ + struct mutex mutex; +}; + +#endif /* _I915_TEE_PXP_INTERFACE_H_ */ -- cgit v1.2.3 From aef8dc4398c6c6fde0d4c746e8343a33c683cc33 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:08 +0300 Subject: drm: move i915_pciids.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Bjorn Helgaas Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/a19cebc0f03588b9627dcaaebe69a9fef28c27f0.1717075103.git.jani.nikula@intel.com --- arch/x86/kernel/early-quirks.c | 2 +- .../gpu/drm/i915/display/intel_display_device.c | 2 +- drivers/gpu/drm/i915/i915_pci.c | 2 +- drivers/gpu/drm/i915/intel_device_info.c | 2 +- include/drm/i915_pciids.h | 792 --------------------- include/drm/intel/i915_pciids.h | 792 +++++++++++++++++++++ 6 files changed, 796 insertions(+), 796 deletions(-) delete mode 100644 include/drm/i915_pciids.h create mode 100644 include/drm/intel/i915_pciids.h (limited to 'include') diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index ec1a7943c228..29d1f9104e94 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index b8b56ace7583..b35422da7f6c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -3,7 +3,7 @@ * Copyright © 2023 Intel Corporation */ -#include +#include #include #include diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 2e33b56e1cc6..7058efa75324 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "display/intel_display.h" #include "display/intel_display_driver.h" diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 862f4b705227..d26de37719a7 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include "gt/intel_gt_regs.h" #include "i915_drv.h" diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h deleted file mode 100644 index 7ae7ee11ef38..000000000000 --- a/include/drm/i915_pciids.h +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Copyright 2013 Intel Corporation - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#ifndef _I915_PCIIDS_H -#define _I915_PCIIDS_H - -/* - * A pci_device_id struct { - * __u32 vendor, device; - * __u32 subvendor, subdevice; - * __u32 class, class_mask; - * kernel_ulong_t driver_data; - * }; - * Don't use C99 here because "class" is reserved and we want to - * give userspace flexibility. - */ -#define INTEL_VGA_DEVICE(id, info) { \ - 0x8086, id, \ - ~0, ~0, \ - 0x030000, 0xff0000, \ - (unsigned long) info } - -#define INTEL_QUANTA_VGA_DEVICE(info) { \ - 0x8086, 0x16a, \ - 0x152d, 0x8990, \ - 0x030000, 0xff0000, \ - (unsigned long) info } - -#define INTEL_I810_IDS(MACRO__, ...) \ - MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \ - MACRO__(0x7123, ## __VA_ARGS__), /* I810_DC100 */ \ - MACRO__(0x7125, ## __VA_ARGS__) /* I810_E */ - -#define INTEL_I815_IDS(MACRO__, ...) \ - MACRO__(0x1132, ## __VA_ARGS__) /* I815*/ - -#define INTEL_I830_IDS(MACRO__, ...) \ - MACRO__(0x3577, ## __VA_ARGS__) - -#define INTEL_I845G_IDS(MACRO__, ...) \ - MACRO__(0x2562, ## __VA_ARGS__) - -#define INTEL_I85X_IDS(MACRO__, ...) \ - MACRO__(0x3582, ## __VA_ARGS__), /* I855_GM */ \ - MACRO__(0x358e, ## __VA_ARGS__) - -#define INTEL_I865G_IDS(MACRO__, ...) \ - MACRO__(0x2572, ## __VA_ARGS__) /* I865_G */ - -#define INTEL_I915G_IDS(MACRO__, ...) \ - MACRO__(0x2582, ## __VA_ARGS__), /* I915_G */ \ - MACRO__(0x258a, ## __VA_ARGS__) /* E7221_G */ - -#define INTEL_I915GM_IDS(MACRO__, ...) \ - MACRO__(0x2592, ## __VA_ARGS__) /* I915_GM */ - -#define INTEL_I945G_IDS(MACRO__, ...) \ - MACRO__(0x2772, ## __VA_ARGS__) /* I945_G */ - -#define INTEL_I945GM_IDS(MACRO__, ...) \ - MACRO__(0x27a2, ## __VA_ARGS__), /* I945_GM */ \ - MACRO__(0x27ae, ## __VA_ARGS__) /* I945_GME */ - -#define INTEL_I965G_IDS(MACRO__, ...) \ - MACRO__(0x2972, ## __VA_ARGS__), /* I946_GZ */ \ - MACRO__(0x2982, ## __VA_ARGS__), /* G35_G */ \ - MACRO__(0x2992, ## __VA_ARGS__), /* I965_Q */ \ - MACRO__(0x29a2, ## __VA_ARGS__) /* I965_G */ - -#define INTEL_G33_IDS(MACRO__, ...) \ - MACRO__(0x29b2, ## __VA_ARGS__), /* Q35_G */ \ - MACRO__(0x29c2, ## __VA_ARGS__), /* G33_G */ \ - MACRO__(0x29d2, ## __VA_ARGS__) /* Q33_G */ - -#define INTEL_I965GM_IDS(MACRO__, ...) \ - MACRO__(0x2a02, ## __VA_ARGS__), /* I965_GM */ \ - MACRO__(0x2a12, ## __VA_ARGS__) /* I965_GME */ - -#define INTEL_GM45_IDS(MACRO__, ...) \ - MACRO__(0x2a42, ## __VA_ARGS__) /* GM45_G */ - -#define INTEL_G45_IDS(MACRO__, ...) \ - MACRO__(0x2e02, ## __VA_ARGS__), /* IGD_E_G */ \ - MACRO__(0x2e12, ## __VA_ARGS__), /* Q45_G */ \ - MACRO__(0x2e22, ## __VA_ARGS__), /* G45_G */ \ - MACRO__(0x2e32, ## __VA_ARGS__), /* G41_G */ \ - MACRO__(0x2e42, ## __VA_ARGS__), /* B43_G */ \ - MACRO__(0x2e92, ## __VA_ARGS__) /* B43_G.1 */ - -#define INTEL_PNV_G_IDS(MACRO__, ...) \ - MACRO__(0xa001, ## __VA_ARGS__) - -#define INTEL_PNV_M_IDS(MACRO__, ...) \ - MACRO__(0xa011, ## __VA_ARGS__) - -#define INTEL_PNV_IDS(MACRO__, ...) \ - INTEL_PNV_G_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_PNV_M_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_ILK_D_IDS(MACRO__, ...) \ - MACRO__(0x0042, ## __VA_ARGS__) - -#define INTEL_ILK_M_IDS(MACRO__, ...) \ - MACRO__(0x0046, ## __VA_ARGS__) - -#define INTEL_ILK_IDS(MACRO__, ...) \ - INTEL_ILK_D_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_ILK_M_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_SNB_D_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0102, ## __VA_ARGS__), \ - MACRO__(0x010A, ## __VA_ARGS__) - -#define INTEL_SNB_D_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0112, ## __VA_ARGS__), \ - MACRO__(0x0122, ## __VA_ARGS__) - -#define INTEL_SNB_D_IDS(MACRO__, ...) \ - INTEL_SNB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SNB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_SNB_M_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0106, ## __VA_ARGS__) - -#define INTEL_SNB_M_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0116, ## __VA_ARGS__), \ - MACRO__(0x0126, ## __VA_ARGS__) - -#define INTEL_SNB_M_IDS(MACRO__, ...) \ - INTEL_SNB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SNB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_SNB_IDS(MACRO__, ...) \ - INTEL_SNB_D_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SNB_M_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_IVB_M_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0156, ## __VA_ARGS__) /* GT1 mobile */ - -#define INTEL_IVB_M_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0166, ## __VA_ARGS__) /* GT2 mobile */ - -#define INTEL_IVB_M_IDS(MACRO__, ...) \ - INTEL_IVB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_IVB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_IVB_D_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0152, ## __VA_ARGS__), /* GT1 desktop */ \ - MACRO__(0x015a, ## __VA_ARGS__) /* GT1 server */ - -#define INTEL_IVB_D_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0162, ## __VA_ARGS__), /* GT2 desktop */ \ - MACRO__(0x016a, ## __VA_ARGS__) /* GT2 server */ - -#define INTEL_IVB_D_IDS(MACRO__, ...) \ - INTEL_IVB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_IVB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_IVB_IDS(MACRO__, ...) \ - INTEL_IVB_M_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_IVB_D_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_IVB_Q_IDS(MACRO__, ...) \ - INTEL_QUANTA_VGA_DEVICE(__VA_ARGS__) /* Quanta transcode */ - -#define INTEL_HSW_ULT_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0A02, ## __VA_ARGS__), /* ULT GT1 desktop */ \ - MACRO__(0x0A06, ## __VA_ARGS__), /* ULT GT1 mobile */ \ - MACRO__(0x0A0A, ## __VA_ARGS__), /* ULT GT1 server */ \ - MACRO__(0x0A0B, ## __VA_ARGS__) /* ULT GT1 reserved */ - -#define INTEL_HSW_ULX_GT1_IDS(MACRO__, ...) \ - MACRO__(0x0A0E, ## __VA_ARGS__) /* ULX GT1 mobile */ - -#define INTEL_HSW_GT1_IDS(MACRO__, ...) \ - INTEL_HSW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_HSW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x0402, ## __VA_ARGS__), /* GT1 desktop */ \ - MACRO__(0x0406, ## __VA_ARGS__), /* GT1 mobile */ \ - MACRO__(0x040A, ## __VA_ARGS__), /* GT1 server */ \ - MACRO__(0x040B, ## __VA_ARGS__), /* GT1 reserved */ \ - MACRO__(0x040E, ## __VA_ARGS__), /* GT1 reserved */ \ - MACRO__(0x0C02, ## __VA_ARGS__), /* SDV GT1 desktop */ \ - MACRO__(0x0C06, ## __VA_ARGS__), /* SDV GT1 mobile */ \ - MACRO__(0x0C0A, ## __VA_ARGS__), /* SDV GT1 server */ \ - MACRO__(0x0C0B, ## __VA_ARGS__), /* SDV GT1 reserved */ \ - MACRO__(0x0C0E, ## __VA_ARGS__), /* SDV GT1 reserved */ \ - MACRO__(0x0D02, ## __VA_ARGS__), /* CRW GT1 desktop */ \ - MACRO__(0x0D06, ## __VA_ARGS__), /* CRW GT1 mobile */ \ - MACRO__(0x0D0A, ## __VA_ARGS__), /* CRW GT1 server */ \ - MACRO__(0x0D0B, ## __VA_ARGS__), /* CRW GT1 reserved */ \ - MACRO__(0x0D0E, ## __VA_ARGS__) /* CRW GT1 reserved */ - -#define INTEL_HSW_ULT_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0A12, ## __VA_ARGS__), /* ULT GT2 desktop */ \ - MACRO__(0x0A16, ## __VA_ARGS__), /* ULT GT2 mobile */ \ - MACRO__(0x0A1A, ## __VA_ARGS__), /* ULT GT2 server */ \ - MACRO__(0x0A1B, ## __VA_ARGS__) /* ULT GT2 reserved */ \ - -#define INTEL_HSW_ULX_GT2_IDS(MACRO__, ...) \ - MACRO__(0x0A1E, ## __VA_ARGS__) /* ULX GT2 mobile */ \ - -#define INTEL_HSW_GT2_IDS(MACRO__, ...) \ - INTEL_HSW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_HSW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x0412, ## __VA_ARGS__), /* GT2 desktop */ \ - MACRO__(0x0416, ## __VA_ARGS__), /* GT2 mobile */ \ - MACRO__(0x041A, ## __VA_ARGS__), /* GT2 server */ \ - MACRO__(0x041B, ## __VA_ARGS__), /* GT2 reserved */ \ - MACRO__(0x041E, ## __VA_ARGS__), /* GT2 reserved */ \ - MACRO__(0x0C12, ## __VA_ARGS__), /* SDV GT2 desktop */ \ - MACRO__(0x0C16, ## __VA_ARGS__), /* SDV GT2 mobile */ \ - MACRO__(0x0C1A, ## __VA_ARGS__), /* SDV GT2 server */ \ - MACRO__(0x0C1B, ## __VA_ARGS__), /* SDV GT2 reserved */ \ - MACRO__(0x0C1E, ## __VA_ARGS__), /* SDV GT2 reserved */ \ - MACRO__(0x0D12, ## __VA_ARGS__), /* CRW GT2 desktop */ \ - MACRO__(0x0D16, ## __VA_ARGS__), /* CRW GT2 mobile */ \ - MACRO__(0x0D1A, ## __VA_ARGS__), /* CRW GT2 server */ \ - MACRO__(0x0D1B, ## __VA_ARGS__), /* CRW GT2 reserved */ \ - MACRO__(0x0D1E, ## __VA_ARGS__) /* CRW GT2 reserved */ - -#define INTEL_HSW_ULT_GT3_IDS(MACRO__, ...) \ - MACRO__(0x0A22, ## __VA_ARGS__), /* ULT GT3 desktop */ \ - MACRO__(0x0A26, ## __VA_ARGS__), /* ULT GT3 mobile */ \ - MACRO__(0x0A2A, ## __VA_ARGS__), /* ULT GT3 server */ \ - MACRO__(0x0A2B, ## __VA_ARGS__), /* ULT GT3 reserved */ \ - MACRO__(0x0A2E, ## __VA_ARGS__) /* ULT GT3 reserved */ - -#define INTEL_HSW_GT3_IDS(MACRO__, ...) \ - INTEL_HSW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x0422, ## __VA_ARGS__), /* GT3 desktop */ \ - MACRO__(0x0426, ## __VA_ARGS__), /* GT3 mobile */ \ - MACRO__(0x042A, ## __VA_ARGS__), /* GT3 server */ \ - MACRO__(0x042B, ## __VA_ARGS__), /* GT3 reserved */ \ - MACRO__(0x042E, ## __VA_ARGS__), /* GT3 reserved */ \ - MACRO__(0x0C22, ## __VA_ARGS__), /* SDV GT3 desktop */ \ - MACRO__(0x0C26, ## __VA_ARGS__), /* SDV GT3 mobile */ \ - MACRO__(0x0C2A, ## __VA_ARGS__), /* SDV GT3 server */ \ - MACRO__(0x0C2B, ## __VA_ARGS__), /* SDV GT3 reserved */ \ - MACRO__(0x0C2E, ## __VA_ARGS__), /* SDV GT3 reserved */ \ - MACRO__(0x0D22, ## __VA_ARGS__), /* CRW GT3 desktop */ \ - MACRO__(0x0D26, ## __VA_ARGS__), /* CRW GT3 mobile */ \ - MACRO__(0x0D2A, ## __VA_ARGS__), /* CRW GT3 server */ \ - MACRO__(0x0D2B, ## __VA_ARGS__), /* CRW GT3 reserved */ \ - MACRO__(0x0D2E, ## __VA_ARGS__) /* CRW GT3 reserved */ - -#define INTEL_HSW_IDS(MACRO__, ...) \ - INTEL_HSW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_HSW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_HSW_GT3_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_VLV_IDS(MACRO__, ...) \ - MACRO__(0x0f30, ## __VA_ARGS__), \ - MACRO__(0x0f31, ## __VA_ARGS__), \ - MACRO__(0x0f32, ## __VA_ARGS__), \ - MACRO__(0x0f33, ## __VA_ARGS__) - -#define INTEL_BDW_ULT_GT1_IDS(MACRO__, ...) \ - MACRO__(0x1606, ## __VA_ARGS__), /* GT1 ULT */ \ - MACRO__(0x160B, ## __VA_ARGS__) /* GT1 Iris */ - -#define INTEL_BDW_ULX_GT1_IDS(MACRO__, ...) \ - MACRO__(0x160E, ## __VA_ARGS__) /* GT1 ULX */ - -#define INTEL_BDW_GT1_IDS(MACRO__, ...) \ - INTEL_BDW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1602, ## __VA_ARGS__), /* GT1 ULT */ \ - MACRO__(0x160A, ## __VA_ARGS__), /* GT1 Server */ \ - MACRO__(0x160D, ## __VA_ARGS__) /* GT1 Workstation */ - -#define INTEL_BDW_ULT_GT2_IDS(MACRO__, ...) \ - MACRO__(0x1616, ## __VA_ARGS__), /* GT2 ULT */ \ - MACRO__(0x161B, ## __VA_ARGS__) /* GT2 ULT */ - -#define INTEL_BDW_ULX_GT2_IDS(MACRO__, ...) \ - MACRO__(0x161E, ## __VA_ARGS__) /* GT2 ULX */ - -#define INTEL_BDW_GT2_IDS(MACRO__, ...) \ - INTEL_BDW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1612, ## __VA_ARGS__), /* GT2 Halo */ \ - MACRO__(0x161A, ## __VA_ARGS__), /* GT2 Server */ \ - MACRO__(0x161D, ## __VA_ARGS__) /* GT2 Workstation */ - -#define INTEL_BDW_ULT_GT3_IDS(MACRO__, ...) \ - MACRO__(0x1626, ## __VA_ARGS__), /* ULT */ \ - MACRO__(0x162B, ## __VA_ARGS__) /* Iris */ \ - -#define INTEL_BDW_ULX_GT3_IDS(MACRO__, ...) \ - MACRO__(0x162E, ## __VA_ARGS__) /* ULX */ - -#define INTEL_BDW_GT3_IDS(MACRO__, ...) \ - INTEL_BDW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_ULX_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1622, ## __VA_ARGS__), /* ULT */ \ - MACRO__(0x162A, ## __VA_ARGS__), /* Server */ \ - MACRO__(0x162D, ## __VA_ARGS__) /* Workstation */ - -#define INTEL_BDW_ULT_RSVD_IDS(MACRO__, ...) \ - MACRO__(0x1636, ## __VA_ARGS__), /* ULT */ \ - MACRO__(0x163B, ## __VA_ARGS__) /* Iris */ - -#define INTEL_BDW_ULX_RSVD_IDS(MACRO__, ...) \ - MACRO__(0x163E, ## __VA_ARGS__) /* ULX */ - -#define INTEL_BDW_RSVD_IDS(MACRO__, ...) \ - INTEL_BDW_ULT_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_ULX_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1632, ## __VA_ARGS__), /* ULT */ \ - MACRO__(0x163A, ## __VA_ARGS__), /* Server */ \ - MACRO__(0x163D, ## __VA_ARGS__) /* Workstation */ - -#define INTEL_BDW_IDS(MACRO__, ...) \ - INTEL_BDW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_BDW_RSVD_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_CHV_IDS(MACRO__, ...) \ - MACRO__(0x22b0, ## __VA_ARGS__), \ - MACRO__(0x22b1, ## __VA_ARGS__), \ - MACRO__(0x22b2, ## __VA_ARGS__), \ - MACRO__(0x22b3, ## __VA_ARGS__) - -#define INTEL_SKL_ULT_GT1_IDS(MACRO__, ...) \ - MACRO__(0x1906, ## __VA_ARGS__), /* ULT GT1 */ \ - MACRO__(0x1913, ## __VA_ARGS__) /* ULT GT1.5 */ - -#define INTEL_SKL_ULX_GT1_IDS(MACRO__, ...) \ - MACRO__(0x190E, ## __VA_ARGS__), /* ULX GT1 */ \ - MACRO__(0x1915, ## __VA_ARGS__) /* ULX GT1.5 */ - -#define INTEL_SKL_GT1_IDS(MACRO__, ...) \ - INTEL_SKL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SKL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1902, ## __VA_ARGS__), /* DT GT1 */ \ - MACRO__(0x190A, ## __VA_ARGS__), /* SRV GT1 */ \ - MACRO__(0x190B, ## __VA_ARGS__), /* Halo GT1 */ \ - MACRO__(0x1917, ## __VA_ARGS__) /* DT GT1.5 */ - -#define INTEL_SKL_ULT_GT2_IDS(MACRO__, ...) \ - MACRO__(0x1916, ## __VA_ARGS__), /* ULT GT2 */ \ - MACRO__(0x1921, ## __VA_ARGS__) /* ULT GT2F */ - -#define INTEL_SKL_ULX_GT2_IDS(MACRO__, ...) \ - MACRO__(0x191E, ## __VA_ARGS__) /* ULX GT2 */ - -#define INTEL_SKL_GT2_IDS(MACRO__, ...) \ - INTEL_SKL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SKL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x1912, ## __VA_ARGS__), /* DT GT2 */ \ - MACRO__(0x191A, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x191B, ## __VA_ARGS__), /* Halo GT2 */ \ - MACRO__(0x191D, ## __VA_ARGS__) /* WKS GT2 */ - -#define INTEL_SKL_ULT_GT3_IDS(MACRO__, ...) \ - MACRO__(0x1923, ## __VA_ARGS__), /* ULT GT3 */ \ - MACRO__(0x1926, ## __VA_ARGS__), /* ULT GT3e */ \ - MACRO__(0x1927, ## __VA_ARGS__) /* ULT GT3e */ - -#define INTEL_SKL_GT3_IDS(MACRO__, ...) \ - INTEL_SKL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x192A, ## __VA_ARGS__), /* SRV GT3 */ \ - MACRO__(0x192B, ## __VA_ARGS__), /* Halo GT3e */ \ - MACRO__(0x192D, ## __VA_ARGS__) /* SRV GT3e */ - -#define INTEL_SKL_GT4_IDS(MACRO__, ...) \ - MACRO__(0x1932, ## __VA_ARGS__), /* DT GT4 */ \ - MACRO__(0x193A, ## __VA_ARGS__), /* SRV GT4e */ \ - MACRO__(0x193B, ## __VA_ARGS__), /* Halo GT4e */ \ - MACRO__(0x193D, ## __VA_ARGS__) /* WKS GT4e */ - -#define INTEL_SKL_IDS(MACRO__, ...) \ - INTEL_SKL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SKL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SKL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_SKL_GT4_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_BXT_IDS(MACRO__, ...) \ - MACRO__(0x0A84, ## __VA_ARGS__), \ - MACRO__(0x1A84, ## __VA_ARGS__), \ - MACRO__(0x1A85, ## __VA_ARGS__), \ - MACRO__(0x5A84, ## __VA_ARGS__), /* APL HD Graphics 505 */ \ - MACRO__(0x5A85, ## __VA_ARGS__) /* APL HD Graphics 500 */ - -#define INTEL_GLK_IDS(MACRO__, ...) \ - MACRO__(0x3184, ## __VA_ARGS__), \ - MACRO__(0x3185, ## __VA_ARGS__) - -#define INTEL_KBL_ULT_GT1_IDS(MACRO__, ...) \ - MACRO__(0x5906, ## __VA_ARGS__), /* ULT GT1 */ \ - MACRO__(0x5913, ## __VA_ARGS__) /* ULT GT1.5 */ - -#define INTEL_KBL_ULX_GT1_IDS(MACRO__, ...) \ - MACRO__(0x590E, ## __VA_ARGS__), /* ULX GT1 */ \ - MACRO__(0x5915, ## __VA_ARGS__) /* ULX GT1.5 */ - -#define INTEL_KBL_GT1_IDS(MACRO__, ...) \ - INTEL_KBL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_KBL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x5902, ## __VA_ARGS__), /* DT GT1 */ \ - MACRO__(0x5908, ## __VA_ARGS__), /* Halo GT1 */ \ - MACRO__(0x590A, ## __VA_ARGS__), /* SRV GT1 */ \ - MACRO__(0x590B, ## __VA_ARGS__) /* Halo GT1 */ - -#define INTEL_KBL_ULT_GT2_IDS(MACRO__, ...) \ - MACRO__(0x5916, ## __VA_ARGS__), /* ULT GT2 */ \ - MACRO__(0x5921, ## __VA_ARGS__) /* ULT GT2F */ - -#define INTEL_KBL_ULX_GT2_IDS(MACRO__, ...) \ - MACRO__(0x591E, ## __VA_ARGS__) /* ULX GT2 */ - -#define INTEL_KBL_GT2_IDS(MACRO__, ...) \ - INTEL_KBL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_KBL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x5912, ## __VA_ARGS__), /* DT GT2 */ \ - MACRO__(0x5917, ## __VA_ARGS__), /* Mobile GT2 */ \ - MACRO__(0x591A, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x591B, ## __VA_ARGS__), /* Halo GT2 */ \ - MACRO__(0x591D, ## __VA_ARGS__) /* WKS GT2 */ - -#define INTEL_KBL_ULT_GT3_IDS(MACRO__, ...) \ - MACRO__(0x5926, ## __VA_ARGS__) /* ULT GT3 */ - -#define INTEL_KBL_GT3_IDS(MACRO__, ...) \ - INTEL_KBL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x5923, ## __VA_ARGS__), /* ULT GT3 */ \ - MACRO__(0x5927, ## __VA_ARGS__) /* ULT GT3 */ - -#define INTEL_KBL_GT4_IDS(MACRO__, ...) \ - MACRO__(0x593B, ## __VA_ARGS__) /* Halo GT4 */ - -/* AML/KBL Y GT2 */ -#define INTEL_AML_KBL_GT2_IDS(MACRO__, ...) \ - MACRO__(0x591C, ## __VA_ARGS__), /* ULX GT2 */ \ - MACRO__(0x87C0, ## __VA_ARGS__) /* ULX GT2 */ - -/* AML/CFL Y GT2 */ -#define INTEL_AML_CFL_GT2_IDS(MACRO__, ...) \ - MACRO__(0x87CA, ## __VA_ARGS__) - -/* CML GT1 */ -#define INTEL_CML_GT1_IDS(MACRO__, ...) \ - MACRO__(0x9BA2, ## __VA_ARGS__), \ - MACRO__(0x9BA4, ## __VA_ARGS__), \ - MACRO__(0x9BA5, ## __VA_ARGS__), \ - MACRO__(0x9BA8, ## __VA_ARGS__) - -#define INTEL_CML_U_GT1_IDS(MACRO__, ...) \ - MACRO__(0x9B21, ## __VA_ARGS__), \ - MACRO__(0x9BAA, ## __VA_ARGS__), \ - MACRO__(0x9BAC, ## __VA_ARGS__) - -/* CML GT2 */ -#define INTEL_CML_GT2_IDS(MACRO__, ...) \ - MACRO__(0x9BC2, ## __VA_ARGS__), \ - MACRO__(0x9BC4, ## __VA_ARGS__), \ - MACRO__(0x9BC5, ## __VA_ARGS__), \ - MACRO__(0x9BC6, ## __VA_ARGS__), \ - MACRO__(0x9BC8, ## __VA_ARGS__), \ - MACRO__(0x9BE6, ## __VA_ARGS__), \ - MACRO__(0x9BF6, ## __VA_ARGS__) - -#define INTEL_CML_U_GT2_IDS(MACRO__, ...) \ - MACRO__(0x9B41, ## __VA_ARGS__), \ - MACRO__(0x9BCA, ## __VA_ARGS__), \ - MACRO__(0x9BCC, ## __VA_ARGS__) - -#define INTEL_CML_IDS(MACRO__, ...) \ - INTEL_CML_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CML_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CML_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CML_U_GT2_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_KBL_IDS(MACRO__, ...) \ - INTEL_KBL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_KBL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_KBL_GT4_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_AML_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__) - -/* CFL S */ -#define INTEL_CFL_S_GT1_IDS(MACRO__, ...) \ - MACRO__(0x3E90, ## __VA_ARGS__), /* SRV GT1 */ \ - MACRO__(0x3E93, ## __VA_ARGS__), /* SRV GT1 */ \ - MACRO__(0x3E99, ## __VA_ARGS__) /* SRV GT1 */ - -#define INTEL_CFL_S_GT2_IDS(MACRO__, ...) \ - MACRO__(0x3E91, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x3E92, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x3E96, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x3E98, ## __VA_ARGS__), /* SRV GT2 */ \ - MACRO__(0x3E9A, ## __VA_ARGS__) /* SRV GT2 */ - -/* CFL H */ -#define INTEL_CFL_H_GT1_IDS(MACRO__, ...) \ - MACRO__(0x3E9C, ## __VA_ARGS__) - -#define INTEL_CFL_H_GT2_IDS(MACRO__, ...) \ - MACRO__(0x3E94, ## __VA_ARGS__), /* Halo GT2 */ \ - MACRO__(0x3E9B, ## __VA_ARGS__) /* Halo GT2 */ - -/* CFL U GT2 */ -#define INTEL_CFL_U_GT2_IDS(MACRO__, ...) \ - MACRO__(0x3EA9, ## __VA_ARGS__) - -/* CFL U GT3 */ -#define INTEL_CFL_U_GT3_IDS(MACRO__, ...) \ - MACRO__(0x3EA5, ## __VA_ARGS__), /* ULT GT3 */ \ - MACRO__(0x3EA6, ## __VA_ARGS__), /* ULT GT3 */ \ - MACRO__(0x3EA7, ## __VA_ARGS__), /* ULT GT3 */ \ - MACRO__(0x3EA8, ## __VA_ARGS__) /* ULT GT3 */ - -#define INTEL_CFL_IDS(MACRO__, ...) \ - INTEL_CFL_S_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CFL_S_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CFL_H_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CFL_H_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CFL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_CFL_U_GT3_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_AML_CFL_GT2_IDS(MACRO__, ## __VA_ARGS__) - -/* WHL/CFL U GT1 */ -#define INTEL_WHL_U_GT1_IDS(MACRO__, ...) \ - MACRO__(0x3EA1, ## __VA_ARGS__), \ - MACRO__(0x3EA4, ## __VA_ARGS__) - -/* WHL/CFL U GT2 */ -#define INTEL_WHL_U_GT2_IDS(MACRO__, ...) \ - MACRO__(0x3EA0, ## __VA_ARGS__), \ - MACRO__(0x3EA3, ## __VA_ARGS__) - -/* WHL/CFL U GT3 */ -#define INTEL_WHL_U_GT3_IDS(MACRO__, ...) \ - MACRO__(0x3EA2, ## __VA_ARGS__) - -#define INTEL_WHL_IDS(MACRO__, ...) \ - INTEL_WHL_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_WHL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_WHL_U_GT3_IDS(MACRO__, ## __VA_ARGS__) - -/* CNL */ -#define INTEL_CNL_PORT_F_IDS(MACRO__, ...) \ - MACRO__(0x5A44, ## __VA_ARGS__), \ - MACRO__(0x5A4C, ## __VA_ARGS__), \ - MACRO__(0x5A54, ## __VA_ARGS__), \ - MACRO__(0x5A5C, ## __VA_ARGS__) - -#define INTEL_CNL_IDS(MACRO__, ...) \ - INTEL_CNL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x5A40, ## __VA_ARGS__), \ - MACRO__(0x5A41, ## __VA_ARGS__), \ - MACRO__(0x5A42, ## __VA_ARGS__), \ - MACRO__(0x5A49, ## __VA_ARGS__), \ - MACRO__(0x5A4A, ## __VA_ARGS__), \ - MACRO__(0x5A50, ## __VA_ARGS__), \ - MACRO__(0x5A51, ## __VA_ARGS__), \ - MACRO__(0x5A52, ## __VA_ARGS__), \ - MACRO__(0x5A59, ## __VA_ARGS__), \ - MACRO__(0x5A5A, ## __VA_ARGS__) - -/* ICL */ -#define INTEL_ICL_PORT_F_IDS(MACRO__, ...) \ - MACRO__(0x8A50, ## __VA_ARGS__), \ - MACRO__(0x8A52, ## __VA_ARGS__), \ - MACRO__(0x8A53, ## __VA_ARGS__), \ - MACRO__(0x8A54, ## __VA_ARGS__), \ - MACRO__(0x8A56, ## __VA_ARGS__), \ - MACRO__(0x8A57, ## __VA_ARGS__), \ - MACRO__(0x8A58, ## __VA_ARGS__), \ - MACRO__(0x8A59, ## __VA_ARGS__), \ - MACRO__(0x8A5A, ## __VA_ARGS__), \ - MACRO__(0x8A5B, ## __VA_ARGS__), \ - MACRO__(0x8A5C, ## __VA_ARGS__), \ - MACRO__(0x8A70, ## __VA_ARGS__), \ - MACRO__(0x8A71, ## __VA_ARGS__) - -#define INTEL_ICL_IDS(MACRO__, ...) \ - INTEL_ICL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0x8A51, ## __VA_ARGS__), \ - MACRO__(0x8A5D, ## __VA_ARGS__) - -/* EHL */ -#define INTEL_EHL_IDS(MACRO__, ...) \ - MACRO__(0x4541, ## __VA_ARGS__), \ - MACRO__(0x4551, ## __VA_ARGS__), \ - MACRO__(0x4555, ## __VA_ARGS__), \ - MACRO__(0x4557, ## __VA_ARGS__), \ - MACRO__(0x4570, ## __VA_ARGS__), \ - MACRO__(0x4571, ## __VA_ARGS__) - -/* JSL */ -#define INTEL_JSL_IDS(MACRO__, ...) \ - MACRO__(0x4E51, ## __VA_ARGS__), \ - MACRO__(0x4E55, ## __VA_ARGS__), \ - MACRO__(0x4E57, ## __VA_ARGS__), \ - MACRO__(0x4E61, ## __VA_ARGS__), \ - MACRO__(0x4E71, ## __VA_ARGS__) - -/* TGL */ -#define INTEL_TGL_GT1_IDS(MACRO__, ...) \ - MACRO__(0x9A60, ## __VA_ARGS__), \ - MACRO__(0x9A68, ## __VA_ARGS__), \ - MACRO__(0x9A70, ## __VA_ARGS__) - -#define INTEL_TGL_GT2_IDS(MACRO__, ...) \ - MACRO__(0x9A40, ## __VA_ARGS__), \ - MACRO__(0x9A49, ## __VA_ARGS__), \ - MACRO__(0x9A59, ## __VA_ARGS__), \ - MACRO__(0x9A78, ## __VA_ARGS__), \ - MACRO__(0x9AC0, ## __VA_ARGS__), \ - MACRO__(0x9AC9, ## __VA_ARGS__), \ - MACRO__(0x9AD9, ## __VA_ARGS__), \ - MACRO__(0x9AF8, ## __VA_ARGS__) - -#define INTEL_TGL_IDS(MACRO__, ...) \ - INTEL_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__) - -/* RKL */ -#define INTEL_RKL_IDS(MACRO__, ...) \ - MACRO__(0x4C80, ## __VA_ARGS__), \ - MACRO__(0x4C8A, ## __VA_ARGS__), \ - MACRO__(0x4C8B, ## __VA_ARGS__), \ - MACRO__(0x4C8C, ## __VA_ARGS__), \ - MACRO__(0x4C90, ## __VA_ARGS__), \ - MACRO__(0x4C9A, ## __VA_ARGS__) - -/* DG1 */ -#define INTEL_DG1_IDS(MACRO__, ...) \ - MACRO__(0x4905, ## __VA_ARGS__), \ - MACRO__(0x4906, ## __VA_ARGS__), \ - MACRO__(0x4907, ## __VA_ARGS__), \ - MACRO__(0x4908, ## __VA_ARGS__), \ - MACRO__(0x4909, ## __VA_ARGS__) - -/* ADL-S */ -#define INTEL_ADLS_IDS(MACRO__, ...) \ - MACRO__(0x4680, ## __VA_ARGS__), \ - MACRO__(0x4682, ## __VA_ARGS__), \ - MACRO__(0x4688, ## __VA_ARGS__), \ - MACRO__(0x468A, ## __VA_ARGS__), \ - MACRO__(0x468B, ## __VA_ARGS__), \ - MACRO__(0x4690, ## __VA_ARGS__), \ - MACRO__(0x4692, ## __VA_ARGS__), \ - MACRO__(0x4693, ## __VA_ARGS__) - -/* ADL-P */ -#define INTEL_ADLP_IDS(MACRO__, ...) \ - MACRO__(0x46A0, ## __VA_ARGS__), \ - MACRO__(0x46A1, ## __VA_ARGS__), \ - MACRO__(0x46A2, ## __VA_ARGS__), \ - MACRO__(0x46A3, ## __VA_ARGS__), \ - MACRO__(0x46A6, ## __VA_ARGS__), \ - MACRO__(0x46A8, ## __VA_ARGS__), \ - MACRO__(0x46AA, ## __VA_ARGS__), \ - MACRO__(0x462A, ## __VA_ARGS__), \ - MACRO__(0x4626, ## __VA_ARGS__), \ - MACRO__(0x4628, ## __VA_ARGS__), \ - MACRO__(0x46B0, ## __VA_ARGS__), \ - MACRO__(0x46B1, ## __VA_ARGS__), \ - MACRO__(0x46B2, ## __VA_ARGS__), \ - MACRO__(0x46B3, ## __VA_ARGS__), \ - MACRO__(0x46C0, ## __VA_ARGS__), \ - MACRO__(0x46C1, ## __VA_ARGS__), \ - MACRO__(0x46C2, ## __VA_ARGS__), \ - MACRO__(0x46C3, ## __VA_ARGS__) - -/* ADL-N */ -#define INTEL_ADLN_IDS(MACRO__, ...) \ - MACRO__(0x46D0, ## __VA_ARGS__), \ - MACRO__(0x46D1, ## __VA_ARGS__), \ - MACRO__(0x46D2, ## __VA_ARGS__), \ - MACRO__(0x46D3, ## __VA_ARGS__), \ - MACRO__(0x46D4, ## __VA_ARGS__) - -/* RPL-S */ -#define INTEL_RPLS_IDS(MACRO__, ...) \ - MACRO__(0xA780, ## __VA_ARGS__), \ - MACRO__(0xA781, ## __VA_ARGS__), \ - MACRO__(0xA782, ## __VA_ARGS__), \ - MACRO__(0xA783, ## __VA_ARGS__), \ - MACRO__(0xA788, ## __VA_ARGS__), \ - MACRO__(0xA789, ## __VA_ARGS__), \ - MACRO__(0xA78A, ## __VA_ARGS__), \ - MACRO__(0xA78B, ## __VA_ARGS__) - -/* RPL-U */ -#define INTEL_RPLU_IDS(MACRO__, ...) \ - MACRO__(0xA721, ## __VA_ARGS__), \ - MACRO__(0xA7A1, ## __VA_ARGS__), \ - MACRO__(0xA7A9, ## __VA_ARGS__), \ - MACRO__(0xA7AC, ## __VA_ARGS__), \ - MACRO__(0xA7AD, ## __VA_ARGS__) - -/* RPL-P */ -#define INTEL_RPLP_IDS(MACRO__, ...) \ - MACRO__(0xA720, ## __VA_ARGS__), \ - MACRO__(0xA7A0, ## __VA_ARGS__), \ - MACRO__(0xA7A8, ## __VA_ARGS__), \ - MACRO__(0xA7AA, ## __VA_ARGS__), \ - MACRO__(0xA7AB, ## __VA_ARGS__) - -/* DG2 */ -#define INTEL_DG2_G10_IDS(MACRO__, ...) \ - MACRO__(0x5690, ## __VA_ARGS__), \ - MACRO__(0x5691, ## __VA_ARGS__), \ - MACRO__(0x5692, ## __VA_ARGS__), \ - MACRO__(0x56A0, ## __VA_ARGS__), \ - MACRO__(0x56A1, ## __VA_ARGS__), \ - MACRO__(0x56A2, ## __VA_ARGS__), \ - MACRO__(0x56BE, ## __VA_ARGS__), \ - MACRO__(0x56BF, ## __VA_ARGS__) - -#define INTEL_DG2_G11_IDS(MACRO__, ...) \ - MACRO__(0x5693, ## __VA_ARGS__), \ - MACRO__(0x5694, ## __VA_ARGS__), \ - MACRO__(0x5695, ## __VA_ARGS__), \ - MACRO__(0x56A5, ## __VA_ARGS__), \ - MACRO__(0x56A6, ## __VA_ARGS__), \ - MACRO__(0x56B0, ## __VA_ARGS__), \ - MACRO__(0x56B1, ## __VA_ARGS__), \ - MACRO__(0x56BA, ## __VA_ARGS__), \ - MACRO__(0x56BB, ## __VA_ARGS__), \ - MACRO__(0x56BC, ## __VA_ARGS__), \ - MACRO__(0x56BD, ## __VA_ARGS__) - -#define INTEL_DG2_G12_IDS(MACRO__, ...) \ - MACRO__(0x5696, ## __VA_ARGS__), \ - MACRO__(0x5697, ## __VA_ARGS__), \ - MACRO__(0x56A3, ## __VA_ARGS__), \ - MACRO__(0x56A4, ## __VA_ARGS__), \ - MACRO__(0x56B2, ## __VA_ARGS__), \ - MACRO__(0x56B3, ## __VA_ARGS__) - -#define INTEL_DG2_IDS(MACRO__, ...) \ - INTEL_DG2_G10_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_DG2_G11_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_DG2_G12_IDS(MACRO__, ## __VA_ARGS__) - -#define INTEL_ATS_M150_IDS(MACRO__, ...) \ - MACRO__(0x56C0, ## __VA_ARGS__), \ - MACRO__(0x56C2, ## __VA_ARGS__) - -#define INTEL_ATS_M75_IDS(MACRO__, ...) \ - MACRO__(0x56C1, ## __VA_ARGS__) - -#define INTEL_ATS_M_IDS(MACRO__, ...) \ - INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \ - INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) - -/* MTL */ -#define INTEL_MTL_IDS(MACRO__, ...) \ - MACRO__(0x7D40, ## __VA_ARGS__), \ - MACRO__(0x7D41, ## __VA_ARGS__), \ - MACRO__(0x7D45, ## __VA_ARGS__), \ - MACRO__(0x7D51, ## __VA_ARGS__), \ - MACRO__(0x7D55, ## __VA_ARGS__), \ - MACRO__(0x7D60, ## __VA_ARGS__), \ - MACRO__(0x7D67, ## __VA_ARGS__), \ - MACRO__(0x7DD1, ## __VA_ARGS__), \ - MACRO__(0x7DD5, ## __VA_ARGS__) - -/* LNL */ -#define INTEL_LNL_IDS(MACRO__, ...) \ - MACRO__(0x6420, ## __VA_ARGS__), \ - MACRO__(0x64A0, ## __VA_ARGS__), \ - MACRO__(0x64B0, ## __VA_ARGS__) - -#endif /* _I915_PCIIDS_H */ diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h new file mode 100644 index 000000000000..7ae7ee11ef38 --- /dev/null +++ b/include/drm/intel/i915_pciids.h @@ -0,0 +1,792 @@ +/* + * Copyright 2013 Intel Corporation + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _I915_PCIIDS_H +#define _I915_PCIIDS_H + +/* + * A pci_device_id struct { + * __u32 vendor, device; + * __u32 subvendor, subdevice; + * __u32 class, class_mask; + * kernel_ulong_t driver_data; + * }; + * Don't use C99 here because "class" is reserved and we want to + * give userspace flexibility. + */ +#define INTEL_VGA_DEVICE(id, info) { \ + 0x8086, id, \ + ~0, ~0, \ + 0x030000, 0xff0000, \ + (unsigned long) info } + +#define INTEL_QUANTA_VGA_DEVICE(info) { \ + 0x8086, 0x16a, \ + 0x152d, 0x8990, \ + 0x030000, 0xff0000, \ + (unsigned long) info } + +#define INTEL_I810_IDS(MACRO__, ...) \ + MACRO__(0x7121, ## __VA_ARGS__), /* I810 */ \ + MACRO__(0x7123, ## __VA_ARGS__), /* I810_DC100 */ \ + MACRO__(0x7125, ## __VA_ARGS__) /* I810_E */ + +#define INTEL_I815_IDS(MACRO__, ...) \ + MACRO__(0x1132, ## __VA_ARGS__) /* I815*/ + +#define INTEL_I830_IDS(MACRO__, ...) \ + MACRO__(0x3577, ## __VA_ARGS__) + +#define INTEL_I845G_IDS(MACRO__, ...) \ + MACRO__(0x2562, ## __VA_ARGS__) + +#define INTEL_I85X_IDS(MACRO__, ...) \ + MACRO__(0x3582, ## __VA_ARGS__), /* I855_GM */ \ + MACRO__(0x358e, ## __VA_ARGS__) + +#define INTEL_I865G_IDS(MACRO__, ...) \ + MACRO__(0x2572, ## __VA_ARGS__) /* I865_G */ + +#define INTEL_I915G_IDS(MACRO__, ...) \ + MACRO__(0x2582, ## __VA_ARGS__), /* I915_G */ \ + MACRO__(0x258a, ## __VA_ARGS__) /* E7221_G */ + +#define INTEL_I915GM_IDS(MACRO__, ...) \ + MACRO__(0x2592, ## __VA_ARGS__) /* I915_GM */ + +#define INTEL_I945G_IDS(MACRO__, ...) \ + MACRO__(0x2772, ## __VA_ARGS__) /* I945_G */ + +#define INTEL_I945GM_IDS(MACRO__, ...) \ + MACRO__(0x27a2, ## __VA_ARGS__), /* I945_GM */ \ + MACRO__(0x27ae, ## __VA_ARGS__) /* I945_GME */ + +#define INTEL_I965G_IDS(MACRO__, ...) \ + MACRO__(0x2972, ## __VA_ARGS__), /* I946_GZ */ \ + MACRO__(0x2982, ## __VA_ARGS__), /* G35_G */ \ + MACRO__(0x2992, ## __VA_ARGS__), /* I965_Q */ \ + MACRO__(0x29a2, ## __VA_ARGS__) /* I965_G */ + +#define INTEL_G33_IDS(MACRO__, ...) \ + MACRO__(0x29b2, ## __VA_ARGS__), /* Q35_G */ \ + MACRO__(0x29c2, ## __VA_ARGS__), /* G33_G */ \ + MACRO__(0x29d2, ## __VA_ARGS__) /* Q33_G */ + +#define INTEL_I965GM_IDS(MACRO__, ...) \ + MACRO__(0x2a02, ## __VA_ARGS__), /* I965_GM */ \ + MACRO__(0x2a12, ## __VA_ARGS__) /* I965_GME */ + +#define INTEL_GM45_IDS(MACRO__, ...) \ + MACRO__(0x2a42, ## __VA_ARGS__) /* GM45_G */ + +#define INTEL_G45_IDS(MACRO__, ...) \ + MACRO__(0x2e02, ## __VA_ARGS__), /* IGD_E_G */ \ + MACRO__(0x2e12, ## __VA_ARGS__), /* Q45_G */ \ + MACRO__(0x2e22, ## __VA_ARGS__), /* G45_G */ \ + MACRO__(0x2e32, ## __VA_ARGS__), /* G41_G */ \ + MACRO__(0x2e42, ## __VA_ARGS__), /* B43_G */ \ + MACRO__(0x2e92, ## __VA_ARGS__) /* B43_G.1 */ + +#define INTEL_PNV_G_IDS(MACRO__, ...) \ + MACRO__(0xa001, ## __VA_ARGS__) + +#define INTEL_PNV_M_IDS(MACRO__, ...) \ + MACRO__(0xa011, ## __VA_ARGS__) + +#define INTEL_PNV_IDS(MACRO__, ...) \ + INTEL_PNV_G_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_PNV_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_ILK_D_IDS(MACRO__, ...) \ + MACRO__(0x0042, ## __VA_ARGS__) + +#define INTEL_ILK_M_IDS(MACRO__, ...) \ + MACRO__(0x0046, ## __VA_ARGS__) + +#define INTEL_ILK_IDS(MACRO__, ...) \ + INTEL_ILK_D_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_ILK_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_D_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0102, ## __VA_ARGS__), \ + MACRO__(0x010A, ## __VA_ARGS__) + +#define INTEL_SNB_D_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0112, ## __VA_ARGS__), \ + MACRO__(0x0122, ## __VA_ARGS__) + +#define INTEL_SNB_D_IDS(MACRO__, ...) \ + INTEL_SNB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_M_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0106, ## __VA_ARGS__) + +#define INTEL_SNB_M_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0116, ## __VA_ARGS__), \ + MACRO__(0x0126, ## __VA_ARGS__) + +#define INTEL_SNB_M_IDS(MACRO__, ...) \ + INTEL_SNB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_SNB_IDS(MACRO__, ...) \ + INTEL_SNB_D_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SNB_M_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_M_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0156, ## __VA_ARGS__) /* GT1 mobile */ + +#define INTEL_IVB_M_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0166, ## __VA_ARGS__) /* GT2 mobile */ + +#define INTEL_IVB_M_IDS(MACRO__, ...) \ + INTEL_IVB_M_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_M_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_D_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0152, ## __VA_ARGS__), /* GT1 desktop */ \ + MACRO__(0x015a, ## __VA_ARGS__) /* GT1 server */ + +#define INTEL_IVB_D_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0162, ## __VA_ARGS__), /* GT2 desktop */ \ + MACRO__(0x016a, ## __VA_ARGS__) /* GT2 server */ + +#define INTEL_IVB_D_IDS(MACRO__, ...) \ + INTEL_IVB_D_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_D_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_IDS(MACRO__, ...) \ + INTEL_IVB_M_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_IVB_D_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_IVB_Q_IDS(MACRO__, ...) \ + INTEL_QUANTA_VGA_DEVICE(__VA_ARGS__) /* Quanta transcode */ + +#define INTEL_HSW_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0A02, ## __VA_ARGS__), /* ULT GT1 desktop */ \ + MACRO__(0x0A06, ## __VA_ARGS__), /* ULT GT1 mobile */ \ + MACRO__(0x0A0A, ## __VA_ARGS__), /* ULT GT1 server */ \ + MACRO__(0x0A0B, ## __VA_ARGS__) /* ULT GT1 reserved */ + +#define INTEL_HSW_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x0A0E, ## __VA_ARGS__) /* ULX GT1 mobile */ + +#define INTEL_HSW_GT1_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0402, ## __VA_ARGS__), /* GT1 desktop */ \ + MACRO__(0x0406, ## __VA_ARGS__), /* GT1 mobile */ \ + MACRO__(0x040A, ## __VA_ARGS__), /* GT1 server */ \ + MACRO__(0x040B, ## __VA_ARGS__), /* GT1 reserved */ \ + MACRO__(0x040E, ## __VA_ARGS__), /* GT1 reserved */ \ + MACRO__(0x0C02, ## __VA_ARGS__), /* SDV GT1 desktop */ \ + MACRO__(0x0C06, ## __VA_ARGS__), /* SDV GT1 mobile */ \ + MACRO__(0x0C0A, ## __VA_ARGS__), /* SDV GT1 server */ \ + MACRO__(0x0C0B, ## __VA_ARGS__), /* SDV GT1 reserved */ \ + MACRO__(0x0C0E, ## __VA_ARGS__), /* SDV GT1 reserved */ \ + MACRO__(0x0D02, ## __VA_ARGS__), /* CRW GT1 desktop */ \ + MACRO__(0x0D06, ## __VA_ARGS__), /* CRW GT1 mobile */ \ + MACRO__(0x0D0A, ## __VA_ARGS__), /* CRW GT1 server */ \ + MACRO__(0x0D0B, ## __VA_ARGS__), /* CRW GT1 reserved */ \ + MACRO__(0x0D0E, ## __VA_ARGS__) /* CRW GT1 reserved */ + +#define INTEL_HSW_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0A12, ## __VA_ARGS__), /* ULT GT2 desktop */ \ + MACRO__(0x0A16, ## __VA_ARGS__), /* ULT GT2 mobile */ \ + MACRO__(0x0A1A, ## __VA_ARGS__), /* ULT GT2 server */ \ + MACRO__(0x0A1B, ## __VA_ARGS__) /* ULT GT2 reserved */ \ + +#define INTEL_HSW_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x0A1E, ## __VA_ARGS__) /* ULX GT2 mobile */ \ + +#define INTEL_HSW_GT2_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0412, ## __VA_ARGS__), /* GT2 desktop */ \ + MACRO__(0x0416, ## __VA_ARGS__), /* GT2 mobile */ \ + MACRO__(0x041A, ## __VA_ARGS__), /* GT2 server */ \ + MACRO__(0x041B, ## __VA_ARGS__), /* GT2 reserved */ \ + MACRO__(0x041E, ## __VA_ARGS__), /* GT2 reserved */ \ + MACRO__(0x0C12, ## __VA_ARGS__), /* SDV GT2 desktop */ \ + MACRO__(0x0C16, ## __VA_ARGS__), /* SDV GT2 mobile */ \ + MACRO__(0x0C1A, ## __VA_ARGS__), /* SDV GT2 server */ \ + MACRO__(0x0C1B, ## __VA_ARGS__), /* SDV GT2 reserved */ \ + MACRO__(0x0C1E, ## __VA_ARGS__), /* SDV GT2 reserved */ \ + MACRO__(0x0D12, ## __VA_ARGS__), /* CRW GT2 desktop */ \ + MACRO__(0x0D16, ## __VA_ARGS__), /* CRW GT2 mobile */ \ + MACRO__(0x0D1A, ## __VA_ARGS__), /* CRW GT2 server */ \ + MACRO__(0x0D1B, ## __VA_ARGS__), /* CRW GT2 reserved */ \ + MACRO__(0x0D1E, ## __VA_ARGS__) /* CRW GT2 reserved */ + +#define INTEL_HSW_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x0A22, ## __VA_ARGS__), /* ULT GT3 desktop */ \ + MACRO__(0x0A26, ## __VA_ARGS__), /* ULT GT3 mobile */ \ + MACRO__(0x0A2A, ## __VA_ARGS__), /* ULT GT3 server */ \ + MACRO__(0x0A2B, ## __VA_ARGS__), /* ULT GT3 reserved */ \ + MACRO__(0x0A2E, ## __VA_ARGS__) /* ULT GT3 reserved */ + +#define INTEL_HSW_GT3_IDS(MACRO__, ...) \ + INTEL_HSW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x0422, ## __VA_ARGS__), /* GT3 desktop */ \ + MACRO__(0x0426, ## __VA_ARGS__), /* GT3 mobile */ \ + MACRO__(0x042A, ## __VA_ARGS__), /* GT3 server */ \ + MACRO__(0x042B, ## __VA_ARGS__), /* GT3 reserved */ \ + MACRO__(0x042E, ## __VA_ARGS__), /* GT3 reserved */ \ + MACRO__(0x0C22, ## __VA_ARGS__), /* SDV GT3 desktop */ \ + MACRO__(0x0C26, ## __VA_ARGS__), /* SDV GT3 mobile */ \ + MACRO__(0x0C2A, ## __VA_ARGS__), /* SDV GT3 server */ \ + MACRO__(0x0C2B, ## __VA_ARGS__), /* SDV GT3 reserved */ \ + MACRO__(0x0C2E, ## __VA_ARGS__), /* SDV GT3 reserved */ \ + MACRO__(0x0D22, ## __VA_ARGS__), /* CRW GT3 desktop */ \ + MACRO__(0x0D26, ## __VA_ARGS__), /* CRW GT3 mobile */ \ + MACRO__(0x0D2A, ## __VA_ARGS__), /* CRW GT3 server */ \ + MACRO__(0x0D2B, ## __VA_ARGS__), /* CRW GT3 reserved */ \ + MACRO__(0x0D2E, ## __VA_ARGS__) /* CRW GT3 reserved */ + +#define INTEL_HSW_IDS(MACRO__, ...) \ + INTEL_HSW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_HSW_GT3_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_VLV_IDS(MACRO__, ...) \ + MACRO__(0x0f30, ## __VA_ARGS__), \ + MACRO__(0x0f31, ## __VA_ARGS__), \ + MACRO__(0x0f32, ## __VA_ARGS__), \ + MACRO__(0x0f33, ## __VA_ARGS__) + +#define INTEL_BDW_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x1606, ## __VA_ARGS__), /* GT1 ULT */ \ + MACRO__(0x160B, ## __VA_ARGS__) /* GT1 Iris */ + +#define INTEL_BDW_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x160E, ## __VA_ARGS__) /* GT1 ULX */ + +#define INTEL_BDW_GT1_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1602, ## __VA_ARGS__), /* GT1 ULT */ \ + MACRO__(0x160A, ## __VA_ARGS__), /* GT1 Server */ \ + MACRO__(0x160D, ## __VA_ARGS__) /* GT1 Workstation */ + +#define INTEL_BDW_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x1616, ## __VA_ARGS__), /* GT2 ULT */ \ + MACRO__(0x161B, ## __VA_ARGS__) /* GT2 ULT */ + +#define INTEL_BDW_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x161E, ## __VA_ARGS__) /* GT2 ULX */ + +#define INTEL_BDW_GT2_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1612, ## __VA_ARGS__), /* GT2 Halo */ \ + MACRO__(0x161A, ## __VA_ARGS__), /* GT2 Server */ \ + MACRO__(0x161D, ## __VA_ARGS__) /* GT2 Workstation */ + +#define INTEL_BDW_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x1626, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x162B, ## __VA_ARGS__) /* Iris */ \ + +#define INTEL_BDW_ULX_GT3_IDS(MACRO__, ...) \ + MACRO__(0x162E, ## __VA_ARGS__) /* ULX */ + +#define INTEL_BDW_GT3_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1622, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x162A, ## __VA_ARGS__), /* Server */ \ + MACRO__(0x162D, ## __VA_ARGS__) /* Workstation */ + +#define INTEL_BDW_ULT_RSVD_IDS(MACRO__, ...) \ + MACRO__(0x1636, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x163B, ## __VA_ARGS__) /* Iris */ + +#define INTEL_BDW_ULX_RSVD_IDS(MACRO__, ...) \ + MACRO__(0x163E, ## __VA_ARGS__) /* ULX */ + +#define INTEL_BDW_RSVD_IDS(MACRO__, ...) \ + INTEL_BDW_ULT_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_ULX_RSVD_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1632, ## __VA_ARGS__), /* ULT */ \ + MACRO__(0x163A, ## __VA_ARGS__), /* Server */ \ + MACRO__(0x163D, ## __VA_ARGS__) /* Workstation */ + +#define INTEL_BDW_IDS(MACRO__, ...) \ + INTEL_BDW_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_BDW_RSVD_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_CHV_IDS(MACRO__, ...) \ + MACRO__(0x22b0, ## __VA_ARGS__), \ + MACRO__(0x22b1, ## __VA_ARGS__), \ + MACRO__(0x22b2, ## __VA_ARGS__), \ + MACRO__(0x22b3, ## __VA_ARGS__) + +#define INTEL_SKL_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x1906, ## __VA_ARGS__), /* ULT GT1 */ \ + MACRO__(0x1913, ## __VA_ARGS__) /* ULT GT1.5 */ + +#define INTEL_SKL_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x190E, ## __VA_ARGS__), /* ULX GT1 */ \ + MACRO__(0x1915, ## __VA_ARGS__) /* ULX GT1.5 */ + +#define INTEL_SKL_GT1_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1902, ## __VA_ARGS__), /* DT GT1 */ \ + MACRO__(0x190A, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x190B, ## __VA_ARGS__), /* Halo GT1 */ \ + MACRO__(0x1917, ## __VA_ARGS__) /* DT GT1.5 */ + +#define INTEL_SKL_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x1916, ## __VA_ARGS__), /* ULT GT2 */ \ + MACRO__(0x1921, ## __VA_ARGS__) /* ULT GT2F */ + +#define INTEL_SKL_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x191E, ## __VA_ARGS__) /* ULX GT2 */ + +#define INTEL_SKL_GT2_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x1912, ## __VA_ARGS__), /* DT GT2 */ \ + MACRO__(0x191A, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x191B, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x191D, ## __VA_ARGS__) /* WKS GT2 */ + +#define INTEL_SKL_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x1923, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x1926, ## __VA_ARGS__), /* ULT GT3e */ \ + MACRO__(0x1927, ## __VA_ARGS__) /* ULT GT3e */ + +#define INTEL_SKL_GT3_IDS(MACRO__, ...) \ + INTEL_SKL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x192A, ## __VA_ARGS__), /* SRV GT3 */ \ + MACRO__(0x192B, ## __VA_ARGS__), /* Halo GT3e */ \ + MACRO__(0x192D, ## __VA_ARGS__) /* SRV GT3e */ + +#define INTEL_SKL_GT4_IDS(MACRO__, ...) \ + MACRO__(0x1932, ## __VA_ARGS__), /* DT GT4 */ \ + MACRO__(0x193A, ## __VA_ARGS__), /* SRV GT4e */ \ + MACRO__(0x193B, ## __VA_ARGS__), /* Halo GT4e */ \ + MACRO__(0x193D, ## __VA_ARGS__) /* WKS GT4e */ + +#define INTEL_SKL_IDS(MACRO__, ...) \ + INTEL_SKL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_SKL_GT4_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_BXT_IDS(MACRO__, ...) \ + MACRO__(0x0A84, ## __VA_ARGS__), \ + MACRO__(0x1A84, ## __VA_ARGS__), \ + MACRO__(0x1A85, ## __VA_ARGS__), \ + MACRO__(0x5A84, ## __VA_ARGS__), /* APL HD Graphics 505 */ \ + MACRO__(0x5A85, ## __VA_ARGS__) /* APL HD Graphics 500 */ + +#define INTEL_GLK_IDS(MACRO__, ...) \ + MACRO__(0x3184, ## __VA_ARGS__), \ + MACRO__(0x3185, ## __VA_ARGS__) + +#define INTEL_KBL_ULT_GT1_IDS(MACRO__, ...) \ + MACRO__(0x5906, ## __VA_ARGS__), /* ULT GT1 */ \ + MACRO__(0x5913, ## __VA_ARGS__) /* ULT GT1.5 */ + +#define INTEL_KBL_ULX_GT1_IDS(MACRO__, ...) \ + MACRO__(0x590E, ## __VA_ARGS__), /* ULX GT1 */ \ + MACRO__(0x5915, ## __VA_ARGS__) /* ULX GT1.5 */ + +#define INTEL_KBL_GT1_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_ULX_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5902, ## __VA_ARGS__), /* DT GT1 */ \ + MACRO__(0x5908, ## __VA_ARGS__), /* Halo GT1 */ \ + MACRO__(0x590A, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x590B, ## __VA_ARGS__) /* Halo GT1 */ + +#define INTEL_KBL_ULT_GT2_IDS(MACRO__, ...) \ + MACRO__(0x5916, ## __VA_ARGS__), /* ULT GT2 */ \ + MACRO__(0x5921, ## __VA_ARGS__) /* ULT GT2F */ + +#define INTEL_KBL_ULX_GT2_IDS(MACRO__, ...) \ + MACRO__(0x591E, ## __VA_ARGS__) /* ULX GT2 */ + +#define INTEL_KBL_GT2_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_ULX_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5912, ## __VA_ARGS__), /* DT GT2 */ \ + MACRO__(0x5917, ## __VA_ARGS__), /* Mobile GT2 */ \ + MACRO__(0x591A, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x591B, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x591D, ## __VA_ARGS__) /* WKS GT2 */ + +#define INTEL_KBL_ULT_GT3_IDS(MACRO__, ...) \ + MACRO__(0x5926, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_KBL_GT3_IDS(MACRO__, ...) \ + INTEL_KBL_ULT_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5923, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x5927, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_KBL_GT4_IDS(MACRO__, ...) \ + MACRO__(0x593B, ## __VA_ARGS__) /* Halo GT4 */ + +/* AML/KBL Y GT2 */ +#define INTEL_AML_KBL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x591C, ## __VA_ARGS__), /* ULX GT2 */ \ + MACRO__(0x87C0, ## __VA_ARGS__) /* ULX GT2 */ + +/* AML/CFL Y GT2 */ +#define INTEL_AML_CFL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x87CA, ## __VA_ARGS__) + +/* CML GT1 */ +#define INTEL_CML_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9BA2, ## __VA_ARGS__), \ + MACRO__(0x9BA4, ## __VA_ARGS__), \ + MACRO__(0x9BA5, ## __VA_ARGS__), \ + MACRO__(0x9BA8, ## __VA_ARGS__) + +#define INTEL_CML_U_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9B21, ## __VA_ARGS__), \ + MACRO__(0x9BAA, ## __VA_ARGS__), \ + MACRO__(0x9BAC, ## __VA_ARGS__) + +/* CML GT2 */ +#define INTEL_CML_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9BC2, ## __VA_ARGS__), \ + MACRO__(0x9BC4, ## __VA_ARGS__), \ + MACRO__(0x9BC5, ## __VA_ARGS__), \ + MACRO__(0x9BC6, ## __VA_ARGS__), \ + MACRO__(0x9BC8, ## __VA_ARGS__), \ + MACRO__(0x9BE6, ## __VA_ARGS__), \ + MACRO__(0x9BF6, ## __VA_ARGS__) + +#define INTEL_CML_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9B41, ## __VA_ARGS__), \ + MACRO__(0x9BCA, ## __VA_ARGS__), \ + MACRO__(0x9BCC, ## __VA_ARGS__) + +#define INTEL_CML_IDS(MACRO__, ...) \ + INTEL_CML_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CML_U_GT2_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_KBL_IDS(MACRO__, ...) \ + INTEL_KBL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_KBL_GT4_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_AML_KBL_GT2_IDS(MACRO__, ## __VA_ARGS__) + +/* CFL S */ +#define INTEL_CFL_S_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3E90, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x3E93, ## __VA_ARGS__), /* SRV GT1 */ \ + MACRO__(0x3E99, ## __VA_ARGS__) /* SRV GT1 */ + +#define INTEL_CFL_S_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3E91, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E92, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E96, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E98, ## __VA_ARGS__), /* SRV GT2 */ \ + MACRO__(0x3E9A, ## __VA_ARGS__) /* SRV GT2 */ + +/* CFL H */ +#define INTEL_CFL_H_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3E9C, ## __VA_ARGS__) + +#define INTEL_CFL_H_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3E94, ## __VA_ARGS__), /* Halo GT2 */ \ + MACRO__(0x3E9B, ## __VA_ARGS__) /* Halo GT2 */ + +/* CFL U GT2 */ +#define INTEL_CFL_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3EA9, ## __VA_ARGS__) + +/* CFL U GT3 */ +#define INTEL_CFL_U_GT3_IDS(MACRO__, ...) \ + MACRO__(0x3EA5, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA6, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA7, ## __VA_ARGS__), /* ULT GT3 */ \ + MACRO__(0x3EA8, ## __VA_ARGS__) /* ULT GT3 */ + +#define INTEL_CFL_IDS(MACRO__, ...) \ + INTEL_CFL_S_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_S_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_H_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_H_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_CFL_U_GT3_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_AML_CFL_GT2_IDS(MACRO__, ## __VA_ARGS__) + +/* WHL/CFL U GT1 */ +#define INTEL_WHL_U_GT1_IDS(MACRO__, ...) \ + MACRO__(0x3EA1, ## __VA_ARGS__), \ + MACRO__(0x3EA4, ## __VA_ARGS__) + +/* WHL/CFL U GT2 */ +#define INTEL_WHL_U_GT2_IDS(MACRO__, ...) \ + MACRO__(0x3EA0, ## __VA_ARGS__), \ + MACRO__(0x3EA3, ## __VA_ARGS__) + +/* WHL/CFL U GT3 */ +#define INTEL_WHL_U_GT3_IDS(MACRO__, ...) \ + MACRO__(0x3EA2, ## __VA_ARGS__) + +#define INTEL_WHL_IDS(MACRO__, ...) \ + INTEL_WHL_U_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_WHL_U_GT2_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_WHL_U_GT3_IDS(MACRO__, ## __VA_ARGS__) + +/* CNL */ +#define INTEL_CNL_PORT_F_IDS(MACRO__, ...) \ + MACRO__(0x5A44, ## __VA_ARGS__), \ + MACRO__(0x5A4C, ## __VA_ARGS__), \ + MACRO__(0x5A54, ## __VA_ARGS__), \ + MACRO__(0x5A5C, ## __VA_ARGS__) + +#define INTEL_CNL_IDS(MACRO__, ...) \ + INTEL_CNL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x5A40, ## __VA_ARGS__), \ + MACRO__(0x5A41, ## __VA_ARGS__), \ + MACRO__(0x5A42, ## __VA_ARGS__), \ + MACRO__(0x5A49, ## __VA_ARGS__), \ + MACRO__(0x5A4A, ## __VA_ARGS__), \ + MACRO__(0x5A50, ## __VA_ARGS__), \ + MACRO__(0x5A51, ## __VA_ARGS__), \ + MACRO__(0x5A52, ## __VA_ARGS__), \ + MACRO__(0x5A59, ## __VA_ARGS__), \ + MACRO__(0x5A5A, ## __VA_ARGS__) + +/* ICL */ +#define INTEL_ICL_PORT_F_IDS(MACRO__, ...) \ + MACRO__(0x8A50, ## __VA_ARGS__), \ + MACRO__(0x8A52, ## __VA_ARGS__), \ + MACRO__(0x8A53, ## __VA_ARGS__), \ + MACRO__(0x8A54, ## __VA_ARGS__), \ + MACRO__(0x8A56, ## __VA_ARGS__), \ + MACRO__(0x8A57, ## __VA_ARGS__), \ + MACRO__(0x8A58, ## __VA_ARGS__), \ + MACRO__(0x8A59, ## __VA_ARGS__), \ + MACRO__(0x8A5A, ## __VA_ARGS__), \ + MACRO__(0x8A5B, ## __VA_ARGS__), \ + MACRO__(0x8A5C, ## __VA_ARGS__), \ + MACRO__(0x8A70, ## __VA_ARGS__), \ + MACRO__(0x8A71, ## __VA_ARGS__) + +#define INTEL_ICL_IDS(MACRO__, ...) \ + INTEL_ICL_PORT_F_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0x8A51, ## __VA_ARGS__), \ + MACRO__(0x8A5D, ## __VA_ARGS__) + +/* EHL */ +#define INTEL_EHL_IDS(MACRO__, ...) \ + MACRO__(0x4541, ## __VA_ARGS__), \ + MACRO__(0x4551, ## __VA_ARGS__), \ + MACRO__(0x4555, ## __VA_ARGS__), \ + MACRO__(0x4557, ## __VA_ARGS__), \ + MACRO__(0x4570, ## __VA_ARGS__), \ + MACRO__(0x4571, ## __VA_ARGS__) + +/* JSL */ +#define INTEL_JSL_IDS(MACRO__, ...) \ + MACRO__(0x4E51, ## __VA_ARGS__), \ + MACRO__(0x4E55, ## __VA_ARGS__), \ + MACRO__(0x4E57, ## __VA_ARGS__), \ + MACRO__(0x4E61, ## __VA_ARGS__), \ + MACRO__(0x4E71, ## __VA_ARGS__) + +/* TGL */ +#define INTEL_TGL_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9A60, ## __VA_ARGS__), \ + MACRO__(0x9A68, ## __VA_ARGS__), \ + MACRO__(0x9A70, ## __VA_ARGS__) + +#define INTEL_TGL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9A40, ## __VA_ARGS__), \ + MACRO__(0x9A49, ## __VA_ARGS__), \ + MACRO__(0x9A59, ## __VA_ARGS__), \ + MACRO__(0x9A78, ## __VA_ARGS__), \ + MACRO__(0x9AC0, ## __VA_ARGS__), \ + MACRO__(0x9AC9, ## __VA_ARGS__), \ + MACRO__(0x9AD9, ## __VA_ARGS__), \ + MACRO__(0x9AF8, ## __VA_ARGS__) + +#define INTEL_TGL_IDS(MACRO__, ...) \ + INTEL_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__) + +/* RKL */ +#define INTEL_RKL_IDS(MACRO__, ...) \ + MACRO__(0x4C80, ## __VA_ARGS__), \ + MACRO__(0x4C8A, ## __VA_ARGS__), \ + MACRO__(0x4C8B, ## __VA_ARGS__), \ + MACRO__(0x4C8C, ## __VA_ARGS__), \ + MACRO__(0x4C90, ## __VA_ARGS__), \ + MACRO__(0x4C9A, ## __VA_ARGS__) + +/* DG1 */ +#define INTEL_DG1_IDS(MACRO__, ...) \ + MACRO__(0x4905, ## __VA_ARGS__), \ + MACRO__(0x4906, ## __VA_ARGS__), \ + MACRO__(0x4907, ## __VA_ARGS__), \ + MACRO__(0x4908, ## __VA_ARGS__), \ + MACRO__(0x4909, ## __VA_ARGS__) + +/* ADL-S */ +#define INTEL_ADLS_IDS(MACRO__, ...) \ + MACRO__(0x4680, ## __VA_ARGS__), \ + MACRO__(0x4682, ## __VA_ARGS__), \ + MACRO__(0x4688, ## __VA_ARGS__), \ + MACRO__(0x468A, ## __VA_ARGS__), \ + MACRO__(0x468B, ## __VA_ARGS__), \ + MACRO__(0x4690, ## __VA_ARGS__), \ + MACRO__(0x4692, ## __VA_ARGS__), \ + MACRO__(0x4693, ## __VA_ARGS__) + +/* ADL-P */ +#define INTEL_ADLP_IDS(MACRO__, ...) \ + MACRO__(0x46A0, ## __VA_ARGS__), \ + MACRO__(0x46A1, ## __VA_ARGS__), \ + MACRO__(0x46A2, ## __VA_ARGS__), \ + MACRO__(0x46A3, ## __VA_ARGS__), \ + MACRO__(0x46A6, ## __VA_ARGS__), \ + MACRO__(0x46A8, ## __VA_ARGS__), \ + MACRO__(0x46AA, ## __VA_ARGS__), \ + MACRO__(0x462A, ## __VA_ARGS__), \ + MACRO__(0x4626, ## __VA_ARGS__), \ + MACRO__(0x4628, ## __VA_ARGS__), \ + MACRO__(0x46B0, ## __VA_ARGS__), \ + MACRO__(0x46B1, ## __VA_ARGS__), \ + MACRO__(0x46B2, ## __VA_ARGS__), \ + MACRO__(0x46B3, ## __VA_ARGS__), \ + MACRO__(0x46C0, ## __VA_ARGS__), \ + MACRO__(0x46C1, ## __VA_ARGS__), \ + MACRO__(0x46C2, ## __VA_ARGS__), \ + MACRO__(0x46C3, ## __VA_ARGS__) + +/* ADL-N */ +#define INTEL_ADLN_IDS(MACRO__, ...) \ + MACRO__(0x46D0, ## __VA_ARGS__), \ + MACRO__(0x46D1, ## __VA_ARGS__), \ + MACRO__(0x46D2, ## __VA_ARGS__), \ + MACRO__(0x46D3, ## __VA_ARGS__), \ + MACRO__(0x46D4, ## __VA_ARGS__) + +/* RPL-S */ +#define INTEL_RPLS_IDS(MACRO__, ...) \ + MACRO__(0xA780, ## __VA_ARGS__), \ + MACRO__(0xA781, ## __VA_ARGS__), \ + MACRO__(0xA782, ## __VA_ARGS__), \ + MACRO__(0xA783, ## __VA_ARGS__), \ + MACRO__(0xA788, ## __VA_ARGS__), \ + MACRO__(0xA789, ## __VA_ARGS__), \ + MACRO__(0xA78A, ## __VA_ARGS__), \ + MACRO__(0xA78B, ## __VA_ARGS__) + +/* RPL-U */ +#define INTEL_RPLU_IDS(MACRO__, ...) \ + MACRO__(0xA721, ## __VA_ARGS__), \ + MACRO__(0xA7A1, ## __VA_ARGS__), \ + MACRO__(0xA7A9, ## __VA_ARGS__), \ + MACRO__(0xA7AC, ## __VA_ARGS__), \ + MACRO__(0xA7AD, ## __VA_ARGS__) + +/* RPL-P */ +#define INTEL_RPLP_IDS(MACRO__, ...) \ + MACRO__(0xA720, ## __VA_ARGS__), \ + MACRO__(0xA7A0, ## __VA_ARGS__), \ + MACRO__(0xA7A8, ## __VA_ARGS__), \ + MACRO__(0xA7AA, ## __VA_ARGS__), \ + MACRO__(0xA7AB, ## __VA_ARGS__) + +/* DG2 */ +#define INTEL_DG2_G10_IDS(MACRO__, ...) \ + MACRO__(0x5690, ## __VA_ARGS__), \ + MACRO__(0x5691, ## __VA_ARGS__), \ + MACRO__(0x5692, ## __VA_ARGS__), \ + MACRO__(0x56A0, ## __VA_ARGS__), \ + MACRO__(0x56A1, ## __VA_ARGS__), \ + MACRO__(0x56A2, ## __VA_ARGS__), \ + MACRO__(0x56BE, ## __VA_ARGS__), \ + MACRO__(0x56BF, ## __VA_ARGS__) + +#define INTEL_DG2_G11_IDS(MACRO__, ...) \ + MACRO__(0x5693, ## __VA_ARGS__), \ + MACRO__(0x5694, ## __VA_ARGS__), \ + MACRO__(0x5695, ## __VA_ARGS__), \ + MACRO__(0x56A5, ## __VA_ARGS__), \ + MACRO__(0x56A6, ## __VA_ARGS__), \ + MACRO__(0x56B0, ## __VA_ARGS__), \ + MACRO__(0x56B1, ## __VA_ARGS__), \ + MACRO__(0x56BA, ## __VA_ARGS__), \ + MACRO__(0x56BB, ## __VA_ARGS__), \ + MACRO__(0x56BC, ## __VA_ARGS__), \ + MACRO__(0x56BD, ## __VA_ARGS__) + +#define INTEL_DG2_G12_IDS(MACRO__, ...) \ + MACRO__(0x5696, ## __VA_ARGS__), \ + MACRO__(0x5697, ## __VA_ARGS__), \ + MACRO__(0x56A3, ## __VA_ARGS__), \ + MACRO__(0x56A4, ## __VA_ARGS__), \ + MACRO__(0x56B2, ## __VA_ARGS__), \ + MACRO__(0x56B3, ## __VA_ARGS__) + +#define INTEL_DG2_IDS(MACRO__, ...) \ + INTEL_DG2_G10_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_DG2_G11_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_DG2_G12_IDS(MACRO__, ## __VA_ARGS__) + +#define INTEL_ATS_M150_IDS(MACRO__, ...) \ + MACRO__(0x56C0, ## __VA_ARGS__), \ + MACRO__(0x56C2, ## __VA_ARGS__) + +#define INTEL_ATS_M75_IDS(MACRO__, ...) \ + MACRO__(0x56C1, ## __VA_ARGS__) + +#define INTEL_ATS_M_IDS(MACRO__, ...) \ + INTEL_ATS_M150_IDS(MACRO__, ## __VA_ARGS__), \ + INTEL_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) + +/* MTL */ +#define INTEL_MTL_IDS(MACRO__, ...) \ + MACRO__(0x7D40, ## __VA_ARGS__), \ + MACRO__(0x7D41, ## __VA_ARGS__), \ + MACRO__(0x7D45, ## __VA_ARGS__), \ + MACRO__(0x7D51, ## __VA_ARGS__), \ + MACRO__(0x7D55, ## __VA_ARGS__), \ + MACRO__(0x7D60, ## __VA_ARGS__), \ + MACRO__(0x7D67, ## __VA_ARGS__), \ + MACRO__(0x7DD1, ## __VA_ARGS__), \ + MACRO__(0x7DD5, ## __VA_ARGS__) + +/* LNL */ +#define INTEL_LNL_IDS(MACRO__, ...) \ + MACRO__(0x6420, ## __VA_ARGS__), \ + MACRO__(0x64A0, ## __VA_ARGS__), \ + MACRO__(0x64B0, ## __VA_ARGS__) + +#endif /* _I915_PCIIDS_H */ -- cgit v1.2.3 From e051d64b0a8f5fba923ffbe2003d691ef03f0607 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:09 +0300 Subject: drm: move xe_pciids.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/e19543f2ae978678c2ff814454f07c96ccd02175.1717075103.git.jani.nikula@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 2 +- include/drm/intel/xe_pciids.h | 195 ++++++++++++++++++++++++++++++++++++++++++ include/drm/xe_pciids.h | 195 ------------------------------------------ 3 files changed, 196 insertions(+), 196 deletions(-) create mode 100644 include/drm/intel/xe_pciids.h delete mode 100644 include/drm/xe_pciids.h (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index d6859108cc69..0dd21e0da94e 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include "display/xe_display.h" #include "regs/xe_gt_regs.h" diff --git a/include/drm/intel/xe_pciids.h b/include/drm/intel/xe_pciids.h new file mode 100644 index 000000000000..adb37bc541e4 --- /dev/null +++ b/include/drm/intel/xe_pciids.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2022 Intel Corporation + */ + +#ifndef _XE_PCIIDS_H_ +#define _XE_PCIIDS_H_ + +/* + * Lists below can be turned into initializers for a struct pci_device_id + * by defining INTEL_VGA_DEVICE: + * + * #define INTEL_VGA_DEVICE(id, info) { \ + * 0x8086, id, \ + * ~0, ~0, \ + * 0x030000, 0xff0000, \ + * (unsigned long) info } + * + * And then calling like: + * + * XE_TGL_12_GT1_IDS(INTEL_VGA_DEVICE, ## __VA_ARGS__) + * + * To turn them into something else, just provide a different macro passed as + * first argument. + */ + +/* TGL */ +#define XE_TGL_GT1_IDS(MACRO__, ...) \ + MACRO__(0x9A60, ## __VA_ARGS__), \ + MACRO__(0x9A68, ## __VA_ARGS__), \ + MACRO__(0x9A70, ## __VA_ARGS__) + +#define XE_TGL_GT2_IDS(MACRO__, ...) \ + MACRO__(0x9A40, ## __VA_ARGS__), \ + MACRO__(0x9A49, ## __VA_ARGS__), \ + MACRO__(0x9A59, ## __VA_ARGS__), \ + MACRO__(0x9A78, ## __VA_ARGS__), \ + MACRO__(0x9AC0, ## __VA_ARGS__), \ + MACRO__(0x9AC9, ## __VA_ARGS__), \ + MACRO__(0x9AD9, ## __VA_ARGS__), \ + MACRO__(0x9AF8, ## __VA_ARGS__) + +#define XE_TGL_IDS(MACRO__, ...) \ + XE_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__),\ + XE_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__) + +/* RKL */ +#define XE_RKL_IDS(MACRO__, ...) \ + MACRO__(0x4C80, ## __VA_ARGS__), \ + MACRO__(0x4C8A, ## __VA_ARGS__), \ + MACRO__(0x4C8B, ## __VA_ARGS__), \ + MACRO__(0x4C8C, ## __VA_ARGS__), \ + MACRO__(0x4C90, ## __VA_ARGS__), \ + MACRO__(0x4C9A, ## __VA_ARGS__) + +/* DG1 */ +#define XE_DG1_IDS(MACRO__, ...) \ + MACRO__(0x4905, ## __VA_ARGS__), \ + MACRO__(0x4906, ## __VA_ARGS__), \ + MACRO__(0x4907, ## __VA_ARGS__), \ + MACRO__(0x4908, ## __VA_ARGS__), \ + MACRO__(0x4909, ## __VA_ARGS__) + +/* ADL-S */ +#define XE_ADLS_IDS(MACRO__, ...) \ + MACRO__(0x4680, ## __VA_ARGS__), \ + MACRO__(0x4682, ## __VA_ARGS__), \ + MACRO__(0x4688, ## __VA_ARGS__), \ + MACRO__(0x468A, ## __VA_ARGS__), \ + MACRO__(0x468B, ## __VA_ARGS__), \ + MACRO__(0x4690, ## __VA_ARGS__), \ + MACRO__(0x4692, ## __VA_ARGS__), \ + MACRO__(0x4693, ## __VA_ARGS__) + +/* ADL-P */ +#define XE_ADLP_IDS(MACRO__, ...) \ + MACRO__(0x46A0, ## __VA_ARGS__), \ + MACRO__(0x46A1, ## __VA_ARGS__), \ + MACRO__(0x46A2, ## __VA_ARGS__), \ + MACRO__(0x46A3, ## __VA_ARGS__), \ + MACRO__(0x46A6, ## __VA_ARGS__), \ + MACRO__(0x46A8, ## __VA_ARGS__), \ + MACRO__(0x46AA, ## __VA_ARGS__), \ + MACRO__(0x462A, ## __VA_ARGS__), \ + MACRO__(0x4626, ## __VA_ARGS__), \ + MACRO__(0x4628, ## __VA_ARGS__), \ + MACRO__(0x46B0, ## __VA_ARGS__), \ + MACRO__(0x46B1, ## __VA_ARGS__), \ + MACRO__(0x46B2, ## __VA_ARGS__), \ + MACRO__(0x46B3, ## __VA_ARGS__), \ + MACRO__(0x46C0, ## __VA_ARGS__), \ + MACRO__(0x46C1, ## __VA_ARGS__), \ + MACRO__(0x46C2, ## __VA_ARGS__), \ + MACRO__(0x46C3, ## __VA_ARGS__) + +/* ADL-N */ +#define XE_ADLN_IDS(MACRO__, ...) \ + MACRO__(0x46D0, ## __VA_ARGS__), \ + MACRO__(0x46D1, ## __VA_ARGS__), \ + MACRO__(0x46D2, ## __VA_ARGS__) + +/* RPL-S */ +#define XE_RPLS_IDS(MACRO__, ...) \ + MACRO__(0xA780, ## __VA_ARGS__), \ + MACRO__(0xA781, ## __VA_ARGS__), \ + MACRO__(0xA782, ## __VA_ARGS__), \ + MACRO__(0xA783, ## __VA_ARGS__), \ + MACRO__(0xA788, ## __VA_ARGS__), \ + MACRO__(0xA789, ## __VA_ARGS__), \ + MACRO__(0xA78A, ## __VA_ARGS__), \ + MACRO__(0xA78B, ## __VA_ARGS__) + +/* RPL-U */ +#define XE_RPLU_IDS(MACRO__, ...) \ + MACRO__(0xA721, ## __VA_ARGS__), \ + MACRO__(0xA7A1, ## __VA_ARGS__), \ + MACRO__(0xA7A9, ## __VA_ARGS__), \ + MACRO__(0xA7AC, ## __VA_ARGS__), \ + MACRO__(0xA7AD, ## __VA_ARGS__) + +/* RPL-P */ +#define XE_RPLP_IDS(MACRO__, ...) \ + XE_RPLU_IDS(MACRO__, ## __VA_ARGS__), \ + MACRO__(0xA720, ## __VA_ARGS__), \ + MACRO__(0xA7A0, ## __VA_ARGS__), \ + MACRO__(0xA7A8, ## __VA_ARGS__), \ + MACRO__(0xA7AA, ## __VA_ARGS__), \ + MACRO__(0xA7AB, ## __VA_ARGS__) + +/* DG2 */ +#define XE_DG2_G10_IDS(MACRO__, ...) \ + MACRO__(0x5690, ## __VA_ARGS__), \ + MACRO__(0x5691, ## __VA_ARGS__), \ + MACRO__(0x5692, ## __VA_ARGS__), \ + MACRO__(0x56A0, ## __VA_ARGS__), \ + MACRO__(0x56A1, ## __VA_ARGS__), \ + MACRO__(0x56A2, ## __VA_ARGS__), \ + MACRO__(0x56BE, ## __VA_ARGS__), \ + MACRO__(0x56BF, ## __VA_ARGS__) + +#define XE_DG2_G11_IDS(MACRO__, ...) \ + MACRO__(0x5693, ## __VA_ARGS__), \ + MACRO__(0x5694, ## __VA_ARGS__), \ + MACRO__(0x5695, ## __VA_ARGS__), \ + MACRO__(0x56A5, ## __VA_ARGS__), \ + MACRO__(0x56A6, ## __VA_ARGS__), \ + MACRO__(0x56B0, ## __VA_ARGS__), \ + MACRO__(0x56B1, ## __VA_ARGS__), \ + MACRO__(0x56BA, ## __VA_ARGS__), \ + MACRO__(0x56BB, ## __VA_ARGS__), \ + MACRO__(0x56BC, ## __VA_ARGS__), \ + MACRO__(0x56BD, ## __VA_ARGS__) + +#define XE_DG2_G12_IDS(MACRO__, ...) \ + MACRO__(0x5696, ## __VA_ARGS__), \ + MACRO__(0x5697, ## __VA_ARGS__), \ + MACRO__(0x56A3, ## __VA_ARGS__), \ + MACRO__(0x56A4, ## __VA_ARGS__), \ + MACRO__(0x56B2, ## __VA_ARGS__), \ + MACRO__(0x56B3, ## __VA_ARGS__) + +#define XE_DG2_IDS(MACRO__, ...) \ + XE_DG2_G10_IDS(MACRO__, ## __VA_ARGS__),\ + XE_DG2_G11_IDS(MACRO__, ## __VA_ARGS__),\ + XE_DG2_G12_IDS(MACRO__, ## __VA_ARGS__) + +#define XE_ATS_M150_IDS(MACRO__, ...) \ + MACRO__(0x56C0, ## __VA_ARGS__), \ + MACRO__(0x56C2, ## __VA_ARGS__) + +#define XE_ATS_M75_IDS(MACRO__, ...) \ + MACRO__(0x56C1, ## __VA_ARGS__) + +#define XE_ATS_M_IDS(MACRO__, ...) \ + XE_ATS_M150_IDS(MACRO__, ## __VA_ARGS__),\ + XE_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) + +/* MTL / ARL */ +#define XE_MTL_IDS(MACRO__, ...) \ + MACRO__(0x7D40, ## __VA_ARGS__), \ + MACRO__(0x7D41, ## __VA_ARGS__), \ + MACRO__(0x7D45, ## __VA_ARGS__), \ + MACRO__(0x7D51, ## __VA_ARGS__), \ + MACRO__(0x7D55, ## __VA_ARGS__), \ + MACRO__(0x7D60, ## __VA_ARGS__), \ + MACRO__(0x7D67, ## __VA_ARGS__), \ + MACRO__(0x7DD1, ## __VA_ARGS__), \ + MACRO__(0x7DD5, ## __VA_ARGS__) + +#define XE_LNL_IDS(MACRO__, ...) \ + MACRO__(0x6420, ## __VA_ARGS__), \ + MACRO__(0x64A0, ## __VA_ARGS__), \ + MACRO__(0x64B0, ## __VA_ARGS__) + +#endif diff --git a/include/drm/xe_pciids.h b/include/drm/xe_pciids.h deleted file mode 100644 index adb37bc541e4..000000000000 --- a/include/drm/xe_pciids.h +++ /dev/null @@ -1,195 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2022 Intel Corporation - */ - -#ifndef _XE_PCIIDS_H_ -#define _XE_PCIIDS_H_ - -/* - * Lists below can be turned into initializers for a struct pci_device_id - * by defining INTEL_VGA_DEVICE: - * - * #define INTEL_VGA_DEVICE(id, info) { \ - * 0x8086, id, \ - * ~0, ~0, \ - * 0x030000, 0xff0000, \ - * (unsigned long) info } - * - * And then calling like: - * - * XE_TGL_12_GT1_IDS(INTEL_VGA_DEVICE, ## __VA_ARGS__) - * - * To turn them into something else, just provide a different macro passed as - * first argument. - */ - -/* TGL */ -#define XE_TGL_GT1_IDS(MACRO__, ...) \ - MACRO__(0x9A60, ## __VA_ARGS__), \ - MACRO__(0x9A68, ## __VA_ARGS__), \ - MACRO__(0x9A70, ## __VA_ARGS__) - -#define XE_TGL_GT2_IDS(MACRO__, ...) \ - MACRO__(0x9A40, ## __VA_ARGS__), \ - MACRO__(0x9A49, ## __VA_ARGS__), \ - MACRO__(0x9A59, ## __VA_ARGS__), \ - MACRO__(0x9A78, ## __VA_ARGS__), \ - MACRO__(0x9AC0, ## __VA_ARGS__), \ - MACRO__(0x9AC9, ## __VA_ARGS__), \ - MACRO__(0x9AD9, ## __VA_ARGS__), \ - MACRO__(0x9AF8, ## __VA_ARGS__) - -#define XE_TGL_IDS(MACRO__, ...) \ - XE_TGL_GT1_IDS(MACRO__, ## __VA_ARGS__),\ - XE_TGL_GT2_IDS(MACRO__, ## __VA_ARGS__) - -/* RKL */ -#define XE_RKL_IDS(MACRO__, ...) \ - MACRO__(0x4C80, ## __VA_ARGS__), \ - MACRO__(0x4C8A, ## __VA_ARGS__), \ - MACRO__(0x4C8B, ## __VA_ARGS__), \ - MACRO__(0x4C8C, ## __VA_ARGS__), \ - MACRO__(0x4C90, ## __VA_ARGS__), \ - MACRO__(0x4C9A, ## __VA_ARGS__) - -/* DG1 */ -#define XE_DG1_IDS(MACRO__, ...) \ - MACRO__(0x4905, ## __VA_ARGS__), \ - MACRO__(0x4906, ## __VA_ARGS__), \ - MACRO__(0x4907, ## __VA_ARGS__), \ - MACRO__(0x4908, ## __VA_ARGS__), \ - MACRO__(0x4909, ## __VA_ARGS__) - -/* ADL-S */ -#define XE_ADLS_IDS(MACRO__, ...) \ - MACRO__(0x4680, ## __VA_ARGS__), \ - MACRO__(0x4682, ## __VA_ARGS__), \ - MACRO__(0x4688, ## __VA_ARGS__), \ - MACRO__(0x468A, ## __VA_ARGS__), \ - MACRO__(0x468B, ## __VA_ARGS__), \ - MACRO__(0x4690, ## __VA_ARGS__), \ - MACRO__(0x4692, ## __VA_ARGS__), \ - MACRO__(0x4693, ## __VA_ARGS__) - -/* ADL-P */ -#define XE_ADLP_IDS(MACRO__, ...) \ - MACRO__(0x46A0, ## __VA_ARGS__), \ - MACRO__(0x46A1, ## __VA_ARGS__), \ - MACRO__(0x46A2, ## __VA_ARGS__), \ - MACRO__(0x46A3, ## __VA_ARGS__), \ - MACRO__(0x46A6, ## __VA_ARGS__), \ - MACRO__(0x46A8, ## __VA_ARGS__), \ - MACRO__(0x46AA, ## __VA_ARGS__), \ - MACRO__(0x462A, ## __VA_ARGS__), \ - MACRO__(0x4626, ## __VA_ARGS__), \ - MACRO__(0x4628, ## __VA_ARGS__), \ - MACRO__(0x46B0, ## __VA_ARGS__), \ - MACRO__(0x46B1, ## __VA_ARGS__), \ - MACRO__(0x46B2, ## __VA_ARGS__), \ - MACRO__(0x46B3, ## __VA_ARGS__), \ - MACRO__(0x46C0, ## __VA_ARGS__), \ - MACRO__(0x46C1, ## __VA_ARGS__), \ - MACRO__(0x46C2, ## __VA_ARGS__), \ - MACRO__(0x46C3, ## __VA_ARGS__) - -/* ADL-N */ -#define XE_ADLN_IDS(MACRO__, ...) \ - MACRO__(0x46D0, ## __VA_ARGS__), \ - MACRO__(0x46D1, ## __VA_ARGS__), \ - MACRO__(0x46D2, ## __VA_ARGS__) - -/* RPL-S */ -#define XE_RPLS_IDS(MACRO__, ...) \ - MACRO__(0xA780, ## __VA_ARGS__), \ - MACRO__(0xA781, ## __VA_ARGS__), \ - MACRO__(0xA782, ## __VA_ARGS__), \ - MACRO__(0xA783, ## __VA_ARGS__), \ - MACRO__(0xA788, ## __VA_ARGS__), \ - MACRO__(0xA789, ## __VA_ARGS__), \ - MACRO__(0xA78A, ## __VA_ARGS__), \ - MACRO__(0xA78B, ## __VA_ARGS__) - -/* RPL-U */ -#define XE_RPLU_IDS(MACRO__, ...) \ - MACRO__(0xA721, ## __VA_ARGS__), \ - MACRO__(0xA7A1, ## __VA_ARGS__), \ - MACRO__(0xA7A9, ## __VA_ARGS__), \ - MACRO__(0xA7AC, ## __VA_ARGS__), \ - MACRO__(0xA7AD, ## __VA_ARGS__) - -/* RPL-P */ -#define XE_RPLP_IDS(MACRO__, ...) \ - XE_RPLU_IDS(MACRO__, ## __VA_ARGS__), \ - MACRO__(0xA720, ## __VA_ARGS__), \ - MACRO__(0xA7A0, ## __VA_ARGS__), \ - MACRO__(0xA7A8, ## __VA_ARGS__), \ - MACRO__(0xA7AA, ## __VA_ARGS__), \ - MACRO__(0xA7AB, ## __VA_ARGS__) - -/* DG2 */ -#define XE_DG2_G10_IDS(MACRO__, ...) \ - MACRO__(0x5690, ## __VA_ARGS__), \ - MACRO__(0x5691, ## __VA_ARGS__), \ - MACRO__(0x5692, ## __VA_ARGS__), \ - MACRO__(0x56A0, ## __VA_ARGS__), \ - MACRO__(0x56A1, ## __VA_ARGS__), \ - MACRO__(0x56A2, ## __VA_ARGS__), \ - MACRO__(0x56BE, ## __VA_ARGS__), \ - MACRO__(0x56BF, ## __VA_ARGS__) - -#define XE_DG2_G11_IDS(MACRO__, ...) \ - MACRO__(0x5693, ## __VA_ARGS__), \ - MACRO__(0x5694, ## __VA_ARGS__), \ - MACRO__(0x5695, ## __VA_ARGS__), \ - MACRO__(0x56A5, ## __VA_ARGS__), \ - MACRO__(0x56A6, ## __VA_ARGS__), \ - MACRO__(0x56B0, ## __VA_ARGS__), \ - MACRO__(0x56B1, ## __VA_ARGS__), \ - MACRO__(0x56BA, ## __VA_ARGS__), \ - MACRO__(0x56BB, ## __VA_ARGS__), \ - MACRO__(0x56BC, ## __VA_ARGS__), \ - MACRO__(0x56BD, ## __VA_ARGS__) - -#define XE_DG2_G12_IDS(MACRO__, ...) \ - MACRO__(0x5696, ## __VA_ARGS__), \ - MACRO__(0x5697, ## __VA_ARGS__), \ - MACRO__(0x56A3, ## __VA_ARGS__), \ - MACRO__(0x56A4, ## __VA_ARGS__), \ - MACRO__(0x56B2, ## __VA_ARGS__), \ - MACRO__(0x56B3, ## __VA_ARGS__) - -#define XE_DG2_IDS(MACRO__, ...) \ - XE_DG2_G10_IDS(MACRO__, ## __VA_ARGS__),\ - XE_DG2_G11_IDS(MACRO__, ## __VA_ARGS__),\ - XE_DG2_G12_IDS(MACRO__, ## __VA_ARGS__) - -#define XE_ATS_M150_IDS(MACRO__, ...) \ - MACRO__(0x56C0, ## __VA_ARGS__), \ - MACRO__(0x56C2, ## __VA_ARGS__) - -#define XE_ATS_M75_IDS(MACRO__, ...) \ - MACRO__(0x56C1, ## __VA_ARGS__) - -#define XE_ATS_M_IDS(MACRO__, ...) \ - XE_ATS_M150_IDS(MACRO__, ## __VA_ARGS__),\ - XE_ATS_M75_IDS(MACRO__, ## __VA_ARGS__) - -/* MTL / ARL */ -#define XE_MTL_IDS(MACRO__, ...) \ - MACRO__(0x7D40, ## __VA_ARGS__), \ - MACRO__(0x7D41, ## __VA_ARGS__), \ - MACRO__(0x7D45, ## __VA_ARGS__), \ - MACRO__(0x7D51, ## __VA_ARGS__), \ - MACRO__(0x7D55, ## __VA_ARGS__), \ - MACRO__(0x7D60, ## __VA_ARGS__), \ - MACRO__(0x7D67, ## __VA_ARGS__), \ - MACRO__(0x7DD1, ## __VA_ARGS__), \ - MACRO__(0x7DD5, ## __VA_ARGS__) - -#define XE_LNL_IDS(MACRO__, ...) \ - MACRO__(0x6420, ## __VA_ARGS__), \ - MACRO__(0x64A0, ## __VA_ARGS__), \ - MACRO__(0x64B0, ## __VA_ARGS__) - -#endif -- cgit v1.2.3 From 3acbde3e9ef941fe6c847a007f72aefee0746226 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 30 May 2024 16:19:10 +0300 Subject: drm: move i915_hdcp_interface.h under include/drm/intel Clean up the top level include/drm directory by grouping all the Intel specific files under a common subdirectory. Cc: Daniel Vetter Cc: Dave Airlie Cc: Lucas De Marchi Cc: Tomas Winkler Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/5f53384118e33123d3c87b94cc8835360237698b.1717075103.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 2 +- drivers/gpu/drm/i915/display/intel_hdcp_gsc.c | 2 +- .../gpu/drm/i915/display/intel_hdcp_gsc_message.c | 2 +- drivers/gpu/drm/xe/display/xe_hdcp_gsc.c | 2 +- drivers/misc/mei/hdcp/mei_hdcp.c | 2 +- include/drm/i915_hdcp_interface.h | 547 --------------------- include/drm/intel/i915_hdcp_interface.h | 547 +++++++++++++++++++++ 7 files changed, 552 insertions(+), 552 deletions(-) delete mode 100644 include/drm/i915_hdcp_interface.h create mode 100644 include/drm/intel/i915_hdcp_interface.h (limited to 'include') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 012ff9e18b54..52d0fd2bdc82 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include "i915_vma.h" diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c index 35823e1f65d6..16afeb8a3a8d 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c @@ -3,7 +3,7 @@ * Copyright 2023, Intel Corporation. */ -#include +#include #include "gem/i915_gem_region.h" #include "gt/intel_gt.h" diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c index 240b00849f3d..6548e71b4c49 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include "i915_drv.h" #include "intel_hdcp_gsc_message.h" diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index d46f87a039f2..e44adbccf694 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include "abi/gsc_command_header_abi.h" diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c index e43ea536c947..323f10620d90 100644 --- a/drivers/misc/mei/hdcp/mei_hdcp.c +++ b/drivers/misc/mei/hdcp/mei_hdcp.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "mei_hdcp.h" diff --git a/include/drm/i915_hdcp_interface.h b/include/drm/i915_hdcp_interface.h deleted file mode 100644 index d776ed7dcd00..000000000000 --- a/include/drm/i915_hdcp_interface.h +++ /dev/null @@ -1,547 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0+) */ -/* - * Copyright © 2017-2019 Intel Corporation - * - * Authors: - * Ramalingam C - */ - -#ifndef _I915_HDCP_INTERFACE_H_ -#define _I915_HDCP_INTERFACE_H_ - -#include -#include -#include - -/** - * enum hdcp_port_type - HDCP port implementation type defined by ME/GSC FW - * @HDCP_PORT_TYPE_INVALID: Invalid hdcp port type - * @HDCP_PORT_TYPE_INTEGRATED: In-Host HDCP2.x port - * @HDCP_PORT_TYPE_LSPCON: HDCP2.2 discrete wired Tx port with LSPCON - * (HDMI 2.0) solution - * @HDCP_PORT_TYPE_CPDP: HDCP2.2 discrete wired Tx port using the CPDP (DP 1.3) - * solution - */ -enum hdcp_port_type { - HDCP_PORT_TYPE_INVALID, - HDCP_PORT_TYPE_INTEGRATED, - HDCP_PORT_TYPE_LSPCON, - HDCP_PORT_TYPE_CPDP -}; - -/** - * enum hdcp_wired_protocol - HDCP adaptation used on the port - * @HDCP_PROTOCOL_INVALID: Invalid HDCP adaptation protocol - * @HDCP_PROTOCOL_HDMI: HDMI adaptation of HDCP used on the port - * @HDCP_PROTOCOL_DP: DP adaptation of HDCP used on the port - */ -enum hdcp_wired_protocol { - HDCP_PROTOCOL_INVALID, - HDCP_PROTOCOL_HDMI, - HDCP_PROTOCOL_DP -}; - -enum hdcp_ddi { - HDCP_DDI_INVALID_PORT = 0x0, - - HDCP_DDI_B = 1, - HDCP_DDI_C, - HDCP_DDI_D, - HDCP_DDI_E, - HDCP_DDI_F, - HDCP_DDI_A = 7, - HDCP_DDI_RANGE_END = HDCP_DDI_A, -}; - -/** - * enum hdcp_transcoder - ME/GSC Firmware defined index for transcoders - * @HDCP_INVALID_TRANSCODER: Index for Invalid transcoder - * @HDCP_TRANSCODER_EDP: Index for EDP Transcoder - * @HDCP_TRANSCODER_DSI0: Index for DSI0 Transcoder - * @HDCP_TRANSCODER_DSI1: Index for DSI1 Transcoder - * @HDCP_TRANSCODER_A: Index for Transcoder A - * @HDCP_TRANSCODER_B: Index for Transcoder B - * @HDCP_TRANSCODER_C: Index for Transcoder C - * @HDCP_TRANSCODER_D: Index for Transcoder D - */ -enum hdcp_transcoder { - HDCP_INVALID_TRANSCODER = 0x00, - HDCP_TRANSCODER_EDP, - HDCP_TRANSCODER_DSI0, - HDCP_TRANSCODER_DSI1, - HDCP_TRANSCODER_A = 0x10, - HDCP_TRANSCODER_B, - HDCP_TRANSCODER_C, - HDCP_TRANSCODER_D -}; - -/** - * struct hdcp_port_data - intel specific HDCP port data - * @hdcp_ddi: ddi index as per ME/GSC FW - * @hdcp_transcoder: transcoder index as per ME/GSC FW - * @port_type: HDCP port type as per ME/GSC FW classification - * @protocol: HDCP adaptation as per ME/GSC FW - * @k: No of streams transmitted on a port. Only on DP MST this is != 1 - * @seq_num_m: Count of RepeaterAuth_Stream_Manage msg propagated. - * Initialized to 0 on AKE_INIT. Incremented after every successful - * transmission of RepeaterAuth_Stream_Manage message. When it rolls - * over re-Auth has to be triggered. - * @streams: struct hdcp2_streamid_type[k]. Defines the type and id for the - * streams - */ -struct hdcp_port_data { - enum hdcp_ddi hdcp_ddi; - enum hdcp_transcoder hdcp_transcoder; - u8 port_type; - u8 protocol; - u16 k; - u32 seq_num_m; - struct hdcp2_streamid_type *streams; -}; - -/** - * struct i915_hdcp_ops- ops for HDCP2.2 services. - * @owner: Module providing the ops - * @initiate_hdcp2_session: Initiate a Wired HDCP2.2 Tx Session. - * And Prepare AKE_Init. - * @verify_receiver_cert_prepare_km: Verify the Receiver Certificate - * AKE_Send_Cert and prepare - * AKE_Stored_Km/AKE_No_Stored_Km - * @verify_hprime: Verify AKE_Send_H_prime - * @store_pairing_info: Store pairing info received - * @initiate_locality_check: Prepare LC_Init - * @verify_lprime: Verify lprime - * @get_session_key: Prepare SKE_Send_Eks - * @repeater_check_flow_prepare_ack: Validate the Downstream topology - * and prepare rep_ack - * @verify_mprime: Verify mprime - * @enable_hdcp_authentication: Mark a port as authenticated. - * @close_hdcp_session: Close the Wired HDCP Tx session per port. - * This also disables the authenticated state of the port. - */ -struct i915_hdcp_ops { - /** - * @owner: hdcp module - */ - struct module *owner; - - int (*initiate_hdcp2_session)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ake_init *ake_data); - int (*verify_receiver_cert_prepare_km)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ake_send_cert - *rx_cert, - bool *km_stored, - struct hdcp2_ake_no_stored_km - *ek_pub_km, - size_t *msg_sz); - int (*verify_hprime)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ake_send_hprime *rx_hprime); - int (*store_pairing_info)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ake_send_pairing_info - *pairing_info); - int (*initiate_locality_check)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_lc_init *lc_init_data); - int (*verify_lprime)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_lc_send_lprime *rx_lprime); - int (*get_session_key)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ske_send_eks *ske_data); - int (*repeater_check_flow_prepare_ack)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_rep_send_receiverid_list - *rep_topology, - struct hdcp2_rep_send_ack - *rep_send_ack); - int (*verify_mprime)(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_rep_stream_ready *stream_ready); - int (*enable_hdcp_authentication)(struct device *dev, - struct hdcp_port_data *data); - int (*close_hdcp_session)(struct device *dev, - struct hdcp_port_data *data); -}; - -/** - * struct i915_hdcp_arbiter - Used for communication between i915 - * and hdcp drivers for the HDCP2.2 services - */ -struct i915_hdcp_arbiter { - /** - * @hdcp_dev: device that provides the HDCP2.2 service from MEI Bus. - */ - struct device *hdcp_dev; - - /** - * @ops: Ops implemented by hdcp driver or intel_hdcp_gsc, used by i915 - * driver. - */ - const struct i915_hdcp_ops *ops; - - /** - * @mutex: To protect the above members. - */ - struct mutex mutex; -}; - -/* fw_hdcp_status: Enumeration of all HDCP Status Codes */ -enum fw_hdcp_status { - FW_HDCP_STATUS_SUCCESS = 0x0000, - - /* WiDi Generic Status Codes */ - FW_HDCP_STATUS_INTERNAL_ERROR = 0x1000, - FW_HDCP_STATUS_UNKNOWN_ERROR = 0x1001, - FW_HDCP_STATUS_INCORRECT_API_VERSION = 0x1002, - FW_HDCP_STATUS_INVALID_FUNCTION = 0x1003, - FW_HDCP_STATUS_INVALID_BUFFER_LENGTH = 0x1004, - FW_HDCP_STATUS_INVALID_PARAMS = 0x1005, - FW_HDCP_STATUS_AUTHENTICATION_FAILED = 0x1006, - - /* WiDi Status Codes */ - FW_HDCP_INVALID_SESSION_STATE = 0x6000, - FW_HDCP_SRM_FRAGMENT_UNEXPECTED = 0x6001, - FW_HDCP_SRM_INVALID_LENGTH = 0x6002, - FW_HDCP_SRM_FRAGMENT_OFFSET_INVALID = 0x6003, - FW_HDCP_SRM_VERIFICATION_FAILED = 0x6004, - FW_HDCP_SRM_VERSION_TOO_OLD = 0x6005, - FW_HDCP_RX_CERT_VERIFICATION_FAILED = 0x6006, - FW_HDCP_RX_REVOKED = 0x6007, - FW_HDCP_H_VERIFICATION_FAILED = 0x6008, - FW_HDCP_REPEATER_CHECK_UNEXPECTED = 0x6009, - FW_HDCP_TOPOLOGY_MAX_EXCEEDED = 0x600A, - FW_HDCP_V_VERIFICATION_FAILED = 0x600B, - FW_HDCP_L_VERIFICATION_FAILED = 0x600C, - FW_HDCP_STREAM_KEY_ALLOC_FAILED = 0x600D, - FW_HDCP_BASE_KEY_RESET_FAILED = 0x600E, - FW_HDCP_NONCE_GENERATION_FAILED = 0x600F, - FW_HDCP_STATUS_INVALID_E_KEY_STATE = 0x6010, - FW_HDCP_STATUS_INVALID_CS_ICV = 0x6011, - FW_HDCP_STATUS_INVALID_KB_KEY_STATE = 0x6012, - FW_HDCP_STATUS_INVALID_PAVP_MODE_ICV = 0x6013, - FW_HDCP_STATUS_INVALID_PAVP_MODE = 0x6014, - FW_HDCP_STATUS_LC_MAX_ATTEMPTS = 0x6015, - - /* New status for HDCP 2.1 */ - FW_HDCP_STATUS_MISMATCH_IN_M = 0x6016, - - /* New status code for HDCP 2.2 Rx */ - FW_HDCP_STATUS_RX_PROV_NOT_ALLOWED = 0x6017, - FW_HDCP_STATUS_RX_PROV_WRONG_SUBJECT = 0x6018, - FW_HDCP_RX_NEEDS_PROVISIONING = 0x6019, - FW_HDCP_BKSV_ICV_AUTH_FAILED = 0x6020, - FW_HDCP_STATUS_INVALID_STREAM_ID = 0x6021, - FW_HDCP_STATUS_CHAIN_NOT_INITIALIZED = 0x6022, - FW_HDCP_FAIL_NOT_EXPECTED = 0x6023, - FW_HDCP_FAIL_HDCP_OFF = 0x6024, - FW_HDCP_FAIL_INVALID_PAVP_MEMORY_MODE = 0x6025, - FW_HDCP_FAIL_AES_ECB_FAILURE = 0x6026, - FW_HDCP_FEATURE_NOT_SUPPORTED = 0x6027, - FW_HDCP_DMA_READ_ERROR = 0x6028, - FW_HDCP_DMA_WRITE_ERROR = 0x6029, - FW_HDCP_FAIL_INVALID_PACKET_SIZE = 0x6030, - FW_HDCP_H264_PARSING_ERROR = 0x6031, - FW_HDCP_HDCP2_ERRATA_VIDEO_VIOLATION = 0x6032, - FW_HDCP_HDCP2_ERRATA_AUDIO_VIOLATION = 0x6033, - FW_HDCP_TX_ACTIVE_ERROR = 0x6034, - FW_HDCP_MODE_CHANGE_ERROR = 0x6035, - FW_HDCP_STREAM_TYPE_ERROR = 0x6036, - FW_HDCP_STREAM_MANAGE_NOT_POSSIBLE = 0x6037, - - FW_HDCP_STATUS_PORT_INVALID_COMMAND = 0x6038, - FW_HDCP_STATUS_UNSUPPORTED_PROTOCOL = 0x6039, - FW_HDCP_STATUS_INVALID_PORT_INDEX = 0x603a, - FW_HDCP_STATUS_TX_AUTH_NEEDED = 0x603b, - FW_HDCP_STATUS_NOT_INTEGRATED_PORT = 0x603c, - FW_HDCP_STATUS_SESSION_MAX_REACHED = 0x603d, - - /* hdcp capable bit is not set in rx_caps(error is unique to DP) */ - FW_HDCP_STATUS_NOT_HDCP_CAPABLE = 0x6041, - - FW_HDCP_STATUS_INVALID_STREAM_COUNT = 0x6042, -}; - -#define HDCP_API_VERSION 0x00010000 - -#define HDCP_M_LEN 16 -#define HDCP_KH_LEN 16 - -/* Payload Buffer size(Excluding Header) for CMDs and corresponding response */ -/* Wired_Tx_AKE */ -#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN (4 + 1) -#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_OUT (4 + 8 + 3) - -#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN (4 + 522 + 8 + 3) -#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MIN_OUT (4 + 1 + 3 + 16 + 16) -#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MAX_OUT (4 + 1 + 3 + 128) - -#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN (4 + 32) -#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_OUT (4) - -#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN (4 + 16) -#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_OUT (4) - -#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN (4) -#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_OUT (4) - -/* Wired_Tx_LC */ -#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN (4) -#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_OUT (4 + 8) - -#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN (4 + 32) -#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_OUT (4) - -/* Wired_Tx_SKE */ -#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN (4) -#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_OUT (4 + 16 + 8) - -/* Wired_Tx_SKE */ -#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN (4 + 1) -#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_OUT (4) - -/* Wired_Tx_Repeater */ -#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN (4 + 2 + 3 + 16 + 155) -#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_OUT (4 + 1 + 16) - -#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN (4 + 3 + \ - 32 + 2 + 2) - -#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_OUT (4) - -/* hdcp_command_id: Enumeration of all WIRED HDCP Command IDs */ -enum hdcp_command_id { - _WIDI_COMMAND_BASE = 0x00030000, - WIDI_INITIATE_HDCP2_SESSION = _WIDI_COMMAND_BASE, - HDCP_GET_SRM_STATUS, - HDCP_SEND_SRM_FRAGMENT, - - /* The wired HDCP Tx commands */ - _WIRED_COMMAND_BASE = 0x00031000, - WIRED_INITIATE_HDCP2_SESSION = _WIRED_COMMAND_BASE, - WIRED_VERIFY_RECEIVER_CERT, - WIRED_AKE_SEND_HPRIME, - WIRED_AKE_SEND_PAIRING_INFO, - WIRED_INIT_LOCALITY_CHECK, - WIRED_VALIDATE_LOCALITY, - WIRED_GET_SESSION_KEY, - WIRED_ENABLE_AUTH, - WIRED_VERIFY_REPEATER, - WIRED_REPEATER_AUTH_STREAM_REQ, - WIRED_CLOSE_SESSION, - - _WIRED_COMMANDS_COUNT, -}; - -union encrypted_buff { - u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN]; - u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN]; - struct { - u8 e_kh_km[HDCP_KH_LEN]; - u8 m[HDCP_M_LEN]; - } __packed; -}; - -/* HDCP HECI message header. All header values are little endian. */ -struct hdcp_cmd_header { - u32 api_version; - u32 command_id; - enum fw_hdcp_status status; - /* Length of the HECI message (excluding the header) */ - u32 buffer_len; -} __packed; - -/* Empty command request or response. No data follows the header. */ -struct hdcp_cmd_no_data { - struct hdcp_cmd_header header; -} __packed; - -/* Uniquely identifies the hdcp port being addressed for a given command. */ -struct hdcp_port_id { - u8 integrated_port_type; - /* physical_port is used until Gen11.5. Must be zero for Gen11.5+ */ - u8 physical_port; - /* attached_transcoder is for Gen11.5+. Set to zero for + */ + +#ifndef _I915_HDCP_INTERFACE_H_ +#define _I915_HDCP_INTERFACE_H_ + +#include +#include +#include + +/** + * enum hdcp_port_type - HDCP port implementation type defined by ME/GSC FW + * @HDCP_PORT_TYPE_INVALID: Invalid hdcp port type + * @HDCP_PORT_TYPE_INTEGRATED: In-Host HDCP2.x port + * @HDCP_PORT_TYPE_LSPCON: HDCP2.2 discrete wired Tx port with LSPCON + * (HDMI 2.0) solution + * @HDCP_PORT_TYPE_CPDP: HDCP2.2 discrete wired Tx port using the CPDP (DP 1.3) + * solution + */ +enum hdcp_port_type { + HDCP_PORT_TYPE_INVALID, + HDCP_PORT_TYPE_INTEGRATED, + HDCP_PORT_TYPE_LSPCON, + HDCP_PORT_TYPE_CPDP +}; + +/** + * enum hdcp_wired_protocol - HDCP adaptation used on the port + * @HDCP_PROTOCOL_INVALID: Invalid HDCP adaptation protocol + * @HDCP_PROTOCOL_HDMI: HDMI adaptation of HDCP used on the port + * @HDCP_PROTOCOL_DP: DP adaptation of HDCP used on the port + */ +enum hdcp_wired_protocol { + HDCP_PROTOCOL_INVALID, + HDCP_PROTOCOL_HDMI, + HDCP_PROTOCOL_DP +}; + +enum hdcp_ddi { + HDCP_DDI_INVALID_PORT = 0x0, + + HDCP_DDI_B = 1, + HDCP_DDI_C, + HDCP_DDI_D, + HDCP_DDI_E, + HDCP_DDI_F, + HDCP_DDI_A = 7, + HDCP_DDI_RANGE_END = HDCP_DDI_A, +}; + +/** + * enum hdcp_transcoder - ME/GSC Firmware defined index for transcoders + * @HDCP_INVALID_TRANSCODER: Index for Invalid transcoder + * @HDCP_TRANSCODER_EDP: Index for EDP Transcoder + * @HDCP_TRANSCODER_DSI0: Index for DSI0 Transcoder + * @HDCP_TRANSCODER_DSI1: Index for DSI1 Transcoder + * @HDCP_TRANSCODER_A: Index for Transcoder A + * @HDCP_TRANSCODER_B: Index for Transcoder B + * @HDCP_TRANSCODER_C: Index for Transcoder C + * @HDCP_TRANSCODER_D: Index for Transcoder D + */ +enum hdcp_transcoder { + HDCP_INVALID_TRANSCODER = 0x00, + HDCP_TRANSCODER_EDP, + HDCP_TRANSCODER_DSI0, + HDCP_TRANSCODER_DSI1, + HDCP_TRANSCODER_A = 0x10, + HDCP_TRANSCODER_B, + HDCP_TRANSCODER_C, + HDCP_TRANSCODER_D +}; + +/** + * struct hdcp_port_data - intel specific HDCP port data + * @hdcp_ddi: ddi index as per ME/GSC FW + * @hdcp_transcoder: transcoder index as per ME/GSC FW + * @port_type: HDCP port type as per ME/GSC FW classification + * @protocol: HDCP adaptation as per ME/GSC FW + * @k: No of streams transmitted on a port. Only on DP MST this is != 1 + * @seq_num_m: Count of RepeaterAuth_Stream_Manage msg propagated. + * Initialized to 0 on AKE_INIT. Incremented after every successful + * transmission of RepeaterAuth_Stream_Manage message. When it rolls + * over re-Auth has to be triggered. + * @streams: struct hdcp2_streamid_type[k]. Defines the type and id for the + * streams + */ +struct hdcp_port_data { + enum hdcp_ddi hdcp_ddi; + enum hdcp_transcoder hdcp_transcoder; + u8 port_type; + u8 protocol; + u16 k; + u32 seq_num_m; + struct hdcp2_streamid_type *streams; +}; + +/** + * struct i915_hdcp_ops- ops for HDCP2.2 services. + * @owner: Module providing the ops + * @initiate_hdcp2_session: Initiate a Wired HDCP2.2 Tx Session. + * And Prepare AKE_Init. + * @verify_receiver_cert_prepare_km: Verify the Receiver Certificate + * AKE_Send_Cert and prepare + * AKE_Stored_Km/AKE_No_Stored_Km + * @verify_hprime: Verify AKE_Send_H_prime + * @store_pairing_info: Store pairing info received + * @initiate_locality_check: Prepare LC_Init + * @verify_lprime: Verify lprime + * @get_session_key: Prepare SKE_Send_Eks + * @repeater_check_flow_prepare_ack: Validate the Downstream topology + * and prepare rep_ack + * @verify_mprime: Verify mprime + * @enable_hdcp_authentication: Mark a port as authenticated. + * @close_hdcp_session: Close the Wired HDCP Tx session per port. + * This also disables the authenticated state of the port. + */ +struct i915_hdcp_ops { + /** + * @owner: hdcp module + */ + struct module *owner; + + int (*initiate_hdcp2_session)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ake_init *ake_data); + int (*verify_receiver_cert_prepare_km)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ake_send_cert + *rx_cert, + bool *km_stored, + struct hdcp2_ake_no_stored_km + *ek_pub_km, + size_t *msg_sz); + int (*verify_hprime)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ake_send_hprime *rx_hprime); + int (*store_pairing_info)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ake_send_pairing_info + *pairing_info); + int (*initiate_locality_check)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_lc_init *lc_init_data); + int (*verify_lprime)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_lc_send_lprime *rx_lprime); + int (*get_session_key)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ske_send_eks *ske_data); + int (*repeater_check_flow_prepare_ack)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_rep_send_receiverid_list + *rep_topology, + struct hdcp2_rep_send_ack + *rep_send_ack); + int (*verify_mprime)(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_rep_stream_ready *stream_ready); + int (*enable_hdcp_authentication)(struct device *dev, + struct hdcp_port_data *data); + int (*close_hdcp_session)(struct device *dev, + struct hdcp_port_data *data); +}; + +/** + * struct i915_hdcp_arbiter - Used for communication between i915 + * and hdcp drivers for the HDCP2.2 services + */ +struct i915_hdcp_arbiter { + /** + * @hdcp_dev: device that provides the HDCP2.2 service from MEI Bus. + */ + struct device *hdcp_dev; + + /** + * @ops: Ops implemented by hdcp driver or intel_hdcp_gsc, used by i915 + * driver. + */ + const struct i915_hdcp_ops *ops; + + /** + * @mutex: To protect the above members. + */ + struct mutex mutex; +}; + +/* fw_hdcp_status: Enumeration of all HDCP Status Codes */ +enum fw_hdcp_status { + FW_HDCP_STATUS_SUCCESS = 0x0000, + + /* WiDi Generic Status Codes */ + FW_HDCP_STATUS_INTERNAL_ERROR = 0x1000, + FW_HDCP_STATUS_UNKNOWN_ERROR = 0x1001, + FW_HDCP_STATUS_INCORRECT_API_VERSION = 0x1002, + FW_HDCP_STATUS_INVALID_FUNCTION = 0x1003, + FW_HDCP_STATUS_INVALID_BUFFER_LENGTH = 0x1004, + FW_HDCP_STATUS_INVALID_PARAMS = 0x1005, + FW_HDCP_STATUS_AUTHENTICATION_FAILED = 0x1006, + + /* WiDi Status Codes */ + FW_HDCP_INVALID_SESSION_STATE = 0x6000, + FW_HDCP_SRM_FRAGMENT_UNEXPECTED = 0x6001, + FW_HDCP_SRM_INVALID_LENGTH = 0x6002, + FW_HDCP_SRM_FRAGMENT_OFFSET_INVALID = 0x6003, + FW_HDCP_SRM_VERIFICATION_FAILED = 0x6004, + FW_HDCP_SRM_VERSION_TOO_OLD = 0x6005, + FW_HDCP_RX_CERT_VERIFICATION_FAILED = 0x6006, + FW_HDCP_RX_REVOKED = 0x6007, + FW_HDCP_H_VERIFICATION_FAILED = 0x6008, + FW_HDCP_REPEATER_CHECK_UNEXPECTED = 0x6009, + FW_HDCP_TOPOLOGY_MAX_EXCEEDED = 0x600A, + FW_HDCP_V_VERIFICATION_FAILED = 0x600B, + FW_HDCP_L_VERIFICATION_FAILED = 0x600C, + FW_HDCP_STREAM_KEY_ALLOC_FAILED = 0x600D, + FW_HDCP_BASE_KEY_RESET_FAILED = 0x600E, + FW_HDCP_NONCE_GENERATION_FAILED = 0x600F, + FW_HDCP_STATUS_INVALID_E_KEY_STATE = 0x6010, + FW_HDCP_STATUS_INVALID_CS_ICV = 0x6011, + FW_HDCP_STATUS_INVALID_KB_KEY_STATE = 0x6012, + FW_HDCP_STATUS_INVALID_PAVP_MODE_ICV = 0x6013, + FW_HDCP_STATUS_INVALID_PAVP_MODE = 0x6014, + FW_HDCP_STATUS_LC_MAX_ATTEMPTS = 0x6015, + + /* New status for HDCP 2.1 */ + FW_HDCP_STATUS_MISMATCH_IN_M = 0x6016, + + /* New status code for HDCP 2.2 Rx */ + FW_HDCP_STATUS_RX_PROV_NOT_ALLOWED = 0x6017, + FW_HDCP_STATUS_RX_PROV_WRONG_SUBJECT = 0x6018, + FW_HDCP_RX_NEEDS_PROVISIONING = 0x6019, + FW_HDCP_BKSV_ICV_AUTH_FAILED = 0x6020, + FW_HDCP_STATUS_INVALID_STREAM_ID = 0x6021, + FW_HDCP_STATUS_CHAIN_NOT_INITIALIZED = 0x6022, + FW_HDCP_FAIL_NOT_EXPECTED = 0x6023, + FW_HDCP_FAIL_HDCP_OFF = 0x6024, + FW_HDCP_FAIL_INVALID_PAVP_MEMORY_MODE = 0x6025, + FW_HDCP_FAIL_AES_ECB_FAILURE = 0x6026, + FW_HDCP_FEATURE_NOT_SUPPORTED = 0x6027, + FW_HDCP_DMA_READ_ERROR = 0x6028, + FW_HDCP_DMA_WRITE_ERROR = 0x6029, + FW_HDCP_FAIL_INVALID_PACKET_SIZE = 0x6030, + FW_HDCP_H264_PARSING_ERROR = 0x6031, + FW_HDCP_HDCP2_ERRATA_VIDEO_VIOLATION = 0x6032, + FW_HDCP_HDCP2_ERRATA_AUDIO_VIOLATION = 0x6033, + FW_HDCP_TX_ACTIVE_ERROR = 0x6034, + FW_HDCP_MODE_CHANGE_ERROR = 0x6035, + FW_HDCP_STREAM_TYPE_ERROR = 0x6036, + FW_HDCP_STREAM_MANAGE_NOT_POSSIBLE = 0x6037, + + FW_HDCP_STATUS_PORT_INVALID_COMMAND = 0x6038, + FW_HDCP_STATUS_UNSUPPORTED_PROTOCOL = 0x6039, + FW_HDCP_STATUS_INVALID_PORT_INDEX = 0x603a, + FW_HDCP_STATUS_TX_AUTH_NEEDED = 0x603b, + FW_HDCP_STATUS_NOT_INTEGRATED_PORT = 0x603c, + FW_HDCP_STATUS_SESSION_MAX_REACHED = 0x603d, + + /* hdcp capable bit is not set in rx_caps(error is unique to DP) */ + FW_HDCP_STATUS_NOT_HDCP_CAPABLE = 0x6041, + + FW_HDCP_STATUS_INVALID_STREAM_COUNT = 0x6042, +}; + +#define HDCP_API_VERSION 0x00010000 + +#define HDCP_M_LEN 16 +#define HDCP_KH_LEN 16 + +/* Payload Buffer size(Excluding Header) for CMDs and corresponding response */ +/* Wired_Tx_AKE */ +#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN (4 + 1) +#define WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_OUT (4 + 8 + 3) + +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN (4 + 522 + 8 + 3) +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MIN_OUT (4 + 1 + 3 + 16 + 16) +#define WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_MAX_OUT (4 + 1 + 3 + 128) + +#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN (4 + 32) +#define WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_OUT (4) + +#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN (4 + 16) +#define WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_OUT (4) + +#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN (4) +#define WIRED_CMD_BUF_LEN_CLOSE_SESSION_OUT (4) + +/* Wired_Tx_LC */ +#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN (4) +#define WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_OUT (4 + 8) + +#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN (4 + 32) +#define WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_OUT (4) + +/* Wired_Tx_SKE */ +#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN (4) +#define WIRED_CMD_BUF_LEN_GET_SESSION_KEY_OUT (4 + 16 + 8) + +/* Wired_Tx_SKE */ +#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN (4 + 1) +#define WIRED_CMD_BUF_LEN_ENABLE_AUTH_OUT (4) + +/* Wired_Tx_Repeater */ +#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN (4 + 2 + 3 + 16 + 155) +#define WIRED_CMD_BUF_LEN_VERIFY_REPEATER_OUT (4 + 1 + 16) + +#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN (4 + 3 + \ + 32 + 2 + 2) + +#define WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_OUT (4) + +/* hdcp_command_id: Enumeration of all WIRED HDCP Command IDs */ +enum hdcp_command_id { + _WIDI_COMMAND_BASE = 0x00030000, + WIDI_INITIATE_HDCP2_SESSION = _WIDI_COMMAND_BASE, + HDCP_GET_SRM_STATUS, + HDCP_SEND_SRM_FRAGMENT, + + /* The wired HDCP Tx commands */ + _WIRED_COMMAND_BASE = 0x00031000, + WIRED_INITIATE_HDCP2_SESSION = _WIRED_COMMAND_BASE, + WIRED_VERIFY_RECEIVER_CERT, + WIRED_AKE_SEND_HPRIME, + WIRED_AKE_SEND_PAIRING_INFO, + WIRED_INIT_LOCALITY_CHECK, + WIRED_VALIDATE_LOCALITY, + WIRED_GET_SESSION_KEY, + WIRED_ENABLE_AUTH, + WIRED_VERIFY_REPEATER, + WIRED_REPEATER_AUTH_STREAM_REQ, + WIRED_CLOSE_SESSION, + + _WIRED_COMMANDS_COUNT, +}; + +union encrypted_buff { + u8 e_kpub_km[HDCP_2_2_E_KPUB_KM_LEN]; + u8 e_kh_km_m[HDCP_2_2_E_KH_KM_M_LEN]; + struct { + u8 e_kh_km[HDCP_KH_LEN]; + u8 m[HDCP_M_LEN]; + } __packed; +}; + +/* HDCP HECI message header. All header values are little endian. */ +struct hdcp_cmd_header { + u32 api_version; + u32 command_id; + enum fw_hdcp_status status; + /* Length of the HECI message (excluding the header) */ + u32 buffer_len; +} __packed; + +/* Empty command request or response. No data follows the header. */ +struct hdcp_cmd_no_data { + struct hdcp_cmd_header header; +} __packed; + +/* Uniquely identifies the hdcp port being addressed for a given command. */ +struct hdcp_port_id { + u8 integrated_port_type; + /* physical_port is used until Gen11.5. Must be zero for Gen11.5+ */ + u8 physical_port; + /* attached_transcoder is for Gen11.5+. Set to zero for Date: Wed, 5 Jun 2024 13:26:05 +1200 Subject: dma-buf: align fd_flags and heap_flags with dma_heap_allocation_data dma_heap_allocation_data defines the UAPI as follows: struct dma_heap_allocation_data { __u64 len; __u32 fd; __u32 fd_flags; __u64 heap_flags; }; However, dma_heap_buffer_alloc() casts both fd_flags and heap_flags into unsigned int. We're inconsistent with types in the non UAPI arguments. This patch fixes it. Signed-off-by: Barry Song Acked-by: John Stultz Signed-off-by: Sumit Semwal Link: https://patchwork.freedesktop.org/patch/msgid/20240605012605.5341-1-21cnbao@gmail.com --- drivers/dma-buf/dma-heap.c | 4 ++-- include/uapi/linux/dma-heap.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 84ae708fafe7..2298ca5e112e 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -50,8 +50,8 @@ static struct class *dma_heap_class; static DEFINE_XARRAY_ALLOC(dma_heap_minors); static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, - unsigned int fd_flags, - unsigned int heap_flags) + u32 fd_flags, + u64 heap_flags) { struct dma_buf *dmabuf; int fd; diff --git a/include/uapi/linux/dma-heap.h b/include/uapi/linux/dma-heap.h index 6f84fa08e074..a4cf716a49fa 100644 --- a/include/uapi/linux/dma-heap.h +++ b/include/uapi/linux/dma-heap.h @@ -19,7 +19,7 @@ #define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) /* Currently no heap flags */ -#define DMA_HEAP_VALID_HEAP_FLAGS (0) +#define DMA_HEAP_VALID_HEAP_FLAGS (0ULL) /** * struct dma_heap_allocation_data - metadata passed from userspace for -- cgit v1.2.3 From 73e1d104ef7f5c9843abf4686513b3706538572a Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 29 Apr 2023 07:49:07 -0400 Subject: drm/amdgpu: define new gfx12 uapi flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit define new gfx12 uapi flags Signed-off-by: Marek Olšák Acked-by: Hawking Zhang Signed-off-by: Alex Deucher --- include/uapi/drm/amdgpu_drm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 5b6c0055cfcf..e44362e74fa1 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -171,6 +171,8 @@ extern "C" { * may override the MTYPE selected in AMDGPU_VA_OP_MAP. */ #define AMDGPU_GEM_CREATE_EXT_COHERENT (1 << 15) +/* Set PTE.D and recompress during GTT->VRAM moves according to TILING flags. */ +#define AMDGPU_GEM_CREATE_GFX12_DCC (1 << 16) struct drm_amdgpu_gem_create_in { /** the requested memory size */ -- cgit v1.2.3 From 3ed96977a3c5b0a9b017d626600402be3089d4fc Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Tue, 4 Jun 2024 13:54:38 -0400 Subject: drm/mm: Remove unused drm_mm_replace_node Last caller was removed with commit 078a5b498d6a ("drm/tests: Remove slow tests"). Cc: Maxime Ripard Acked-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240604175438.48125-1-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_mm.c | 35 ----------------------------------- include/drm/drm_mm.h | 1 - 2 files changed, 36 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 8257f9d4f619..5ace481c1901 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -648,41 +648,6 @@ void drm_mm_remove_node(struct drm_mm_node *node) } EXPORT_SYMBOL(drm_mm_remove_node); -/** - * drm_mm_replace_node - move an allocation from @old to @new - * @old: drm_mm_node to remove from the allocator - * @new: drm_mm_node which should inherit @old's allocation - * - * This is useful for when drivers embed the drm_mm_node structure and hence - * can't move allocations by reassigning pointers. It's a combination of remove - * and insert with the guarantee that the allocation start will match. - */ -void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) -{ - struct drm_mm *mm = old->mm; - - DRM_MM_BUG_ON(!drm_mm_node_allocated(old)); - - *new = *old; - - __set_bit(DRM_MM_NODE_ALLOCATED_BIT, &new->flags); - list_replace(&old->node_list, &new->node_list); - rb_replace_node_cached(&old->rb, &new->rb, &mm->interval_tree); - - if (drm_mm_hole_follows(old)) { - list_replace(&old->hole_stack, &new->hole_stack); - rb_replace_node_cached(&old->rb_hole_size, - &new->rb_hole_size, - &mm->holes_size); - rb_replace_node(&old->rb_hole_addr, - &new->rb_hole_addr, - &mm->holes_addr); - } - - clear_bit_unlock(DRM_MM_NODE_ALLOCATED_BIT, &old->flags); -} -EXPORT_SYMBOL(drm_mm_replace_node); - /** * DOC: lru scan roster * diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index ac33ba1b18bc..f654874c4ce6 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -463,7 +463,6 @@ static inline int drm_mm_insert_node(struct drm_mm *mm, } void drm_mm_remove_node(struct drm_mm_node *node); -void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new); void drm_mm_init(struct drm_mm *mm, u64 start, u64 size); void drm_mm_takedown(struct drm_mm *mm); -- cgit v1.2.3 From 0d11307022978f1f395da587285c06c9cea47288 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 23 May 2024 19:44:29 +0200 Subject: drm/print: Add missing [drm] prefix to drm based WARN All drm_device based logging macros, except those related to WARN, include the [drm] prefix. Fix that. [ ] 0000:00:00.0: this is a warning [ ] 0000:00:00.0: drm_WARN_ON(true) vs [ ] 0000:00:00.0: [drm] this is a warning [ ] 0000:00:00.0: [drm] drm_WARN_ON(true) Signed-off-by: Michal Wajdeczko Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240523174429.800-1-michal.wajdeczko@intel.com Signed-off-by: Rodrigo Vivi --- include/drm/drm_print.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 089950ad8681..112f8830b372 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -632,12 +632,12 @@ void __drm_err(const char *format, ...); /* Helper for struct drm_device based WARNs */ #define drm_WARN(drm, condition, format, arg...) \ - WARN(condition, "%s %s: " format, \ + WARN(condition, "%s %s: [drm] " format, \ dev_driver_string((drm)->dev), \ dev_name((drm)->dev), ## arg) #define drm_WARN_ONCE(drm, condition, format, arg...) \ - WARN_ONCE(condition, "%s %s: " format, \ + WARN_ONCE(condition, "%s %s: [drm] " format, \ dev_driver_string((drm)->dev), \ dev_name((drm)->dev), ## arg) -- cgit v1.2.3 From 0d5edcc60abe9a02501f01e032bfa2432c1364de Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Thu, 16 May 2024 18:00:15 +0200 Subject: drm/print: Kill ___drm_dbg() There is no point in maintaining a separate print function, while there is __drm_dev_dbg() function that can work with a NULL device. Signed-off-by: Michal Wajdeczko Cc: Jani Nikula Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20240516160015.2260-1-michal.wajdeczko@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_print.c | 19 ------------------- include/drm/drm_print.h | 8 +++----- 2 files changed, 3 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index cf2efb44722c..7e16ce7c7c7a 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -323,25 +323,6 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev, } EXPORT_SYMBOL(__drm_dev_dbg); -void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...) -{ - struct va_format vaf; - va_list args; - - if (!__drm_debug_enabled(category)) - return; - - va_start(args, format); - vaf.fmt = format; - vaf.va = &args; - - printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV", - __builtin_return_address(0), &vaf); - - va_end(args); -} -EXPORT_SYMBOL(___drm_dbg); - void __drm_err(const char *format, ...) { struct va_format vaf; diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 112f8830b372..679a2086fbea 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -527,17 +527,15 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev, * Prefer drm_device based logging over device or prink based logging. */ -__printf(3, 4) -void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...); __printf(1, 2) void __drm_err(const char *format, ...); #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG) -#define __drm_dbg(cat, fmt, ...) ___drm_dbg(NULL, cat, fmt, ##__VA_ARGS__) +#define __drm_dbg(cat, fmt, ...) __drm_dev_dbg(NULL, NULL, cat, fmt, ##__VA_ARGS__) #else #define __drm_dbg(cat, fmt, ...) \ - _dynamic_func_call_cls(cat, fmt, ___drm_dbg, \ - cat, fmt, ##__VA_ARGS__) + _dynamic_func_call_cls(cat, fmt, __drm_dev_dbg, \ + NULL, cat, fmt, ##__VA_ARGS__) #endif /* Macros to make printk easier */ -- cgit v1.2.3 From c2ef66e9ad882ab4b055a86657c20c61d203f003 Mon Sep 17 00:00:00 2001 From: Michal Wajdeczko Date: Fri, 17 May 2024 18:34:05 +0200 Subject: drm/print: Improve drm_dbg_printer With recent introduction of a generic drm dev printk function, we can now store and use location where drm_dbg_printer was invoked and output it's symbolic name like we do for all drm debug prints. Cc: Jani Nikula Reviewed-by: Jani Nikula Signed-off-by: Michal Wajdeczko Link: https://patchwork.freedesktop.org/patch/msgid/20240517163406.2348-3-michal.wajdeczko@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_print.c | 3 +-- include/drm/drm_print.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c index 94e8f3542846..cf24dfdeb6b2 100644 --- a/drivers/gpu/drm/drm_print.c +++ b/drivers/gpu/drm/drm_print.c @@ -217,8 +217,7 @@ void __drm_printfn_dbg(struct drm_printer *p, struct va_format *vaf) if (!__drm_debug_enabled(category)) return; - /* Note: __builtin_return_address(0) is useless here. */ - __drm_dev_vprintk(dev, KERN_DEBUG, NULL, p->prefix, vaf); + __drm_dev_vprintk(dev, KERN_DEBUG, p->origin, p->prefix, vaf); } EXPORT_SYMBOL(__drm_printfn_dbg); diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h index 679a2086fbea..5d9dff5149c9 100644 --- a/include/drm/drm_print.h +++ b/include/drm/drm_print.h @@ -175,6 +175,7 @@ struct drm_printer { void (*printfn)(struct drm_printer *p, struct va_format *vaf); void (*puts)(struct drm_printer *p, const char *str); void *arg; + const void *origin; const char *prefix; enum drm_debug_category category; }; @@ -332,6 +333,7 @@ static inline struct drm_printer drm_dbg_printer(struct drm_device *drm, struct drm_printer p = { .printfn = __drm_printfn_dbg, .arg = drm, + .origin = (const void *)_THIS_IP_, /* it's fine as we will be inlined */ .prefix = prefix, .category = category, }; -- cgit v1.2.3 From df3fb27a74a4eeb1436129024a7e957c2e83a95e Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Tue, 4 Jun 2024 15:20:30 +0200 Subject: drm/mipi-dbi: Make bits per word configurable for pixel transfers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MIPI DCS write/set commands have 8 bit parameters except for the write_memory commands where it depends on the pixel format. drm_mipi_dbi does currently only support RGB565 which is 16-bit and it has to make sure that the pixels enters the SPI bus in big endian format since the MIPI DBI spec doesn't have support for little endian. drm_mipi_dbi is optimized for DBI interface option 3 which means that the 16-bit bytes are swapped by the upper layer if the SPI bus does not support 16 bits per word, signified by the swap_bytes member. In order to support both 16-bit and 24-bit pixel transfers we need a way to tell the DBI command layer the format of the buffer. Add a write_memory_bpw member that the upper layer can use to tell how many bits per word to use for the SPI transfer. v4: - Expand the commit message (Dmitry) Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240604-panel-mipi-dbi-rgb666-v4-3-d7c2bcb9b78d@tronnes.org Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_mipi_dbi.c | 14 ++++++++++---- include/drm/drm_mipi_dbi.h | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index fa8aba6dc81c..77f8a828d6e0 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -1079,7 +1079,7 @@ static int mipi_dbi_typec1_command_read(struct mipi_dbi *dbi, u8 *cmd, static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd, u8 *parameters, size_t num) { - unsigned int bpw = (*cmd == MIPI_DCS_WRITE_MEMORY_START) ? 16 : 8; + unsigned int bpw = 8; int ret; if (mipi_dbi_command_is_read(dbi, *cmd)) @@ -1091,6 +1091,9 @@ static int mipi_dbi_typec1_command(struct mipi_dbi *dbi, u8 *cmd, if (ret || !num) return ret; + if (*cmd == MIPI_DCS_WRITE_MEMORY_START) + bpw = dbi->write_memory_bpw; + return mipi_dbi_spi1_transfer(dbi, 1, parameters, num, bpw); } @@ -1184,8 +1187,8 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *dbi, u8 *cmd, if (ret || !num) return ret; - if (*cmd == MIPI_DCS_WRITE_MEMORY_START && !dbi->swap_bytes) - bpw = 16; + if (*cmd == MIPI_DCS_WRITE_MEMORY_START) + bpw = dbi->write_memory_bpw; spi_bus_lock(spi->controller); gpiod_set_value_cansleep(dbi->dc, 1); @@ -1256,12 +1259,15 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *dbi, dbi->spi = spi; dbi->read_commands = mipi_dbi_dcs_read_commands; + dbi->write_memory_bpw = 16; if (dc) { dbi->command = mipi_dbi_typec3_command; dbi->dc = dc; - if (!spi_is_bpw_supported(spi, 16)) + if (!spi_is_bpw_supported(spi, 16)) { + dbi->write_memory_bpw = 8; dbi->swap_bytes = true; + } } else { dbi->command = mipi_dbi_typec1_command; dbi->tx_buf9_len = SZ_16K; diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index e8e0f8d39f3a..b36596efdcc3 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -56,6 +56,11 @@ struct mipi_dbi { */ struct spi_device *spi; + /** + * @write_memory_bpw: Bits per word used on a MIPI_DCS_WRITE_MEMORY_START transfer + */ + unsigned int write_memory_bpw; + /** * @dc: Optional D/C gpio. */ -- cgit v1.2.3 From 4aebb79021f3e6c2b6fbb92a7d9c5d1e6ad0324a Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Tue, 4 Jun 2024 15:20:31 +0200 Subject: drm/mipi-dbi: Add support for DRM_FORMAT_RGB888 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DRM_FORMAT_RGB888 is 24 bits per pixel and it would be natural to send it on the SPI bus using a 24 bits per word transfer. The problem with this is that not all SPI controllers support 24 bpw. Since DRM_FORMAT_RGB888 is stored in memory as little endian and the SPI bus is big endian we use 8 bpw to always get the same pixel format on the bus: b8g8r8. The MIPI DCS specification lists the standard commands that can be sent over the MIPI DBI interface. The set_address_mode (36h) command has one bit in the parameter that controls RGB/BGR order. This means that the controller can be configured to receive the pixel as BGR. RGB888 is rarely supported on these controllers but RGB666 is very common. All datasheets I have seen do at least support the pixel format option where each color is sent as one byte and the 6 MSB's are used. All this put together means that we can send each pixel as b8g8r8 and an RGB666 capable controller sees this as b6x2g6x2r6x2. v4: - s/emulation_format/pixel_format/ (Dmitry) Reviewed-by: Dmitry Baryshkov Link: https://patchwork.freedesktop.org/patch/msgid/20240604-panel-mipi-dbi-rgb666-v4-4-d7c2bcb9b78d@tronnes.org Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_mipi_dbi.c | 29 +++++++++++++++++++++++++---- include/drm/drm_mipi_dbi.h | 5 +++++ 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 77f8a828d6e0..1661190c29a2 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -206,6 +206,7 @@ int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer * struct drm_rect *clip, bool swap, struct drm_format_conv_state *fmtcnv_state) { + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev); struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0); struct iosys_map dst_map = IOSYS_MAP_INIT_VADDR(dst); int ret; @@ -222,8 +223,18 @@ int mipi_dbi_buf_copy(void *dst, struct iosys_map *src, struct drm_framebuffer * else drm_fb_memcpy(&dst_map, NULL, src, fb, clip); break; + case DRM_FORMAT_RGB888: + drm_fb_memcpy(&dst_map, NULL, src, fb, clip); + break; case DRM_FORMAT_XRGB8888: - drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, fmtcnv_state, swap); + switch (dbidev->pixel_format) { + case DRM_FORMAT_RGB565: + drm_fb_xrgb8888_to_rgb565(&dst_map, NULL, src, fb, clip, fmtcnv_state, swap); + break; + case DRM_FORMAT_RGB888: + drm_fb_xrgb8888_to_rgb888(&dst_map, NULL, src, fb, clip, fmtcnv_state); + break; + } break; default: drm_err_once(fb->dev, "Format is not supported: %p4cc\n", @@ -260,9 +271,11 @@ static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb, struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(fb->dev); unsigned int height = rect->y2 - rect->y1; unsigned int width = rect->x2 - rect->x1; + const struct drm_format_info *dst_format; struct mipi_dbi *dbi = &dbidev->dbi; bool swap = dbi->swap_bytes; int ret = 0; + size_t len; bool full; void *tr; @@ -283,8 +296,13 @@ static void mipi_dbi_fb_dirty(struct iosys_map *src, struct drm_framebuffer *fb, mipi_dbi_set_window_address(dbidev, rect->x1, rect->x2 - 1, rect->y1, rect->y2 - 1); - ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr, - width * height * 2); + if (fb->format->format == DRM_FORMAT_XRGB8888) + dst_format = drm_format_info(dbidev->pixel_format); + else + dst_format = fb->format; + len = drm_format_info_min_pitch(dst_format, 0, width) * height; + + ret = mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, tr, len); err_msg: if (ret) drm_err_once(fb->dev, "Failed to update display %d\n", ret); @@ -572,7 +590,7 @@ static const uint32_t mipi_dbi_formats[] = { * has one fixed &drm_display_mode which is rotated according to @rotation. * This mode is used to set the mode config min/max width/height properties. * - * Use mipi_dbi_dev_init() if you don't need custom formats. + * Use mipi_dbi_dev_init() if you want native RGB565 and emulated XRGB8888 format. * * Note: * Some of the helper functions expects RGB565 to be the default format and the @@ -631,6 +649,9 @@ int mipi_dbi_dev_init_with_formats(struct mipi_dbi_dev *dbidev, drm->mode_config.min_height = dbidev->mode.vdisplay; drm->mode_config.max_height = dbidev->mode.vdisplay; dbidev->rotation = rotation; + dbidev->pixel_format = formats[0]; + if (formats[0] == DRM_FORMAT_RGB888) + dbidev->dbi.write_memory_bpw = 8; DRM_DEBUG_KMS("rotation = %u\n", rotation); diff --git a/include/drm/drm_mipi_dbi.h b/include/drm/drm_mipi_dbi.h index b36596efdcc3..f45f9612c0bc 100644 --- a/include/drm/drm_mipi_dbi.h +++ b/include/drm/drm_mipi_dbi.h @@ -101,6 +101,11 @@ struct mipi_dbi_dev { */ struct drm_display_mode mode; + /** + * @pixel_format: Native pixel format (DRM_FORMAT\_\*) + */ + u32 pixel_format; + /** * @tx_buf: Buffer used for transfer (copy clip rect area) */ -- cgit v1.2.3 From 76dbc41608167d531f9c45d60054fd1f76498785 Mon Sep 17 00:00:00 2001 From: Balasubramani Vivekanandan Date: Tue, 4 Jun 2024 19:30:21 +0530 Subject: drm/i915/display/bmg: Add platform descriptor Platform descriptor defined and PCI IDs added for Battlemage. Signed-off-by: Balasubramani Vivekanandan Reviewed-by: Radhakrishna Sripada Signed-off-by: Radhakrishna Sripada Link: https://patchwork.freedesktop.org/patch/msgid/20240604140021.1357502-1-balasubramani.vivekanandan@intel.com --- drivers/gpu/drm/i915/display/intel_display_device.c | 5 +++++ drivers/gpu/drm/i915/display/intel_display_device.h | 2 ++ include/drm/intel/i915_pciids.h | 8 ++++++++ 3 files changed, 15 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index b35422da7f6c..dd7dce4b0e7a 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1110,6 +1110,10 @@ static const struct platform_desc lnl_desc = { PLATFORM(LUNARLAKE), }; +static const struct platform_desc bmg_desc = { + PLATFORM(BATTLEMAGE), +}; + __diag_pop(); /* @@ -1178,6 +1182,7 @@ static const struct { INTEL_DG2_IDS(INTEL_DISPLAY_DEVICE, &dg2_desc), INTEL_MTL_IDS(INTEL_DISPLAY_DEVICE, &mtl_desc), INTEL_LNL_IDS(INTEL_DISPLAY_DEVICE, &lnl_desc), + INTEL_BMG_IDS(INTEL_DISPLAY_DEVICE, &bmg_desc), }; static const struct { diff --git a/drivers/gpu/drm/i915/display/intel_display_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index e1d9947394dc..44cda6c3e4d8 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -68,6 +68,8 @@ enum intel_display_platform { INTEL_DISPLAY_METEORLAKE, /* Display ver 20 (based on GMD ID) */ INTEL_DISPLAY_LUNARLAKE, + /* Display ver 14.1 (based on GMD ID) */ + INTEL_DISPLAY_BATTLEMAGE, }; enum intel_display_subplatform { diff --git a/include/drm/intel/i915_pciids.h b/include/drm/intel/i915_pciids.h index 7ae7ee11ef38..b21374f76df2 100644 --- a/include/drm/intel/i915_pciids.h +++ b/include/drm/intel/i915_pciids.h @@ -789,4 +789,12 @@ MACRO__(0x64A0, ## __VA_ARGS__), \ MACRO__(0x64B0, ## __VA_ARGS__) +/* BMG */ +#define INTEL_BMG_IDS(MACRO__, ...) \ + MACRO__(0xE202, ## __VA_ARGS__), \ + MACRO__(0xE20B, ## __VA_ARGS__), \ + MACRO__(0xE20C, ## __VA_ARGS__), \ + MACRO__(0xE20D, ## __VA_ARGS__), \ + MACRO__(0xE212, ## __VA_ARGS__) + #endif /* _I915_PCIIDS_H */ -- cgit v1.2.3 From 24d07f114e4ec7608659a4ef18307f76739c72a8 Mon Sep 17 00:00:00 2001 From: Jocelyn Falempe Date: Mon, 3 Jun 2024 11:47:26 +0200 Subject: drm/panic: Add a set_pixel() callback to drm_scanout_buffer This allows drivers to draw the pixel, and handle tiling, or specific color formats. v2: * Use fg_color for blit() functions (Javier Martinez Canillas) Signed-off-by: Jocelyn Falempe Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20240603095343.39588-3-jfalempe@redhat.com --- drivers/gpu/drm/drm_panic.c | 120 ++++++++++++++++++++++++++++---------------- include/drm/drm_panic.h | 9 ++++ 2 files changed, 85 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c index 056494ae1ede..5dc9e98108ed 100644 --- a/drivers/gpu/drm/drm_panic.c +++ b/drivers/gpu/drm/drm_panic.c @@ -247,40 +247,54 @@ static void drm_panic_blit32(struct iosys_map *dmap, unsigned int dpitch, iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, fg32); } +static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, + const u8 *sbuf8, unsigned int spitch, u32 fg_color) +{ + unsigned int y, x; + + for (y = 0; y < drm_rect_height(clip); y++) + for (x = 0; x < drm_rect_width(clip); x++) + if (drm_panic_is_pixel_fg(sbuf8, spitch, x, y)) + sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); +} + /* * drm_panic_blit - convert a monochrome image to a linear framebuffer - * @dmap: destination iosys_map - * @dpitch: destination pitch in bytes + * @sb: destination scanout buffer + * @clip: destination rectangle * @sbuf8: source buffer, in monochrome format, 8 pixels per byte. * @spitch: source pitch in bytes - * @height: height of the image to copy, in pixels - * @width: width of the image to copy, in pixels * @fg_color: foreground color, in destination format - * @pixel_width: pixel width in bytes. * * This can be used to draw a font character, which is a monochrome image, to a * framebuffer in other supported format. */ -static void drm_panic_blit(struct iosys_map *dmap, unsigned int dpitch, - const u8 *sbuf8, unsigned int spitch, - unsigned int height, unsigned int width, - u32 fg_color, unsigned int pixel_width) +static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, + const u8 *sbuf8, unsigned int spitch, u32 fg_color) { - switch (pixel_width) { + struct iosys_map map; + + if (sb->set_pixel) + return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, fg_color); + + map = sb->map[0]; + iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); + + switch (sb->format->cpp[0]) { case 2: - drm_panic_blit16(dmap, dpitch, sbuf8, spitch, - height, width, fg_color); + drm_panic_blit16(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), fg_color); break; case 3: - drm_panic_blit24(dmap, dpitch, sbuf8, spitch, - height, width, fg_color); + drm_panic_blit24(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), fg_color); break; case 4: - drm_panic_blit32(dmap, dpitch, sbuf8, spitch, - height, width, fg_color); + drm_panic_blit32(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), fg_color); break; default: - WARN_ONCE(1, "Can't blit with pixel width %d\n", pixel_width); + WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); } } @@ -324,33 +338,51 @@ static void drm_panic_fill32(struct iosys_map *dmap, unsigned int dpitch, iosys_map_wr(dmap, y * dpitch + x * sizeof(u32), u32, color); } +static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb, + struct drm_rect *clip, + u32 color) +{ + unsigned int y, x; + + for (y = 0; y < drm_rect_height(clip); y++) + for (x = 0; x < drm_rect_width(clip); x++) + sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color); +} + /* * drm_panic_fill - Fill a rectangle with a color - * @dmap: destination iosys_map, pointing to the top left corner of the rectangle - * @dpitch: destination pitch in bytes - * @height: height of the rectangle, in pixels - * @width: width of the rectangle, in pixels - * @color: color to fill the rectangle. - * @pixel_width: pixel width in bytes + * @sb: destination scanout buffer + * @clip: destination rectangle + * @color: foreground color, in destination format * * Fill a rectangle with a color, in a linear framebuffer. */ -static void drm_panic_fill(struct iosys_map *dmap, unsigned int dpitch, - unsigned int height, unsigned int width, - u32 color, unsigned int pixel_width) +static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip, + u32 color) { - switch (pixel_width) { + struct iosys_map map; + + if (sb->set_pixel) + return drm_panic_fill_pixel(sb, clip, color); + + map = sb->map[0]; + iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); + + switch (sb->format->cpp[0]) { case 2: - drm_panic_fill16(dmap, dpitch, height, width, color); + drm_panic_fill16(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); break; case 3: - drm_panic_fill24(dmap, dpitch, height, width, color); + drm_panic_fill24(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); break; case 4: - drm_panic_fill32(dmap, dpitch, height, width, color); + drm_panic_fill32(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); break; default: - WARN_ONCE(1, "Can't fill with pixel width %d\n", pixel_width); + WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); } } @@ -383,25 +415,24 @@ static void draw_txt_rectangle(struct drm_scanout_buffer *sb, int i, j; const u8 *src; size_t font_pitch = DIV_ROUND_UP(font->width, 8); - struct iosys_map dst; - unsigned int px_width = sb->format->cpp[0]; - int left = 0; + struct drm_rect rec; msg_lines = min(msg_lines, drm_rect_height(clip) / font->height); for (i = 0; i < msg_lines; i++) { size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width); + rec.y1 = clip->y1 + i * font->height; + rec.y2 = rec.y1 + font->height; + rec.x1 = clip->x1; + if (centered) - left = (drm_rect_width(clip) - (line_len * font->width)) / 2; + rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2; - dst = sb->map[0]; - iosys_map_incr(&dst, (clip->y1 + i * font->height) * sb->pitch[0] + - (clip->x1 + left) * px_width); for (j = 0; j < line_len; j++) { src = get_char_bitmap(font, msg[i].txt[j], font_pitch); - drm_panic_blit(&dst, sb->pitch[0], src, font_pitch, - font->height, font->width, color, px_width); - iosys_map_incr(&dst, font->width * px_width); + rec.x2 = rec.x1 + font->width; + drm_panic_blit(sb, &rec, src, font_pitch, color); + rec.x1 += font->width; } } } @@ -416,7 +447,7 @@ static void draw_panic_static(struct drm_scanout_buffer *sb) u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR; u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR; const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); - struct drm_rect r_logo, r_msg; + struct drm_rect r_screen, r_logo, r_msg; if (!font) return; @@ -424,6 +455,8 @@ static void draw_panic_static(struct drm_scanout_buffer *sb) fg_color = convert_from_xrgb8888(fg_color, sb->format->format); bg_color = convert_from_xrgb8888(bg_color, sb->format->format); + r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); + r_logo = DRM_RECT_INIT(0, 0, get_max_line_len(logo, logo_lines) * font->width, logo_lines * font->height); @@ -435,8 +468,7 @@ static void draw_panic_static(struct drm_scanout_buffer *sb) drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2); /* Fill with the background color, and draw text on top */ - drm_panic_fill(&sb->map[0], sb->pitch[0], sb->height, sb->width, - bg_color, sb->format->cpp[0]); + drm_panic_fill(sb, &r_screen, bg_color); if ((r_msg.x1 >= drm_rect_width(&r_logo) || r_msg.y1 >= drm_rect_height(&r_logo)) && drm_rect_width(&r_logo) < sb->width && drm_rect_height(&r_logo) < sb->height) { diff --git a/include/drm/drm_panic.h b/include/drm/drm_panic.h index 822dbb1aa9d6..73bb3f3d9ed9 100644 --- a/include/drm/drm_panic.h +++ b/include/drm/drm_panic.h @@ -50,6 +50,15 @@ struct drm_scanout_buffer { * @pitch: Length in bytes between the start of two consecutive lines. */ unsigned int pitch[DRM_FORMAT_MAX_PLANES]; + + /** + * @set_pixel: Optional function, to set a pixel color on the + * framebuffer. It allows to handle special tiling format inside the + * driver. + */ + void (*set_pixel)(struct drm_scanout_buffer *sb, unsigned int x, + unsigned int y, u32 color); + }; /** -- cgit v1.2.3 From 1f020495458396766496ee067130f507a4d718e4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 31 May 2024 22:37:46 +0200 Subject: drm/bridge: Drop drm_bridge_chain_mode_fixup There are no users left of drm_bridge_chain_mode_fixup() and we do not want to have this function available, so drop it. Signed-off-by: Sam Ravnborg Reviewed-by: Maxime Ripard Reviewed-by: Laurent Pinchart Cc: Laurent Pinchart Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20240531-bridge_chain_mode-v1-2-8b49e36c5dd3@ravnborg.org --- drivers/gpu/drm/drm_bridge.c | 37 ------------------------------------- include/drm/drm_bridge.h | 3 --- 2 files changed, 40 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 584d109330ab..d44f055dbe3e 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -467,43 +467,6 @@ void drm_bridge_detach(struct drm_bridge *bridge) * needed, in order to gradually transition to the new model. */ -/** - * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the - * encoder chain - * @bridge: bridge control structure - * @mode: desired mode to be set for the bridge - * @adjusted_mode: updated mode that works for this bridge - * - * Calls &drm_bridge_funcs.mode_fixup for all the bridges in the - * encoder chain, starting from the first bridge to the last. - * - * Note: the bridge passed should be the one closest to the encoder - * - * RETURNS: - * true on success, false on failure - */ -bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct drm_encoder *encoder; - - if (!bridge) - return true; - - encoder = bridge->encoder; - list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) { - if (!bridge->funcs->mode_fixup) - continue; - - if (!bridge->funcs->mode_fixup(bridge, mode, adjusted_mode)) - return false; - } - - return true; -} -EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); - /** * drm_bridge_chain_mode_valid - validate the mode against all bridges in the * encoder chain. diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 4baca0d9107b..5cf41f92d1f0 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -855,9 +855,6 @@ drm_bridge_chain_get_first_bridge(struct drm_encoder *encoder) #define drm_for_each_bridge_in_chain(encoder, bridge) \ list_for_each_entry(bridge, &(encoder)->bridge_chain, chain_node) -bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); enum drm_mode_status drm_bridge_chain_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, -- cgit v1.2.3 From a20c6d954d75b2e188618e36de43d13d413d4e06 Mon Sep 17 00:00:00 2001 From: Mitul Golani Date: Mon, 10 Jun 2024 12:51:58 +0530 Subject: drm/dp: Add refresh rate divider to struct representing AS SDP Add target_rr_divider to structure representing AS SDP. It is valid only in FAVT mode, sink device ignores the bit in AVT mode. --v2: - Update commit header and send patch to dri-devel. Signed-off-by: Mitul Golani Reviewed-by: Arun R Murthy Acked-by: Maxime Ripard Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240610072203.24956-6-mitulkumar.ajitkumar.golani@intel.com --- include/drm/display/drm_dp_helper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 8bed890eec2c..393dbf8cf6ab 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -122,6 +122,7 @@ struct drm_dp_as_sdp { int target_rr; int duration_incr_ms; int duration_decr_ms; + bool target_rr_divider; enum operation_mode mode; }; -- cgit v1.2.3 From 91930fc0394b3b54c6a8a3333b2b52c923cf6c52 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Fri, 7 Jun 2024 16:49:09 +0300 Subject: drm/display: Add missing Panel Replay Enable SU Region ET bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add missing Panel Replay Enable SU Region ET bit defined in DP2.1 specification. Signed-off-by: Jouni Högander Reviewed-by: Animesh Manna Acked-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20240607134917.1327574-6-jouni.hogander@intel.com --- include/drm/display/drm_dp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index f246fa03a3cb..173548c6473a 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -743,6 +743,7 @@ # define DP_PANEL_REPLAY_RFB_STORAGE_ERROR_EN (1 << 4) # define DP_PANEL_REPLAY_ACTIVE_FRAME_CRC_ERROR_EN (1 << 5) # define DP_PANEL_REPLAY_SU_ENABLE (1 << 6) +# define DP_PANEL_REPLAY_ENABLE_SU_REGION_ET (1 << 7) /* DP 2.1 */ #define PANEL_REPLAY_CONFIG2 0x1b1 /* eDP 1.5 */ # define DP_PANEL_REPLAY_SINK_REFRESH_RATE_UNLOCK_GRANTED (1 << 0) -- cgit v1.2.3 From 000d1940c90984a9a2af9c02bc17e3ca0d87f71d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 7 Jun 2024 16:22:58 +0300 Subject: drm/connector: hdmi: allow disabling Audio Infoframe Add drm_atomic_helper_connector_hdmi_disable_audio_infoframe(), an API to allow the driver disable sending the Audio Infoframe. This is to be used by the drivers if setup of the infoframes is not tightly coupled with the audio functionality and just disabling the audio playback doesn't stop the HDMI hardware from sending the Infoframe. Acked-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240607-bridge-hdmi-connector-v5-1-ab384e6021af@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 36 +++++++++++++++++++++++++ include/drm/display/drm_hdmi_state_helper.h | 1 + 2 files changed, 37 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 437270c29210..2dab3ad8ce64 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -714,3 +714,39 @@ drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *co return ret; } EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); + +/** + * drm_atomic_helper_connector_hdmi_disable_audio_infoframe - Stop sending the Audio Infoframe + * @connector: A pointer to the HDMI connector + * + * This function is meant for HDMI connector drivers to stop sending their + * audio infoframe. It will typically be used in one of the ALSA hooks + * (most likely shutdown). + * + * Returns: + * Zero on success, error code on failure. + */ +int +drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector) +{ + struct drm_connector_hdmi_infoframe *infoframe = + &connector->hdmi.infoframes.audio; + struct drm_display_info *info = &connector->display_info; + int ret; + + if (!info->is_hdmi) + return 0; + + mutex_lock(&connector->hdmi.infoframes.lock); + + infoframe->set = false; + + ret = clear_infoframe(connector, infoframe); + + memset(&infoframe->data, 0, sizeof(infoframe->data)); + + mutex_unlock(&connector->hdmi.infoframes.lock); + + return ret; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_disable_audio_infoframe); diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h index eb162ff24de0..285f366cf716 100644 --- a/include/drm/display/drm_hdmi_state_helper.h +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -16,6 +16,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, struct hdmi_audio_infoframe *frame); +int drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector); int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_state *state); -- cgit v1.2.3 From 6b4468b0c6ba37a16795da567b58dc80bc7fb439 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 7 Jun 2024 16:23:00 +0300 Subject: drm/bridge-connector: implement glue code for HDMI connector In order to let bridge chains implement HDMI connector infrastructure, add necessary glue code to the drm_bridge_connector. In case there is a bridge that sets DRM_BRIDGE_OP_HDMI, drm_bridge_connector will register itself as a HDMI connector and provide proxy drm_connector_hdmi_funcs implementation. Note, to simplify implementation, there can be only one bridge in a chain that sets DRM_BRIDGE_OP_HDMI. Setting more than one is considered an error. This limitation can be lifted later, if the need arises. Acked-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240607-bridge-hdmi-connector-v5-3-ab384e6021af@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_bridge_connector.c | 94 ++++++++++++++++++++++++++++++++-- drivers/gpu/drm/drm_debugfs.c | 2 + include/drm/drm_bridge.h | 81 +++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_bridge_connector.c b/drivers/gpu/drm/drm_bridge_connector.c index e093fc8928dc..0869b663f17e 100644 --- a/drivers/gpu/drm/drm_bridge_connector.c +++ b/drivers/gpu/drm/drm_bridge_connector.c @@ -18,6 +18,7 @@ #include #include #include +#include /** * DOC: overview @@ -87,6 +88,13 @@ struct drm_bridge_connector { * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES). */ struct drm_bridge *bridge_modes; + /** + * @bridge_hdmi: + * + * The bridge in the chain that implements necessary support for the + * HDMI connector infrastructure, if any (see &DRM_BRIDGE_OP_HDMI). + */ + struct drm_bridge *bridge_hdmi; }; #define to_drm_bridge_connector(x) \ @@ -287,6 +295,60 @@ static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs .disable_hpd = drm_bridge_connector_disable_hpd, }; +static enum drm_mode_status +drm_bridge_connector_tmds_char_rate_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return MODE_ERROR; + + if (bridge->funcs->hdmi_tmds_char_rate_valid) + return bridge->funcs->hdmi_tmds_char_rate_valid(bridge, mode, tmds_rate); + else + return MODE_OK; +} + +static int drm_bridge_connector_clear_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_clear_infoframe(bridge, type); +} + +static int drm_bridge_connector_write_infoframe(struct drm_connector *connector, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len) +{ + struct drm_bridge_connector *bridge_connector = + to_drm_bridge_connector(connector); + struct drm_bridge *bridge; + + bridge = bridge_connector->bridge_hdmi; + if (!bridge) + return -EINVAL; + + return bridge->funcs->hdmi_write_infoframe(bridge, type, buffer, len); +} + +static const struct drm_connector_hdmi_funcs drm_bridge_connector_hdmi_funcs = { + .tmds_char_rate_valid = drm_bridge_connector_tmds_char_rate_valid, + .clear_infoframe = drm_bridge_connector_clear_infoframe, + .write_infoframe = drm_bridge_connector_write_infoframe, +}; + /* ----------------------------------------------------------------------------- * Bridge Connector Initialisation */ @@ -312,6 +374,8 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, struct drm_connector *connector; struct i2c_adapter *ddc = NULL; struct drm_bridge *bridge, *panel_bridge = NULL; + unsigned int supported_formats = BIT(HDMI_COLORSPACE_RGB); + unsigned int max_bpc = 8; int connector_type; int ret; @@ -348,6 +412,20 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, bridge_connector->bridge_detect = bridge; if (bridge->ops & DRM_BRIDGE_OP_MODES) bridge_connector->bridge_modes = bridge; + if (bridge->ops & DRM_BRIDGE_OP_HDMI) { + if (bridge_connector->bridge_hdmi) + return ERR_PTR(-EBUSY); + if (!bridge->funcs->hdmi_write_infoframe || + !bridge->funcs->hdmi_clear_infoframe) + return ERR_PTR(-EINVAL); + + bridge_connector->bridge_hdmi = bridge; + + if (bridge->supported_formats) + supported_formats = bridge->supported_formats; + if (bridge->max_bpc) + max_bpc = bridge->max_bpc; + } if (!drm_bridge_get_next_bridge(bridge)) connector_type = bridge->type; @@ -370,9 +448,19 @@ struct drm_connector *drm_bridge_connector_init(struct drm_device *drm, return ERR_PTR(-EINVAL); } - ret = drmm_connector_init(drm, connector, - &drm_bridge_connector_funcs, - connector_type, ddc); + if (bridge_connector->bridge_hdmi) + ret = drmm_connector_hdmi_init(drm, connector, + bridge_connector->bridge_hdmi->vendor, + bridge_connector->bridge_hdmi->product, + &drm_bridge_connector_funcs, + &drm_bridge_connector_hdmi_funcs, + connector_type, ddc, + supported_formats, + max_bpc); + else + ret = drmm_connector_init(drm, connector, + &drm_bridge_connector_funcs, + connector_type, ddc); if (ret) { kfree(bridge_connector); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 8bec99251bee..6b239a24f1df 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -762,6 +762,8 @@ static int bridges_show(struct seq_file *m, void *data) drm_puts(&p, " hpd"); if (bridge->ops & DRM_BRIDGE_OP_MODES) drm_puts(&p, " modes"); + if (bridge->ops & DRM_BRIDGE_OP_HDMI) + drm_puts(&p, " hdmi"); drm_puts(&p, "\n"); } diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h index 5cf41f92d1f0..75019d16be64 100644 --- a/include/drm/drm_bridge.h +++ b/include/drm/drm_bridge.h @@ -630,6 +630,52 @@ struct drm_bridge_funcs { */ void (*hpd_disable)(struct drm_bridge *bridge); + /** + * @hdmi_tmds_char_rate_valid: + * + * Check whether a particular TMDS character rate is supported by the + * driver. + * + * This callback is optional and should only be implemented by the + * bridges that take part in the HDMI connector implementation. Bridges + * that implement it shall set the DRM_BRIDGE_OP_HDMI flag in their + * &drm_bridge->ops. + * + * Returns: + * + * Either &drm_mode_status.MODE_OK or one of the failure reasons + * in &enum drm_mode_status. + */ + enum drm_mode_status + (*hdmi_tmds_char_rate_valid)(const struct drm_bridge *bridge, + const struct drm_display_mode *mode, + unsigned long long tmds_rate); + + /** + * @hdmi_clear_infoframe: + * + * This callback clears the infoframes in the hardware during commit. + * It will be called multiple times, once for every disabled infoframe + * type. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. + */ + int (*hdmi_clear_infoframe)(struct drm_bridge *bridge, + enum hdmi_infoframe_type type); + /** + * @hdmi_write_infoframe: + * + * Program the infoframe into the hardware. It will be called multiple + * times, once for every updated infoframe type. + * + * This callback is optional but it must be implemented by bridges that + * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops. + */ + int (*hdmi_write_infoframe)(struct drm_bridge *bridge, + enum hdmi_infoframe_type type, + const u8 *buffer, size_t len); + /** * @debugfs_init: * @@ -705,6 +751,16 @@ enum drm_bridge_ops { * this flag shall implement the &drm_bridge_funcs->get_modes callback. */ DRM_BRIDGE_OP_MODES = BIT(3), + /** + * @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations, + * including infoframes support. Bridges that set this flag must + * implement the &drm_bridge_funcs->write_infoframe callback. + * + * Note: currently there can be at most one bridge in a chain that sets + * this bit. This is to simplify corresponding glue code in connector + * drivers. + */ + DRM_BRIDGE_OP_HDMI = BIT(4), }; /** @@ -773,6 +829,31 @@ struct drm_bridge { * @hpd_cb. */ void *hpd_data; + + /** + * @vendor: Vendor of the product to be used for the SPD InfoFrame + * generation. This is required if @DRM_BRIDGE_OP_HDMI is set. + */ + const char *vendor; + + /** + * @product: Name of the product to be used for the SPD InfoFrame + * generation. This is required if @DRM_BRIDGE_OP_HDMI is set. + */ + const char *product; + + /** + * @supported_formats: Bitmask of @hdmi_colorspace listing supported + * output formats. This is only relevant if @DRM_BRIDGE_OP_HDMI is set. + */ + unsigned int supported_formats; + + /** + * @max_bpc: Maximum bits per char the HDMI bridge supports. Allowed + * values are 8, 10 and 12. This is only relevant if + * @DRM_BRIDGE_OP_HDMI is set. + */ + unsigned int max_bpc; }; static inline struct drm_bridge * -- cgit v1.2.3 From 66055636a146c435cd226fb5a334176304652f3c Mon Sep 17 00:00:00 2001 From: Tejas Vipin Date: Wed, 12 Jun 2024 19:05:43 +0530 Subject: drm/mipi-dsi: fix handling of ctx in mipi_dsi_msleep ctx would be better off treated as a pointer to account for most of its usage so far, and brackets should be added to account for operator precedence for correct evaluation. Fixes: f79d6d28d8fe ("drm/mipi-dsi: wrap more functions for streamline handling") Signed-off-by: Tejas Vipin Suggested-by: Douglas Anderson Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20240612133550.473279-3-tejasvipin76@gmail.com [narmstrong: fixed fixes tag] Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240612133550.473279-3-tejasvipin76@gmail.com --- include/drm/drm_mipi_dsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index bd5a0b6d0711..71d121aeef24 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -293,7 +293,7 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, #define mipi_dsi_msleep(ctx, delay) \ do { \ - if (!ctx.accum_err) \ + if (!(ctx)->accum_err) \ msleep(delay); \ } while (0) -- cgit v1.2.3 From 3b9c181bcde8555ca81b2394c2dc2201cefc2dd4 Mon Sep 17 00:00:00 2001 From: José Roberto de Souza Date: Tue, 11 Jun 2024 10:47:15 -0700 Subject: devcoredump: Add dev_coredumpm_timeout() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add function to set a custom coredump timeout. For Xe driver usage, current 5 minutes timeout may be too short for users to search and understand what needs to be done to capture coredump to report bugs. We have plans to automate(distribute a udev script) it but at the end will be up to distros and users to pack it so having a option to increase the timeout is a safer option. v2: - replace dev_coredump_timeout_set() by dev_coredumpm_timeout() (Mukesh) v3: - make dev_coredumpm() static inline (Johannes) v5: - rename DEVCOREDUMP_TIMEOUT -> DEVCD_TIMEOUT to avoid redefinition in include/net/bluetooth/coredump.h v6: - fix definition of dev_coredumpm_timeout() when CONFIG_DEV_COREDUMP is disabled Cc: Rodrigo Vivi Cc: Mukesh Ojha Cc: Johannes Berg Cc: Jonathan Cavitt Reviewed-by: Rodrigo Vivi Reviewed-by: Jonathan Cavitt Signed-off-by: José Roberto de Souza Acked-by: Greg Kroah-Hartman Acked-by: Johannes Berg Link: https://patchwork.freedesktop.org/patch/msgid/20240611174716.72660-1-jose.souza@intel.com Signed-off-by: Rodrigo Vivi --- drivers/base/devcoredump.c | 23 ++++++++++---------- include/linux/devcoredump.h | 53 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 54 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 82aeb09b3d1b..c795edad1b96 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -18,9 +18,6 @@ static struct class devcd_class; /* global disable flag, for security purposes */ static bool devcd_disabled; -/* if data isn't read by userspace after 5 minutes then delete it */ -#define DEVCD_TIMEOUT (HZ * 60 * 5) - struct devcd_entry { struct device devcd_dev; void *data; @@ -328,7 +325,8 @@ void dev_coredump_put(struct device *dev) EXPORT_SYMBOL_GPL(dev_coredump_put); /** - * dev_coredumpm - create device coredump with read/free methods + * dev_coredumpm_timeout - create device coredump with read/free methods with a + * custom timeout. * @dev: the struct device for the crashed device * @owner: the module that contains the read/free functions, use %THIS_MODULE * @data: data cookie for the @read/@free functions @@ -336,17 +334,20 @@ EXPORT_SYMBOL_GPL(dev_coredump_put); * @gfp: allocation flags * @read: function to read from the given buffer * @free: function to free the given buffer + * @timeout: time in jiffies to remove coredump * * Creates a new device coredump for the given device. If a previous one hasn't * been read yet, the new coredump is discarded. The data lifetime is determined * by the device coredump framework and when it is no longer needed the @free * function will be called to free the data. */ -void dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, - ssize_t (*read)(char *buffer, loff_t offset, size_t count, - void *data, size_t datalen), - void (*free)(void *data)) +void dev_coredumpm_timeout(struct device *dev, struct module *owner, + void *data, size_t datalen, gfp_t gfp, + ssize_t (*read)(char *buffer, loff_t offset, + size_t count, void *data, + size_t datalen), + void (*free)(void *data), + unsigned long timeout) { static atomic_t devcd_count = ATOMIC_INIT(0); struct devcd_entry *devcd; @@ -403,7 +404,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, dev_set_uevent_suppress(&devcd->devcd_dev, false); kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); - schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); + schedule_delayed_work(&devcd->del_wk, timeout); mutex_unlock(&devcd->mutex); return; put_device: @@ -414,7 +415,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, free: free(data); } -EXPORT_SYMBOL_GPL(dev_coredumpm); +EXPORT_SYMBOL_GPL(dev_coredumpm_timeout); /** * dev_coredumpsg - create device coredump that uses scatterlist as data diff --git a/include/linux/devcoredump.h b/include/linux/devcoredump.h index c8f7eb6cc191..377892604ff4 100644 --- a/include/linux/devcoredump.h +++ b/include/linux/devcoredump.h @@ -12,6 +12,9 @@ #include #include +/* if data isn't read by userspace after 5 minutes then delete it */ +#define DEVCD_TIMEOUT (HZ * 60 * 5) + /* * _devcd_free_sgtable - free all the memory of the given scatterlist table * (i.e. both pages and scatterlist instances) @@ -50,16 +53,17 @@ static inline void _devcd_free_sgtable(struct scatterlist *table) kfree(delete_iter); } - #ifdef CONFIG_DEV_COREDUMP void dev_coredumpv(struct device *dev, void *data, size_t datalen, gfp_t gfp); -void dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, - ssize_t (*read)(char *buffer, loff_t offset, size_t count, - void *data, size_t datalen), - void (*free)(void *data)); +void dev_coredumpm_timeout(struct device *dev, struct module *owner, + void *data, size_t datalen, gfp_t gfp, + ssize_t (*read)(char *buffer, loff_t offset, + size_t count, void *data, + size_t datalen), + void (*free)(void *data), + unsigned long timeout); void dev_coredumpsg(struct device *dev, struct scatterlist *table, size_t datalen, gfp_t gfp); @@ -73,11 +77,13 @@ static inline void dev_coredumpv(struct device *dev, void *data, } static inline void -dev_coredumpm(struct device *dev, struct module *owner, - void *data, size_t datalen, gfp_t gfp, - ssize_t (*read)(char *buffer, loff_t offset, size_t count, - void *data, size_t datalen), - void (*free)(void *data)) +dev_coredumpm_timeout(struct device *dev, struct module *owner, + void *data, size_t datalen, gfp_t gfp, + ssize_t (*read)(char *buffer, loff_t offset, + size_t count, void *data, + size_t datalen), + void (*free)(void *data), + unsigned long timeout) { free(data); } @@ -92,4 +98,29 @@ static inline void dev_coredump_put(struct device *dev) } #endif /* CONFIG_DEV_COREDUMP */ +/** + * dev_coredumpm - create device coredump with read/free methods + * @dev: the struct device for the crashed device + * @owner: the module that contains the read/free functions, use %THIS_MODULE + * @data: data cookie for the @read/@free functions + * @datalen: length of the data + * @gfp: allocation flags + * @read: function to read from the given buffer + * @free: function to free the given buffer + * + * Creates a new device coredump for the given device. If a previous one hasn't + * been read yet, the new coredump is discarded. The data lifetime is determined + * by the device coredump framework and when it is no longer needed the @free + * function will be called to free the data. + */ +static inline void dev_coredumpm(struct device *dev, struct module *owner, + void *data, size_t datalen, gfp_t gfp, + ssize_t (*read)(char *buffer, loff_t offset, size_t count, + void *data, size_t datalen), + void (*free)(void *data)) +{ + dev_coredumpm_timeout(dev, owner, data, datalen, gfp, read, free, + DEVCD_TIMEOUT); +} + #endif /* __DEVCOREDUMP_H */ -- cgit v1.2.3 From e54700f7d6aa2ae0d0a0aeeebedcecd7ce1123fe Mon Sep 17 00:00:00 2001 From: Matt Roper Date: Mon, 3 Jun 2024 20:24:30 +0530 Subject: drm/xe/bmg: Add PCI IDs Add the initial set of device IDs for Battlemage. Signed-off-by: Matt Roper Signed-off-by: Balasubramani Vivekanandan Reviewed-by: Gustavo Sousa Link: https://patchwork.freedesktop.org/patch/msgid/20240603145430.1260817-1-balasubramani.vivekanandan@intel.com --- drivers/gpu/drm/xe/xe_pci.c | 3 ++- include/drm/xe_pciids.h | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index e84da0cbb8e9..08583fdd7643 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -340,7 +340,7 @@ static const struct xe_device_desc lnl_desc = { .require_force_probe = true, }; -static const struct xe_device_desc bmg_desc __maybe_unused = { +static const struct xe_device_desc bmg_desc = { DGFX_FEATURES, PLATFORM(BATTLEMAGE), .require_force_probe = true, @@ -389,6 +389,7 @@ static const struct pci_device_id pciidlist[] = { XE_DG2_IDS(INTEL_VGA_DEVICE, &dg2_desc), XE_MTL_IDS(INTEL_VGA_DEVICE, &mtl_desc), XE_LNL_IDS(INTEL_VGA_DEVICE, &lnl_desc), + XE_BMG_IDS(INTEL_VGA_DEVICE, &bmg_desc), { } }; MODULE_DEVICE_TABLE(pci, pciidlist); diff --git a/include/drm/xe_pciids.h b/include/drm/xe_pciids.h index adb37bc541e4..644872a35c35 100644 --- a/include/drm/xe_pciids.h +++ b/include/drm/xe_pciids.h @@ -192,4 +192,11 @@ MACRO__(0x64A0, ## __VA_ARGS__), \ MACRO__(0x64B0, ## __VA_ARGS__) +#define XE_BMG_IDS(MACRO__, ...) \ + MACRO__(0xE202, ## __VA_ARGS__), \ + MACRO__(0xE20B, ## __VA_ARGS__), \ + MACRO__(0xE20C, ## __VA_ARGS__), \ + MACRO__(0xE20D, ## __VA_ARGS__), \ + MACRO__(0xE212, ## __VA_ARGS__) + #endif -- cgit v1.2.3 From 2755d1f46aa25f65179964bf315d8a16b3540eab Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 10 Jun 2024 13:12:00 +0200 Subject: drm/connector: hdmi: Fix kerneldoc warnings It looks like the documentation for the HDMI-related fields recently added to both the drm_connector and drm_connector_state structures trigger some warnings because of their use of anonymous structures: $ scripts/kernel-doc -none include/drm/drm_connector.h include/drm/drm_connector.h:1138: warning: Excess struct member 'broadcast_rgb' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'infoframes' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'avi' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'hdr_drm' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'spd' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'vendor' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'is_limited_range' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'output_bpc' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'output_format' description in 'drm_connector_state' include/drm/drm_connector.h:1138: warning: Excess struct member 'tmds_char_rate' description in 'drm_connector_state' include/drm/drm_connector.h:2112: warning: Excess struct member 'vendor' description in 'drm_connector' include/drm/drm_connector.h:2112: warning: Excess struct member 'product' description in 'drm_connector' include/drm/drm_connector.h:2112: warning: Excess struct member 'supported_formats' description in 'drm_connector' include/drm/drm_connector.h:2112: warning: Excess struct member 'infoframes' description in 'drm_connector' include/drm/drm_connector.h:2112: warning: Excess struct member 'lock' description in 'drm_connector' include/drm/drm_connector.h:2112: warning: Excess struct member 'audio' description in 'drm_connector' Create some intermediate structures instead of anonymous ones to silence the warnings. Reported-by: Jani Nikula Suggested-by: Jani Nikula Fixes: 54cb39e2293b ("drm/connector: hdmi: Create an HDMI sub-state") Fixes: 948f01d5e559 ("drm/connector: hdmi: Add support for output format") Reviewed-by: Dmitry Baryshkov Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240610111200.428224-1-mripard@kernel.org --- include/drm/drm_connector.h | 206 +++++++++++++++++++++++--------------------- 1 file changed, 108 insertions(+), 98 deletions(-) (limited to 'include') diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e04a8a0d1bbd..f750765d8fbc 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -929,6 +929,67 @@ struct drm_connector_hdmi_infoframe { bool set; }; +/* + * struct drm_connector_hdmi_state - HDMI state container + */ +struct drm_connector_hdmi_state { + /** + * @broadcast_rgb: Connector property to pass the + * Broadcast RGB selection value. + */ + enum drm_hdmi_broadcast_rgb broadcast_rgb; + + /** + * @infoframes: HDMI Infoframes matching that state + */ + struct { + /** + * @avi: AVI Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe avi; + + /** + * @hdr_drm: DRM (Dynamic Range and Mastering) + * Infoframes structure matching our state. + */ + struct drm_connector_hdmi_infoframe hdr_drm; + + /** + * @spd: SPD Infoframes structure matching our + * state. + */ + struct drm_connector_hdmi_infoframe spd; + + /** + * @vendor: HDMI Vendor Infoframes structure + * matching our state. + */ + struct drm_connector_hdmi_infoframe hdmi; + } infoframes; + + /** + * @is_limited_range: Is the output supposed to use a limited + * RGB Quantization Range or not? + */ + bool is_limited_range; + + /** + * @output_bpc: Bits per color channel to output. + */ + unsigned int output_bpc; + + /** + * @output_format: Pixel format to output in. + */ + enum hdmi_colorspace output_format; + + /** + * @tmds_char_rate: TMDS Character Rate, in Hz. + */ + unsigned long long tmds_char_rate; +}; + /** * struct drm_connector_state - mutable connector state */ @@ -1078,63 +1139,7 @@ struct drm_connector_state { * @hdmi: HDMI-related variable and properties. Filled by * @drm_atomic_helper_connector_hdmi_check(). */ - struct { - /** - * @broadcast_rgb: Connector property to pass the - * Broadcast RGB selection value. - */ - enum drm_hdmi_broadcast_rgb broadcast_rgb; - - /** - * @infoframes: HDMI Infoframes matching that state - */ - struct { - /** - * @avi: AVI Infoframes structure matching our - * state. - */ - struct drm_connector_hdmi_infoframe avi; - - /** - * @hdr_drm: DRM (Dynamic Range and Mastering) - * Infoframes structure matching our state. - */ - struct drm_connector_hdmi_infoframe hdr_drm; - - /** - * @spd: SPD Infoframes structure matching our - * state. - */ - struct drm_connector_hdmi_infoframe spd; - - /** - * @vendor: HDMI Vendor Infoframes structure - * matching our state. - */ - struct drm_connector_hdmi_infoframe hdmi; - } infoframes; - - /** - * @is_limited_range: Is the output supposed to use a limited - * RGB Quantization Range or not? - */ - bool is_limited_range; - - /** - * @output_bpc: Bits per color channel to output. - */ - unsigned int output_bpc; - - /** - * @output_format: Pixel format to output in. - */ - enum hdmi_colorspace output_format; - - /** - * @tmds_char_rate: TMDS Character Rate, in Hz. - */ - unsigned long long tmds_char_rate; - } hdmi; + struct drm_connector_hdmi_state hdmi; }; /** @@ -1656,6 +1661,51 @@ struct drm_cmdline_mode { bool tv_mode_specified; }; +/* + * struct drm_connector_hdmi - DRM Connector HDMI-related structure + */ +struct drm_connector_hdmi { +#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8 + /** + * @vendor: HDMI Controller Vendor Name + */ + unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring; + +#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16 + /** + * @product: HDMI Controller Product Name + */ + unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring; + + /** + * @supported_formats: Bitmask of @hdmi_colorspace + * supported by the controller. + */ + unsigned long supported_formats; + + /** + * @funcs: HDMI connector Control Functions + */ + const struct drm_connector_hdmi_funcs *funcs; + + /** + * @infoframes: Current Infoframes output by the connector + */ + struct { + /** + * @lock: Mutex protecting against concurrent access to + * the infoframes, most notably between KMS and ALSA. + */ + struct mutex lock; + + /** + * @audio: Current Audio Infoframes structure. Protected + * by @lock. + */ + struct drm_connector_hdmi_infoframe audio; + } infoframes; +}; + /** * struct drm_connector - central DRM connector control structure * @@ -2068,47 +2118,7 @@ struct drm_connector { /** * @hdmi: HDMI-related variable and properties. */ - struct { -#define DRM_CONNECTOR_HDMI_VENDOR_LEN 8 - /** - * @vendor: HDMI Controller Vendor Name - */ - unsigned char vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] __nonstring; - -#define DRM_CONNECTOR_HDMI_PRODUCT_LEN 16 - /** - * @product: HDMI Controller Product Name - */ - unsigned char product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] __nonstring; - - /** - * @supported_formats: Bitmask of @hdmi_colorspace - * supported by the controller. - */ - unsigned long supported_formats; - - /** - * @funcs: HDMI connector Control Functions - */ - const struct drm_connector_hdmi_funcs *funcs; - - /** - * @infoframes: Current Infoframes output by the connector - */ - struct { - /** - * @lock: Mutex protecting against concurrent access to - * the infoframes, most notably between KMS and ALSA. - */ - struct mutex lock; - - /** - * @audio: Current Audio Infoframes structure. Protected - * by @lock. - */ - struct drm_connector_hdmi_infoframe audio; - } infoframes; - } hdmi; + struct drm_connector_hdmi hdmi; }; #define obj_to_connector(x) container_of(x, struct drm_connector, base) -- cgit v1.2.3 From 41474d25bec56900e3a018907784b0abfe5a6a9e Mon Sep 17 00:00:00 2001 From: Nick Hollinghurst Date: Fri, 16 Feb 2024 18:48:55 +0000 Subject: drm: Add DRM_MODE_TV_MODE_MONOCHROME Add this as a value for enum_drm_connector_tv_mode, represented by the string "Mono", to generate video with no colour encoding or bursts. Define it to have no pedestal (since only NTSC-M calls for a pedestal). Change default mode creation to acommodate the new tv_mode value which comprises both 525-line and 625-line formats. Acked-by: Daniel Vetter Signed-off-by: Nick Hollinghurst Signed-off-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240216184857.245372-2-dave.stevenson@raspberrypi.com --- drivers/gpu/drm/drm_connector.c | 7 +++++++ drivers/gpu/drm/drm_modes.c | 5 ++++- drivers/gpu/drm/drm_probe_helper.c | 5 +++-- include/drm/drm_connector.h | 7 +++++++ 4 files changed, 21 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 3d73a981004c..ab6ab7ff7ea8 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1087,6 +1087,7 @@ static const struct drm_prop_enum_list drm_tv_mode_enum_list[] = { { DRM_MODE_TV_MODE_PAL_M, "PAL-M" }, { DRM_MODE_TV_MODE_PAL_N, "PAL-N" }, { DRM_MODE_TV_MODE_SECAM, "SECAM" }, + { DRM_MODE_TV_MODE_MONOCHROME, "Mono" }, }; DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list) @@ -1858,6 +1859,12 @@ EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property); * TV Mode is CCIR System B (aka 625-lines) together with * the SECAM Color Encoding. * + * Mono: + * + * Use timings appropriate to the DRM mode, including + * equalizing pulses for a 525-line or 625-line mode, + * with no pedestal or color encoding. + * * Drivers can set up this property by calling * drm_mode_create_tv_properties(). */ diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 2d8b0371619d..1a0890083aee 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -531,7 +531,8 @@ static int fill_analog_mode(struct drm_device *dev, * @interlace: whether to compute an interlaced mode * * This function creates a struct drm_display_mode instance suited for - * an analog TV output, for one of the usual analog TV mode. + * an analog TV output, for one of the usual analog TV modes. Where + * this is DRM_MODE_TV_MODE_MONOCHROME, a 625-line mode will be created. * * Note that @hdisplay is larger than the usual constraints for the PAL * and NTSC timings, and we'll choose to ignore most timings constraints @@ -569,6 +570,8 @@ struct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev, case DRM_MODE_TV_MODE_PAL_N: fallthrough; case DRM_MODE_TV_MODE_SECAM: + fallthrough; + case DRM_MODE_TV_MODE_MONOCHROME: analog = DRM_MODE_ANALOG_PAL; break; diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 249c8c2cb319..bb49d552e671 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -1259,8 +1259,9 @@ int drm_connector_helper_tv_get_modes(struct drm_connector *connector) for (i = 0; i < tv_mode_property->num_values; i++) supported_tv_modes |= BIT(tv_mode_property->values[i]); - if ((supported_tv_modes & ntsc_modes) && - (supported_tv_modes & pal_modes)) { + if (((supported_tv_modes & ntsc_modes) && + (supported_tv_modes & pal_modes)) || + (supported_tv_modes & BIT(DRM_MODE_TV_MODE_MONOCHROME))) { uint64_t default_mode; if (drm_object_property_get_default_value(&connector->base, diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index f750765d8fbc..c754651044d4 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -201,6 +201,13 @@ enum drm_connector_tv_mode { */ DRM_MODE_TV_MODE_SECAM, + /** + * @DRM_MODE_TV_MODE_MONOCHROME: Use timings appropriate to + * the DRM mode, including equalizing pulses for a 525-line + * or 625-line mode, with no pedestal or color encoding. + */ + DRM_MODE_TV_MODE_MONOCHROME, + /** * @DRM_MODE_TV_MODE_MAX: Number of analog TV output modes. * -- cgit v1.2.3 From 52c2e956dcebecc8901911217a9647203ebcaf3c Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:45:53 -0700 Subject: drm/xe/perf/uapi: "Perf" layer to support multiple perf counter stream types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Xe, the plan is to support multiple types of perf counter streams (OA is only one type of these streams). Rather than introduce NxM ioctls for these (N perf streams with M ioctl's per perf stream), we decide to multiplex these (N different stream types and the M ops for each of these stream types) through a single PERF ioctl. This multiplexing is the purpose of the PERF layer. In addition to PERF DRM ioctl's, another set of ioctl's on the PERF fd are defined. These are expected to be common to different PERF stream types and therefore defined at the PERF layer itself. v2: Add param_size to 'struct drm_xe_perf_param' (Umesh) v3: Rename 'enum drm_xe_perf_ops' to 'enum drm_xe_perf_ioctls' (Guy Zadicario) Add DRM_ prefix to ioctl names to indicate uapi names v4: Add 'enum drm_xe_perf_op' previously missed out (Guy Zadicario) v5: Squash the ops and PERF layer patches into a single patch (Umesh) Remove param_size from struct 'drm_xe_perf_param' (Umesh) v6: Add DRM_XE_PERF_IOCTL_STATUS v7: Add DRM_XE_PERF_IOCTL_INFO v8: Fix Copyright years, fix DRM_XE_PERF_TYPE_MAX, move '#include "xe_perf.h"' to xe_perf.c, add kernel doc (Michal) Acked-by: Rodrigo Vivi Acked-by: Guy Zadicario Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-2-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/xe_device.c | 2 ++ drivers/gpu/drm/xe/xe_perf.c | 34 ++++++++++++++++++++++ drivers/gpu/drm/xe/xe_perf.h | 14 +++++++++ include/uapi/drm/xe_drm.h | 66 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 drivers/gpu/drm/xe/xe_perf.c create mode 100644 drivers/gpu/drm/xe/xe_perf.h (limited to 'include') diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index cbf961b90237..f99492449e5d 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -95,6 +95,7 @@ xe-y += xe_bb.o \ xe_pat.o \ xe_pci.o \ xe_pcode.o \ + xe_perf.o \ xe_pm.o \ xe_preempt_fence.o \ xe_pt.o \ diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 64691a56d59c..a44093cbbb71 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -44,6 +44,7 @@ #include "xe_module.h" #include "xe_pat.h" #include "xe_pcode.h" +#include "xe_perf.h" #include "xe_pm.h" #include "xe_query.h" #include "xe_sriov.h" @@ -141,6 +142,7 @@ static const struct drm_ioctl_desc xe_ioctls[] = { DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(XE_PERF, xe_perf_ioctl, DRM_RENDER_ALLOW), }; static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/gpu/drm/xe/xe_perf.c b/drivers/gpu/drm/xe/xe_perf.c new file mode 100644 index 000000000000..2963174ecd0e --- /dev/null +++ b/drivers/gpu/drm/xe/xe_perf.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#include + +#include + +#include "xe_perf.h" + +/** + * xe_perf_ioctl - The top level perf layer ioctl + * @dev: @drm_device + * @data: pointer to struct @drm_xe_perf_param + * @file: @drm_file + * + * The function is called for different perf streams types and allows execution + * of different operations supported by those perf stream types. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_xe_perf_param *arg = data; + + if (arg->extensions) + return -EINVAL; + + switch (arg->perf_type) { + default: + return -EINVAL; + } +} diff --git a/drivers/gpu/drm/xe/xe_perf.h b/drivers/gpu/drm/xe/xe_perf.h new file mode 100644 index 000000000000..e7e258eaf0a9 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_perf.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#ifndef _XE_PERF_H_ +#define _XE_PERF_H_ + +struct drm_device; +struct drm_file; + +int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file); + +#endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index d7b0903c22b2..c1626027dc69 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -80,6 +80,7 @@ extern "C" { * - &DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY * - &DRM_IOCTL_XE_EXEC * - &DRM_IOCTL_XE_WAIT_USER_FENCE + * - &DRM_IOCTL_XE_PERF */ /* @@ -100,6 +101,8 @@ extern "C" { #define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x08 #define DRM_XE_EXEC 0x09 #define DRM_XE_WAIT_USER_FENCE 0x0a +#define DRM_XE_PERF 0x0b + /* Must be kept compact -- no holes */ #define DRM_IOCTL_XE_DEVICE_QUERY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_DEVICE_QUERY, struct drm_xe_device_query) @@ -113,6 +116,7 @@ extern "C" { #define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_GET_PROPERTY, struct drm_xe_exec_queue_get_property) #define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec) #define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence) +#define DRM_IOCTL_XE_PERF DRM_IOW(DRM_COMMAND_BASE + DRM_XE_PERF, struct drm_xe_perf_param) /** * DOC: Xe IOCTL Extensions @@ -1370,6 +1374,68 @@ struct drm_xe_wait_user_fence { __u64 reserved[2]; }; +/** + * enum drm_xe_perf_type - Perf stream types + */ +enum drm_xe_perf_type { + __DRM_XE_PERF_TYPE_MAX, /* non-ABI */ +}; + +/** + * enum drm_xe_perf_op - Perf stream ops + */ +enum drm_xe_perf_op { + /** @DRM_XE_PERF_OP_STREAM_OPEN: Open a perf counter stream */ + DRM_XE_PERF_OP_STREAM_OPEN, + + /** @DRM_XE_PERF_OP_ADD_CONFIG: Add perf stream config */ + DRM_XE_PERF_OP_ADD_CONFIG, + + /** @DRM_XE_PERF_OP_REMOVE_CONFIG: Remove perf stream config */ + DRM_XE_PERF_OP_REMOVE_CONFIG, +}; + +/** + * struct drm_xe_perf_param - Input of &DRM_XE_PERF + * + * The perf layer enables multiplexing perf counter streams of multiple + * types. The actual params for a particular stream operation are supplied + * via the @param pointer (use __copy_from_user to get these params). + */ +struct drm_xe_perf_param { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + /** @perf_type: Perf stream type, of enum @drm_xe_perf_type */ + __u64 perf_type; + /** @perf_op: Perf op, of enum @drm_xe_perf_op */ + __u64 perf_op; + /** @param: Pointer to actual stream params */ + __u64 param; +}; + +/** + * enum drm_xe_perf_ioctls - Perf fd ioctl's + * + * Information exchanged between userspace and kernel for perf fd ioctl's + * is stream type specific + */ +enum drm_xe_perf_ioctls { + /** @DRM_XE_PERF_IOCTL_ENABLE: Enable data capture for a stream */ + DRM_XE_PERF_IOCTL_ENABLE = _IO('i', 0x0), + + /** @DRM_XE_PERF_IOCTL_DISABLE: Disable data capture for a stream */ + DRM_XE_PERF_IOCTL_DISABLE = _IO('i', 0x1), + + /** @DRM_XE_PERF_IOCTL_CONFIG: Change stream configuration */ + DRM_XE_PERF_IOCTL_CONFIG = _IO('i', 0x2), + + /** @DRM_XE_PERF_IOCTL_STATUS: Return stream status */ + DRM_XE_PERF_IOCTL_STATUS = _IO('i', 0x3), + + /** @DRM_XE_PERF_IOCTL_INFO: Return stream info */ + DRM_XE_PERF_IOCTL_INFO = _IO('i', 0x4), +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From 67977882a2f1339f0a7d32576ad61967828b2ca5 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:45:55 -0700 Subject: drm/xe/oa/uapi: Add OA data formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add and initialize supported OA data formats for various platforms (including Xe2). User can request OA data in any supported format. Bspec: 52198, 60942, 61101 v2: Start 'xe_oa_format_name' enum from 0 (Umesh) Fix error rewind with OA (Umesh) v3: Use graphics versions rather than absolute platform names v4: Add missing kernel doc for struct memebers and enum and other minor changes (Michal) Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-4-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/Makefile | 1 + drivers/gpu/drm/xe/xe_device.c | 11 +++- drivers/gpu/drm/xe/xe_device_types.h | 4 ++ drivers/gpu/drm/xe/xe_oa.c | 111 +++++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_oa.h | 16 +++++ drivers/gpu/drm/xe/xe_oa_types.h | 83 ++++++++++++++++++++++++++ include/uapi/drm/xe_drm.h | 19 ++++++ 7 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/xe/xe_oa.c create mode 100644 drivers/gpu/drm/xe/xe_oa.h create mode 100644 drivers/gpu/drm/xe/xe_oa_types.h (limited to 'include') diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index f99492449e5d..7039008be234 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -92,6 +92,7 @@ xe-y += xe_bb.o \ xe_mmio.o \ xe_mocs.o \ xe_module.o \ + xe_oa.o \ xe_pat.o \ xe_pci.o \ xe_pcode.o \ diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index a44093cbbb71..1195c64a715a 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -656,10 +656,14 @@ int xe_device_probe(struct xe_device *xe) xe_heci_gsc_init(xe); - err = xe_display_init(xe); + err = xe_oa_init(xe); if (err) goto err_fini_gt; + err = xe_display_init(xe); + if (err) + goto err_fini_oa; + err = drm_dev_register(&xe->drm, 0); if (err) goto err_fini_display; @@ -675,6 +679,9 @@ int xe_device_probe(struct xe_device *xe) err_fini_display: xe_display_driver_remove(xe); +err_fini_oa: + xe_oa_fini(xe); + err_fini_gt: for_each_gt(gt, xe, id) { if (id < last_gt) @@ -707,6 +714,8 @@ void xe_device_remove(struct xe_device *xe) xe_display_fini(xe); + xe_oa_fini(xe); + xe_heci_gsc_fini(xe); for_each_gt(gt, xe, id) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 52bc461171d5..185986e1d586 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -17,6 +17,7 @@ #include "xe_gt_types.h" #include "xe_lmtt_types.h" #include "xe_memirq_types.h" +#include "xe_oa.h" #include "xe_platform_types.h" #include "xe_pt_types.h" #include "xe_sriov_types.h" @@ -462,6 +463,9 @@ struct xe_device { /** @heci_gsc: graphics security controller */ struct xe_heci_gsc heci_gsc; + /** @oa: oa perf counter subsystem */ + struct xe_oa oa; + /** @needs_flr_on_fini: requests function-reset on fini */ bool needs_flr_on_fini; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c new file mode 100644 index 000000000000..5c0179ff4f60 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#include + +#include "xe_assert.h" +#include "xe_device.h" +#include "xe_macros.h" +#include "xe_oa.h" + +#define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x + +static const struct xe_oa_format oa_formats[] = { + [XE_OA_FORMAT_C4_B8] = { 7, 64, DRM_FMT(OAG) }, + [XE_OA_FORMAT_A12] = { 0, 64, DRM_FMT(OAG) }, + [XE_OA_FORMAT_A12_B8_C8] = { 2, 128, DRM_FMT(OAG) }, + [XE_OA_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256, DRM_FMT(OAG) }, + [XE_OAR_FORMAT_A32u40_A4u32_B8_C8] = { 5, 256, DRM_FMT(OAR) }, + [XE_OA_FORMAT_A24u40_A14u32_B8_C8] = { 5, 256, DRM_FMT(OAG) }, + [XE_OAC_FORMAT_A24u64_B8_C8] = { 1, 320, DRM_FMT(OAC), HDR_64_BIT }, + [XE_OAC_FORMAT_A22u32_R2u32_B8_C8] = { 2, 192, DRM_FMT(OAC), HDR_64_BIT }, + [XE_OAM_FORMAT_MPEC8u64_B8_C8] = { 1, 192, DRM_FMT(OAM_MPEC), HDR_64_BIT }, + [XE_OAM_FORMAT_MPEC8u32_B8_C8] = { 2, 128, DRM_FMT(OAM_MPEC), HDR_64_BIT }, + [XE_OA_FORMAT_PEC64u64] = { 1, 576, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, + [XE_OA_FORMAT_PEC64u64_B8_C8] = { 1, 640, DRM_FMT(PEC), HDR_64_BIT, 1, 1 }, + [XE_OA_FORMAT_PEC64u32] = { 1, 320, DRM_FMT(PEC), HDR_64_BIT }, + [XE_OA_FORMAT_PEC32u64_G1] = { 5, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, + [XE_OA_FORMAT_PEC32u32_G1] = { 5, 192, DRM_FMT(PEC), HDR_64_BIT }, + [XE_OA_FORMAT_PEC32u64_G2] = { 6, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, + [XE_OA_FORMAT_PEC32u32_G2] = { 6, 192, DRM_FMT(PEC), HDR_64_BIT }, + [XE_OA_FORMAT_PEC36u64_G1_32_G2_4] = { 3, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, + [XE_OA_FORMAT_PEC36u64_G1_4_G2_32] = { 4, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, +}; + +static void oa_format_add(struct xe_oa *oa, enum xe_oa_format_name format) +{ + __set_bit(format, oa->format_mask); +} + +static void xe_oa_init_supported_formats(struct xe_oa *oa) +{ + if (GRAPHICS_VER(oa->xe) >= 20) { + /* Xe2+ */ + oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8); + oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_PEC64u64); + oa_format_add(oa, XE_OA_FORMAT_PEC64u64_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_PEC64u32); + oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G1); + oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G1); + oa_format_add(oa, XE_OA_FORMAT_PEC32u64_G2); + oa_format_add(oa, XE_OA_FORMAT_PEC32u32_G2); + oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_32_G2_4); + oa_format_add(oa, XE_OA_FORMAT_PEC36u64_G1_4_G2_32); + } else if (GRAPHICS_VERx100(oa->xe) >= 1270) { + /* XE_METEORLAKE */ + oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8); + oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8); + oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8); + oa_format_add(oa, XE_OAM_FORMAT_MPEC8u64_B8_C8); + oa_format_add(oa, XE_OAM_FORMAT_MPEC8u32_B8_C8); + } else if (GRAPHICS_VERx100(oa->xe) >= 1255) { + /* XE_DG2, XE_PVC */ + oa_format_add(oa, XE_OAR_FORMAT_A32u40_A4u32_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_A24u40_A14u32_B8_C8); + oa_format_add(oa, XE_OAC_FORMAT_A24u64_B8_C8); + oa_format_add(oa, XE_OAC_FORMAT_A22u32_R2u32_B8_C8); + } else { + /* Gen12+ */ + xe_assert(oa->xe, GRAPHICS_VER(oa->xe) >= 12); + oa_format_add(oa, XE_OA_FORMAT_A12); + oa_format_add(oa, XE_OA_FORMAT_A12_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_A32u40_A4u32_B8_C8); + oa_format_add(oa, XE_OA_FORMAT_C4_B8); + } +} + +/** + * xe_oa_init - OA initialization during device probe + * @xe: @xe_device + * + * Return: 0 on success or a negative error code on failure + */ +int xe_oa_init(struct xe_device *xe) +{ + struct xe_oa *oa = &xe->oa; + + /* Support OA only with GuC submission and Gen12+ */ + if (XE_WARN_ON(!xe_device_uc_enabled(xe)) || XE_WARN_ON(GRAPHICS_VER(xe) < 12)) + return 0; + + oa->xe = xe; + oa->oa_formats = oa_formats; + + xe_oa_init_supported_formats(oa); + return 0; +} + +/** + * xe_oa_fini - OA de-initialization during device remove + * @xe: @xe_device + */ +void xe_oa_fini(struct xe_device *xe) +{ + struct xe_oa *oa = &xe->oa; + + oa->xe = NULL; +} diff --git a/drivers/gpu/drm/xe/xe_oa.h b/drivers/gpu/drm/xe/xe_oa.h new file mode 100644 index 000000000000..2647c1947746 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_oa.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#ifndef _XE_OA_H_ +#define _XE_OA_H_ + +#include "xe_oa_types.h" + +struct xe_device; + +int xe_oa_init(struct xe_device *xe); +void xe_oa_fini(struct xe_device *xe); + +#endif diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h new file mode 100644 index 000000000000..99940e25b1c6 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#ifndef _XE_OA_TYPES_H_ +#define _XE_OA_TYPES_H_ + +#include +#include + +enum xe_oa_report_header { + HDR_32_BIT = 0, + HDR_64_BIT, +}; + +enum xe_oa_format_name { + XE_OA_FORMAT_C4_B8, + + /* Gen8+ */ + XE_OA_FORMAT_A12, + XE_OA_FORMAT_A12_B8_C8, + XE_OA_FORMAT_A32u40_A4u32_B8_C8, + + /* DG2 */ + XE_OAR_FORMAT_A32u40_A4u32_B8_C8, + XE_OA_FORMAT_A24u40_A14u32_B8_C8, + + /* DG2/MTL OAC */ + XE_OAC_FORMAT_A24u64_B8_C8, + XE_OAC_FORMAT_A22u32_R2u32_B8_C8, + + /* MTL OAM */ + XE_OAM_FORMAT_MPEC8u64_B8_C8, + XE_OAM_FORMAT_MPEC8u32_B8_C8, + + /* Xe2+ */ + XE_OA_FORMAT_PEC64u64, + XE_OA_FORMAT_PEC64u64_B8_C8, + XE_OA_FORMAT_PEC64u32, + XE_OA_FORMAT_PEC32u64_G1, + XE_OA_FORMAT_PEC32u32_G1, + XE_OA_FORMAT_PEC32u64_G2, + XE_OA_FORMAT_PEC32u32_G2, + XE_OA_FORMAT_PEC36u64_G1_32_G2_4, + XE_OA_FORMAT_PEC36u64_G1_4_G2_32, + + __XE_OA_FORMAT_MAX, +}; + +/** + * struct xe_oa_format - Format fields for supported OA formats. OA format + * properties are specified in PRM/Bspec 52198 and 60942 + */ +struct xe_oa_format { + /** @counter_select: counter select value (see Bspec 52198/60942) */ + u32 counter_select; + /** @size: record size as written by HW (multiple of 64 byte cachelines) */ + int size; + /** @type: of enum @drm_xe_oa_format_type */ + int type; + /** @header: 32 or 64 bit report headers */ + enum xe_oa_report_header header; + /** @counter_size: counter size value (see Bspec 60942) */ + u16 counter_size; + /** @bc_report: BC report value (see Bspec 60942) */ + u16 bc_report; +}; + +/** + * struct xe_oa - OA device level information + */ +struct xe_oa { + /** @xe: back pointer to xe device */ + struct xe_device *xe; + + /** @oa_formats: tracks all OA formats across platforms */ + const struct xe_oa_format *oa_formats; + + /** @format_mask: tracks valid OA formats for a platform */ + unsigned long format_mask[BITS_TO_LONGS(__XE_OA_FORMAT_MAX)]; +}; +#endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index c1626027dc69..7e10874bfb33 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1436,6 +1436,25 @@ enum drm_xe_perf_ioctls { DRM_XE_PERF_IOCTL_INFO = _IO('i', 0x4), }; +/** + * enum drm_xe_oa_format_type - OA format types as specified in PRM/Bspec + * 52198/60942 + */ +enum drm_xe_oa_format_type { + /** @DRM_XE_OA_FMT_TYPE_OAG: OAG report format */ + DRM_XE_OA_FMT_TYPE_OAG, + /** @DRM_XE_OA_FMT_TYPE_OAR: OAR report format */ + DRM_XE_OA_FMT_TYPE_OAR, + /** @DRM_XE_OA_FMT_TYPE_OAM: OAM report format */ + DRM_XE_OA_FMT_TYPE_OAM, + /** @DRM_XE_OA_FMT_TYPE_OAC: OAC report format */ + DRM_XE_OA_FMT_TYPE_OAC, + /** @DRM_XE_OA_FMT_TYPE_OAM_MPEC: OAM SAMEDIA or OAM MPEC report format */ + DRM_XE_OA_FMT_TYPE_OAM_MPEC, + /** @DRM_XE_OA_FMT_TYPE_PEC: PEC report format */ + DRM_XE_OA_FMT_TYPE_PEC, +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From a9f905ae7b6f29a337dda2ad773c08b92dafe9a5 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:45:56 -0700 Subject: drm/xe/oa/uapi: Initialize OA units MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initialize OA unit data struct's for each gt during device probe. Also assign OA units for hardware engines. v2: Remove XE_OA_UNIT_OAG/XE_OA_UNIT_OAM_SAMEDIA_0 enum (Umesh) Change mtl_oa_base to 0x13000 (Umesh) v3: Switch to drmm_ functions and other cleanups (Michal) Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-5-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/regs/xe_oa_regs.h | 92 +++++++++++++++++++ drivers/gpu/drm/xe/xe_gt_types.h | 4 + drivers/gpu/drm/xe/xe_hw_engine_types.h | 2 + drivers/gpu/drm/xe/xe_oa.c | 156 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_oa_types.h | 54 +++++++++++ include/uapi/drm/xe_drm.h | 14 +++ 6 files changed, 322 insertions(+) create mode 100644 drivers/gpu/drm/xe/regs/xe_oa_regs.h (limited to 'include') diff --git a/drivers/gpu/drm/xe/regs/xe_oa_regs.h b/drivers/gpu/drm/xe/regs/xe_oa_regs.h new file mode 100644 index 000000000000..99bad563d51d --- /dev/null +++ b/drivers/gpu/drm/xe/regs/xe_oa_regs.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __XE_OA_REGS__ +#define __XE_OA_REGS__ + +#define RPM_CONFIG1 XE_REG(0xd04) +#define GT_NOA_ENABLE REG_BIT(9) + +#define EU_PERF_CNTL0 XE_REG(0xe458) +#define EU_PERF_CNTL4 XE_REG(0xe45c) +#define EU_PERF_CNTL1 XE_REG(0xe558) +#define EU_PERF_CNTL5 XE_REG(0xe55c) +#define EU_PERF_CNTL2 XE_REG(0xe658) +#define EU_PERF_CNTL6 XE_REG(0xe65c) +#define EU_PERF_CNTL3 XE_REG(0xe758) + +#define OA_TLB_INV_CR XE_REG(0xceec) + +/* OAR unit */ +#define OAR_OACONTROL XE_REG(0x2960) +#define OAR_OACONTROL_COUNTER_SEL_MASK REG_GENMASK(3, 1) +#define OAR_OACONTROL_COUNTER_ENABLE REG_BIT(0) + +#define OACTXCONTROL(base) XE_REG((base) + 0x360) +#define OAR_OASTATUS XE_REG(0x2968) +#define OA_COUNTER_RESUME REG_BIT(0) + +/* OAG unit */ +#define OAG_OAGLBCTXCTRL XE_REG(0x2b28) +#define OAG_OAGLBCTXCTRL_TIMER_PERIOD_MASK REG_GENMASK(7, 2) +#define OAG_OAGLBCTXCTRL_TIMER_ENABLE REG_BIT(1) +#define OAG_OAGLBCTXCTRL_COUNTER_RESUME REG_BIT(0) + +#define OAG_OAHEADPTR XE_REG(0xdb00) +#define OAG_OAHEADPTR_MASK REG_GENMASK(31, 6) +#define OAG_OATAILPTR XE_REG(0xdb04) +#define OAG_OATAILPTR_MASK REG_GENMASK(31, 6) + +#define OAG_OABUFFER XE_REG(0xdb08) +#define OABUFFER_SIZE_MASK REG_GENMASK(5, 3) +#define OABUFFER_SIZE_128K REG_FIELD_PREP(OABUFFER_SIZE_MASK, 0) +#define OABUFFER_SIZE_256K REG_FIELD_PREP(OABUFFER_SIZE_MASK, 1) +#define OABUFFER_SIZE_512K REG_FIELD_PREP(OABUFFER_SIZE_MASK, 2) +#define OABUFFER_SIZE_1M REG_FIELD_PREP(OABUFFER_SIZE_MASK, 3) +#define OABUFFER_SIZE_2M REG_FIELD_PREP(OABUFFER_SIZE_MASK, 4) +#define OABUFFER_SIZE_4M REG_FIELD_PREP(OABUFFER_SIZE_MASK, 5) +#define OABUFFER_SIZE_8M REG_FIELD_PREP(OABUFFER_SIZE_MASK, 6) +#define OABUFFER_SIZE_16M REG_FIELD_PREP(OABUFFER_SIZE_MASK, 7) +#define OAG_OABUFFER_MEMORY_SELECT REG_BIT(0) /* 0: PPGTT, 1: GGTT */ + +#define OAG_OACONTROL XE_REG(0xdaf4) +#define OAG_OACONTROL_OA_CCS_SELECT_MASK REG_GENMASK(18, 16) +#define OAG_OACONTROL_OA_COUNTER_SEL_MASK REG_GENMASK(4, 2) +#define OAG_OACONTROL_OA_COUNTER_ENABLE REG_BIT(0) +/* Common to all OA units */ +#define OA_OACONTROL_REPORT_BC_MASK REG_GENMASK(9, 9) +#define OA_OACONTROL_COUNTER_SIZE_MASK REG_GENMASK(8, 8) + +#define OAG_OA_DEBUG XE_REG(0xdaf8, XE_REG_OPTION_MASKED) +#define OAG_OA_DEBUG_INCLUDE_CLK_RATIO REG_BIT(6) +#define OAG_OA_DEBUG_DISABLE_CLK_RATIO_REPORTS REG_BIT(5) +#define OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS REG_BIT(1) + +#define OAG_OASTATUS XE_REG(0xdafc) +#define OASTATUS_MMIO_TRG_Q_FULL REG_BIT(6) +#define OASTATUS_COUNTER_OVERFLOW REG_BIT(2) +#define OASTATUS_BUFFER_OVERFLOW REG_BIT(1) +#define OASTATUS_REPORT_LOST REG_BIT(0) +/* OAM unit */ +#define OAM_HEAD_POINTER_OFFSET (0x1a0) +#define OAM_TAIL_POINTER_OFFSET (0x1a4) +#define OAM_BUFFER_OFFSET (0x1a8) +#define OAM_CONTEXT_CONTROL_OFFSET (0x1bc) +#define OAM_CONTROL_OFFSET (0x194) +#define OAM_CONTROL_COUNTER_SEL_MASK REG_GENMASK(3, 1) +#define OAM_DEBUG_OFFSET (0x198) +#define OAM_STATUS_OFFSET (0x19c) +#define OAM_MMIO_TRG_OFFSET (0x1d0) + +#define OAM_HEAD_POINTER(base) XE_REG((base) + OAM_HEAD_POINTER_OFFSET) +#define OAM_TAIL_POINTER(base) XE_REG((base) + OAM_TAIL_POINTER_OFFSET) +#define OAM_BUFFER(base) XE_REG((base) + OAM_BUFFER_OFFSET) +#define OAM_CONTEXT_CONTROL(base) XE_REG((base) + OAM_CONTEXT_CONTROL_OFFSET) +#define OAM_CONTROL(base) XE_REG((base) + OAM_CONTROL_OFFSET) +#define OAM_DEBUG(base) XE_REG((base) + OAM_DEBUG_OFFSET) +#define OAM_STATUS(base) XE_REG((base) + OAM_STATUS_OFFSET) +#define OAM_MMIO_TRG(base) XE_REG((base) + OAM_MMIO_TRG_OFFSET) + +#endif diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index 10a9a9529377..24bb95de920f 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -12,6 +12,7 @@ #include "xe_gt_sriov_vf_types.h" #include "xe_hw_engine_types.h" #include "xe_hw_fence_types.h" +#include "xe_oa.h" #include "xe_reg_sr_types.h" #include "xe_sa_types.h" #include "xe_uc_types.h" @@ -387,6 +388,9 @@ struct xe_gt { */ u8 instances_per_class[XE_ENGINE_CLASS_MAX]; } user_engines; + + /** @oa: oa perf counter subsystem per gt info */ + struct xe_oa_gt oa; }; #endif diff --git a/drivers/gpu/drm/xe/xe_hw_engine_types.h b/drivers/gpu/drm/xe/xe_hw_engine_types.h index 580bbd7e83b2..70e6434f150d 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_types.h +++ b/drivers/gpu/drm/xe/xe_hw_engine_types.h @@ -148,6 +148,8 @@ struct xe_hw_engine { enum xe_hw_engine_id engine_id; /** @eclass: pointer to per hw engine class interface */ struct xe_hw_engine_class_intf *eclass; + /** @oa_unit: oa unit for this hw engine */ + struct xe_oa_unit *oa_unit; }; /** diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 5c0179ff4f60..e836fafa9fb3 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -3,13 +3,20 @@ * Copyright © 2023-2024 Intel Corporation */ +#include #include +#include "regs/xe_oa_regs.h" #include "xe_assert.h" #include "xe_device.h" +#include "xe_gt.h" +#include "xe_gt_printk.h" #include "xe_macros.h" +#include "xe_mmio.h" #include "xe_oa.h" +#define XE_OA_UNIT_INVALID U32_MAX + #define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x static const struct xe_oa_format oa_formats[] = { @@ -34,6 +41,142 @@ static const struct xe_oa_format oa_formats[] = { [XE_OA_FORMAT_PEC36u64_G1_4_G2_32] = { 4, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, }; +static u32 num_oa_units_per_gt(struct xe_gt *gt) +{ + return 1; +} + +static u32 __hwe_oam_unit(struct xe_hw_engine *hwe) +{ + if (GRAPHICS_VERx100(gt_to_xe(hwe->gt)) >= 1270) { + /* + * There's 1 SAMEDIA gt and 1 OAM per SAMEDIA gt. All media slices + * within the gt use the same OAM. All MTL/LNL SKUs list 1 SA MEDIA + */ + xe_gt_WARN_ON(hwe->gt, hwe->gt->info.type != XE_GT_TYPE_MEDIA); + + return 0; + } + + return XE_OA_UNIT_INVALID; +} + +static u32 __hwe_oa_unit(struct xe_hw_engine *hwe) +{ + switch (hwe->class) { + case XE_ENGINE_CLASS_RENDER: + case XE_ENGINE_CLASS_COMPUTE: + return 0; + + case XE_ENGINE_CLASS_VIDEO_DECODE: + case XE_ENGINE_CLASS_VIDEO_ENHANCE: + return __hwe_oam_unit(hwe); + + default: + return XE_OA_UNIT_INVALID; + } +} + +static struct xe_oa_regs __oam_regs(u32 base) +{ + return (struct xe_oa_regs) { + base, + OAM_HEAD_POINTER(base), + OAM_TAIL_POINTER(base), + OAM_BUFFER(base), + OAM_CONTEXT_CONTROL(base), + OAM_CONTROL(base), + OAM_DEBUG(base), + OAM_STATUS(base), + OAM_CONTROL_COUNTER_SEL_MASK, + }; +} + +static struct xe_oa_regs __oag_regs(void) +{ + return (struct xe_oa_regs) { + 0, + OAG_OAHEADPTR, + OAG_OATAILPTR, + OAG_OABUFFER, + OAG_OAGLBCTXCTRL, + OAG_OACONTROL, + OAG_OA_DEBUG, + OAG_OASTATUS, + OAG_OACONTROL_OA_COUNTER_SEL_MASK, + }; +} + +static void __xe_oa_init_oa_units(struct xe_gt *gt) +{ + const u32 mtl_oa_base[] = { 0x13000 }; + int i, num_units = gt->oa.num_oa_units; + + for (i = 0; i < num_units; i++) { + struct xe_oa_unit *u = >->oa.oa_unit[i]; + + if (gt->info.type != XE_GT_TYPE_MEDIA) { + u->regs = __oag_regs(); + u->type = DRM_XE_OA_UNIT_TYPE_OAG; + } else if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) { + u->regs = __oam_regs(mtl_oa_base[i]); + u->type = DRM_XE_OA_UNIT_TYPE_OAM; + } + + /* Set oa_unit_ids now to ensure ids remain contiguous */ + u->oa_unit_id = gt_to_xe(gt)->oa.oa_unit_ids++; + } +} + +static int xe_oa_init_gt(struct xe_gt *gt) +{ + u32 num_oa_units = num_oa_units_per_gt(gt); + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + struct xe_oa_unit *u; + + u = drmm_kcalloc(>_to_xe(gt)->drm, num_oa_units, sizeof(*u), GFP_KERNEL); + if (!u) + return -ENOMEM; + + for_each_hw_engine(hwe, gt, id) { + u32 index = __hwe_oa_unit(hwe); + + hwe->oa_unit = NULL; + if (index < num_oa_units) { + u[index].num_engines++; + hwe->oa_unit = &u[index]; + } + } + + /* + * Fused off engines can result in oa_unit's with num_engines == 0. These units + * will appear in OA unit query, but no perf streams can be opened on them. + */ + gt->oa.num_oa_units = num_oa_units; + gt->oa.oa_unit = u; + + __xe_oa_init_oa_units(gt); + + drmm_mutex_init(>_to_xe(gt)->drm, >->oa.gt_lock); + + return 0; +} + +static int xe_oa_init_oa_units(struct xe_oa *oa) +{ + struct xe_gt *gt; + int i, ret; + + for_each_gt(gt, oa->xe, i) { + ret = xe_oa_init_gt(gt); + if (ret) + return ret; + } + + return 0; +} + static void oa_format_add(struct xe_oa *oa, enum xe_oa_format_name format) { __set_bit(format, oa->format_mask); @@ -87,6 +230,7 @@ static void xe_oa_init_supported_formats(struct xe_oa *oa) int xe_oa_init(struct xe_device *xe) { struct xe_oa *oa = &xe->oa; + int ret; /* Support OA only with GuC submission and Gen12+ */ if (XE_WARN_ON(!xe_device_uc_enabled(xe)) || XE_WARN_ON(GRAPHICS_VER(xe) < 12)) @@ -95,8 +239,17 @@ int xe_oa_init(struct xe_device *xe) oa->xe = xe; oa->oa_formats = oa_formats; + ret = xe_oa_init_oa_units(oa); + if (ret) { + drm_err(&xe->drm, "OA initialization failed (%pe)\n", ERR_PTR(ret)); + goto exit; + } + xe_oa_init_supported_formats(oa); return 0; +exit: + oa->xe = NULL; + return ret; } /** @@ -107,5 +260,8 @@ void xe_oa_fini(struct xe_device *xe) { struct xe_oa *oa = &xe->oa; + if (!oa->xe) + return; + oa->xe = NULL; } diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h index 99940e25b1c6..e7b91e31f0e8 100644 --- a/drivers/gpu/drm/xe/xe_oa_types.h +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -7,8 +7,12 @@ #define _XE_OA_TYPES_H_ #include +#include #include +#include +#include "regs/xe_reg_defs.h" + enum xe_oa_report_header { HDR_32_BIT = 0, HDR_64_BIT, @@ -67,6 +71,53 @@ struct xe_oa_format { u16 bc_report; }; +/** struct xe_oa_regs - Registers for each OA unit */ +struct xe_oa_regs { + u32 base; + struct xe_reg oa_head_ptr; + struct xe_reg oa_tail_ptr; + struct xe_reg oa_buffer; + struct xe_reg oa_ctx_ctrl; + struct xe_reg oa_ctrl; + struct xe_reg oa_debug; + struct xe_reg oa_status; + u32 oa_ctrl_counter_select_mask; +}; + +/** + * struct xe_oa_unit - Hardware OA unit + */ +struct xe_oa_unit { + /** @oa_unit_id: identifier for the OA unit */ + u16 oa_unit_id; + + /** @type: Type of OA unit - OAM, OAG etc. */ + enum drm_xe_oa_unit_type type; + + /** @regs: OA registers for programming the OA unit */ + struct xe_oa_regs regs; + + /** @num_engines: number of engines attached to this OA unit */ + u32 num_engines; + + /** @exclusive_stream: The stream currently using the OA unit */ + struct xe_oa_stream *exclusive_stream; +}; + +/** + * struct xe_oa_gt - OA per-gt information + */ +struct xe_oa_gt { + /** @gt_lock: lock protecting create/destroy OA streams */ + struct mutex gt_lock; + + /** @num_oa_units: number of oa units for each gt */ + u32 num_oa_units; + + /** @oa_unit: array of oa_units */ + struct xe_oa_unit *oa_unit; +}; + /** * struct xe_oa - OA device level information */ @@ -79,5 +130,8 @@ struct xe_oa { /** @format_mask: tracks valid OA formats for a platform */ unsigned long format_mask[BITS_TO_LONGS(__XE_OA_FORMAT_MAX)]; + + /** @oa_unit_ids: tracks oa unit ids assigned across gt's */ + u16 oa_unit_ids; }; #endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 7e10874bfb33..323d899a276b 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1436,6 +1436,20 @@ enum drm_xe_perf_ioctls { DRM_XE_PERF_IOCTL_INFO = _IO('i', 0x4), }; +/** + * enum drm_xe_oa_unit_type - OA unit types + */ +enum drm_xe_oa_unit_type { + /** + * @DRM_XE_OA_UNIT_TYPE_OAG: OAG OA unit. OAR/OAC are considered + * sub-types of OAG. For OAR/OAC, use OAG. + */ + DRM_XE_OA_UNIT_TYPE_OAG, + + /** @DRM_XE_OA_UNIT_TYPE_OAM: OAM OA unit */ + DRM_XE_OA_UNIT_TYPE_OAM, +}; + /** * enum drm_xe_oa_format_type - OA format types as specified in PRM/Bspec * 52198/60942 -- cgit v1.2.3 From cdf02fe1a94a768cbcd20f5c4e1a1d805f4a06c0 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:45:57 -0700 Subject: drm/xe/oa/uapi: Add/remove OA config perf ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce add/remove config perf ops for OA. OA configurations consist of a set of event/counter select register address/value pairs. The add_config perf op validates and stores such configurations and also exposes them in the metrics sysfs. These configurations will be programmed to OA unit HW when an OA stream using a configuration is opened. The OA stream can also switch to other stored configurations. v2: Start config id's from 1 and other minor review comments (Umesh) v3: Add 32 bit build v4: Add kernel doc for non-static functions (Michal) Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-6-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_device.c | 4 + drivers/gpu/drm/xe/xe_oa.c | 434 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_oa.h | 6 + drivers/gpu/drm/xe/xe_oa_types.h | 10 + drivers/gpu/drm/xe/xe_perf.c | 16 ++ include/uapi/drm/xe_drm.h | 25 +++ 6 files changed, 495 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 1195c64a715a..31b549f5f03a 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -670,6 +670,8 @@ int xe_device_probe(struct xe_device *xe) xe_display_register(xe); + xe_oa_register(xe); + xe_debugfs_register(xe); xe_hwmon_register(xe); @@ -710,6 +712,8 @@ void xe_device_remove(struct xe_device *xe) struct xe_gt *gt; u8 id; + xe_oa_unregister(xe); + xe_device_remove_display(xe); xe_display_fini(xe); diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index e836fafa9fb3..4122785735d4 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -14,9 +14,32 @@ #include "xe_macros.h" #include "xe_mmio.h" #include "xe_oa.h" +#include "xe_perf.h" #define XE_OA_UNIT_INVALID U32_MAX +struct xe_oa_reg { + struct xe_reg addr; + u32 value; +}; + +struct xe_oa_config { + struct xe_oa *oa; + + char uuid[UUID_STRING_LEN + 1]; + int id; + + const struct xe_oa_reg *regs; + u32 regs_len; + + struct attribute_group sysfs_metric; + struct attribute *attrs[2]; + struct kobj_attribute sysfs_metric_id; + + struct kref ref; + struct rcu_head rcu; +}; + #define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x static const struct xe_oa_format oa_formats[] = { @@ -41,6 +64,405 @@ static const struct xe_oa_format oa_formats[] = { [XE_OA_FORMAT_PEC36u64_G1_4_G2_32] = { 4, 320, DRM_FMT(PEC), HDR_64_BIT, 1, 0 }, }; +static void xe_oa_config_release(struct kref *ref) +{ + struct xe_oa_config *oa_config = + container_of(ref, typeof(*oa_config), ref); + + kfree(oa_config->regs); + + kfree_rcu(oa_config, rcu); +} + +static void xe_oa_config_put(struct xe_oa_config *oa_config) +{ + if (!oa_config) + return; + + kref_put(&oa_config->ref, xe_oa_config_release); +} + +static bool xe_oa_is_valid_flex_addr(struct xe_oa *oa, u32 addr) +{ + static const struct xe_reg flex_eu_regs[] = { + EU_PERF_CNTL0, + EU_PERF_CNTL1, + EU_PERF_CNTL2, + EU_PERF_CNTL3, + EU_PERF_CNTL4, + EU_PERF_CNTL5, + EU_PERF_CNTL6, + }; + int i; + + for (i = 0; i < ARRAY_SIZE(flex_eu_regs); i++) { + if (flex_eu_regs[i].addr == addr) + return true; + } + return false; +} + +static bool xe_oa_reg_in_range_table(u32 addr, const struct xe_mmio_range *table) +{ + while (table->start && table->end) { + if (addr >= table->start && addr <= table->end) + return true; + + table++; + } + + return false; +} + +static const struct xe_mmio_range xehp_oa_b_counters[] = { + { .start = 0xdc48, .end = 0xdc48 }, /* OAA_ENABLE_REG */ + { .start = 0xdd00, .end = 0xdd48 }, /* OAG_LCE0_0 - OAA_LENABLE_REG */ + {} +}; + +static const struct xe_mmio_range gen12_oa_b_counters[] = { + { .start = 0x2b2c, .end = 0x2b2c }, /* OAG_OA_PESS */ + { .start = 0xd900, .end = 0xd91c }, /* OAG_OASTARTTRIG[1-8] */ + { .start = 0xd920, .end = 0xd93c }, /* OAG_OAREPORTTRIG1[1-8] */ + { .start = 0xd940, .end = 0xd97c }, /* OAG_CEC[0-7][0-1] */ + { .start = 0xdc00, .end = 0xdc3c }, /* OAG_SCEC[0-7][0-1] */ + { .start = 0xdc40, .end = 0xdc40 }, /* OAG_SPCTR_CNF */ + { .start = 0xdc44, .end = 0xdc44 }, /* OAA_DBG_REG */ + {} +}; + +static const struct xe_mmio_range mtl_oam_b_counters[] = { + { .start = 0x393000, .end = 0x39301c }, /* OAM_STARTTRIG1[1-8] */ + { .start = 0x393020, .end = 0x39303c }, /* OAM_REPORTTRIG1[1-8] */ + { .start = 0x393040, .end = 0x39307c }, /* OAM_CEC[0-7][0-1] */ + { .start = 0x393200, .end = 0x39323C }, /* MPES[0-7] */ + {} +}; + +static const struct xe_mmio_range xe2_oa_b_counters[] = { + { .start = 0x393200, .end = 0x39323C }, /* MPES_0_MPES_SAG - MPES_7_UPPER_MPES_SAG */ + { .start = 0x394200, .end = 0x39423C }, /* MPES_0_MPES_SCMI0 - MPES_7_UPPER_MPES_SCMI0 */ + { .start = 0x394A00, .end = 0x394A3C }, /* MPES_0_MPES_SCMI1 - MPES_7_UPPER_MPES_SCMI1 */ + {}, +}; + +static bool xe_oa_is_valid_b_counter_addr(struct xe_oa *oa, u32 addr) +{ + return xe_oa_reg_in_range_table(addr, xehp_oa_b_counters) || + xe_oa_reg_in_range_table(addr, gen12_oa_b_counters) || + xe_oa_reg_in_range_table(addr, mtl_oam_b_counters) || + (GRAPHICS_VER(oa->xe) >= 20 && + xe_oa_reg_in_range_table(addr, xe2_oa_b_counters)); +} + +static const struct xe_mmio_range mtl_oa_mux_regs[] = { + { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */ + { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */ + { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */ + { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */ + { .start = 0x38d100, .end = 0x38d114}, /* VISACTL */ + {} +}; + +static const struct xe_mmio_range gen12_oa_mux_regs[] = { + { .start = 0x0d00, .end = 0x0d04 }, /* RPM_CONFIG[0-1] */ + { .start = 0x0d0c, .end = 0x0d2c }, /* NOA_CONFIG[0-8] */ + { .start = 0x9840, .end = 0x9840 }, /* GDT_CHICKEN_BITS */ + { .start = 0x9884, .end = 0x9888 }, /* NOA_WRITE */ + { .start = 0x20cc, .end = 0x20cc }, /* WAIT_FOR_RC6_EXIT */ + {} +}; + +static const struct xe_mmio_range xe2_oa_mux_regs[] = { + { .start = 0x5194, .end = 0x5194 }, /* SYS_MEM_LAT_MEASURE_MERTF_GRP_3D */ + { .start = 0x8704, .end = 0x8704 }, /* LMEM_LAT_MEASURE_MCFG_GRP */ + { .start = 0xB1BC, .end = 0xB1BC }, /* L3_BANK_LAT_MEASURE_LBCF_GFX */ + { .start = 0xE18C, .end = 0xE18C }, /* SAMPLER_MODE */ + { .start = 0xE590, .end = 0xE590 }, /* TDL_LSC_LAT_MEASURE_TDL_GFX */ + { .start = 0x13000, .end = 0x137FC }, /* PES_0_PESL0 - PES_63_UPPER_PESL3 */ + {}, +}; + +static bool xe_oa_is_valid_mux_addr(struct xe_oa *oa, u32 addr) +{ + if (GRAPHICS_VER(oa->xe) >= 20) + return xe_oa_reg_in_range_table(addr, xe2_oa_mux_regs); + else if (GRAPHICS_VERx100(oa->xe) >= 1270) + return xe_oa_reg_in_range_table(addr, mtl_oa_mux_regs); + else + return xe_oa_reg_in_range_table(addr, gen12_oa_mux_regs); +} + +static bool xe_oa_is_valid_config_reg_addr(struct xe_oa *oa, u32 addr) +{ + return xe_oa_is_valid_flex_addr(oa, addr) || + xe_oa_is_valid_b_counter_addr(oa, addr) || + xe_oa_is_valid_mux_addr(oa, addr); +} + +static struct xe_oa_reg * +xe_oa_alloc_regs(struct xe_oa *oa, bool (*is_valid)(struct xe_oa *oa, u32 addr), + u32 __user *regs, u32 n_regs) +{ + struct xe_oa_reg *oa_regs; + int err; + u32 i; + + oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL); + if (!oa_regs) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < n_regs; i++) { + u32 addr, value; + + err = get_user(addr, regs); + if (err) + goto addr_err; + + if (!is_valid(oa, addr)) { + drm_dbg(&oa->xe->drm, "Invalid oa_reg address: %X\n", addr); + err = -EINVAL; + goto addr_err; + } + + err = get_user(value, regs + 1); + if (err) + goto addr_err; + + oa_regs[i].addr = XE_REG(addr); + oa_regs[i].value = value; + + regs += 2; + } + + return oa_regs; + +addr_err: + kfree(oa_regs); + return ERR_PTR(err); +} + +static ssize_t show_dynamic_id(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct xe_oa_config *oa_config = + container_of(attr, typeof(*oa_config), sysfs_metric_id); + + return sysfs_emit(buf, "%d\n", oa_config->id); +} + +static int create_dynamic_oa_sysfs_entry(struct xe_oa *oa, + struct xe_oa_config *oa_config) +{ + sysfs_attr_init(&oa_config->sysfs_metric_id.attr); + oa_config->sysfs_metric_id.attr.name = "id"; + oa_config->sysfs_metric_id.attr.mode = 0444; + oa_config->sysfs_metric_id.show = show_dynamic_id; + oa_config->sysfs_metric_id.store = NULL; + + oa_config->attrs[0] = &oa_config->sysfs_metric_id.attr; + oa_config->attrs[1] = NULL; + + oa_config->sysfs_metric.name = oa_config->uuid; + oa_config->sysfs_metric.attrs = oa_config->attrs; + + return sysfs_create_group(oa->metrics_kobj, &oa_config->sysfs_metric); +} + +/** + * xe_oa_add_config_ioctl - Adds one OA config + * @dev: @drm_device + * @data: pointer to struct @drm_xe_oa_config + * @file: @drm_file + * + * The functions adds an OA config to the set of OA configs maintained in + * the kernel. The config determines which OA metrics are collected for an + * OA stream. + */ +int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file) +{ + struct xe_oa *oa = &to_xe_device(dev)->oa; + struct drm_xe_oa_config param; + struct drm_xe_oa_config *arg = ¶m; + struct xe_oa_config *oa_config, *tmp; + struct xe_oa_reg *regs; + int err, id; + + if (!oa->xe) { + drm_dbg(&oa->xe->drm, "xe oa interface not available for this system\n"); + return -ENODEV; + } + + if (xe_perf_stream_paranoid && !perfmon_capable()) { + drm_dbg(&oa->xe->drm, "Insufficient privileges to add xe OA config\n"); + return -EACCES; + } + + err = __copy_from_user(¶m, u64_to_user_ptr(data), sizeof(param)); + if (XE_IOCTL_DBG(oa->xe, err)) + return -EFAULT; + + if (XE_IOCTL_DBG(oa->xe, arg->extensions) || + XE_IOCTL_DBG(oa->xe, !arg->regs_ptr) || + XE_IOCTL_DBG(oa->xe, !arg->n_regs)) + return -EINVAL; + + oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL); + if (!oa_config) + return -ENOMEM; + + oa_config->oa = oa; + kref_init(&oa_config->ref); + + if (!uuid_is_valid(arg->uuid)) { + drm_dbg(&oa->xe->drm, "Invalid uuid format for OA config\n"); + err = -EINVAL; + goto reg_err; + } + + /* Last character in oa_config->uuid will be 0 because oa_config is kzalloc */ + memcpy(oa_config->uuid, arg->uuid, sizeof(arg->uuid)); + + oa_config->regs_len = arg->n_regs; + regs = xe_oa_alloc_regs(oa, xe_oa_is_valid_config_reg_addr, + u64_to_user_ptr(arg->regs_ptr), + arg->n_regs); + if (IS_ERR(regs)) { + drm_dbg(&oa->xe->drm, "Failed to create OA config for mux_regs\n"); + err = PTR_ERR(regs); + goto reg_err; + } + oa_config->regs = regs; + + err = mutex_lock_interruptible(&oa->metrics_lock); + if (err) + goto reg_err; + + /* We shouldn't have too many configs, so this iteration shouldn't be too costly */ + idr_for_each_entry(&oa->metrics_idr, tmp, id) { + if (!strcmp(tmp->uuid, oa_config->uuid)) { + drm_dbg(&oa->xe->drm, "OA config already exists with this uuid\n"); + err = -EADDRINUSE; + goto sysfs_err; + } + } + + err = create_dynamic_oa_sysfs_entry(oa, oa_config); + if (err) { + drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n"); + goto sysfs_err; + } + + oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 1, 0, GFP_KERNEL); + if (oa_config->id < 0) { + drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n"); + err = oa_config->id; + goto sysfs_err; + } + + mutex_unlock(&oa->metrics_lock); + + drm_dbg(&oa->xe->drm, "Added config %s id=%i\n", oa_config->uuid, oa_config->id); + + return oa_config->id; + +sysfs_err: + mutex_unlock(&oa->metrics_lock); +reg_err: + xe_oa_config_put(oa_config); + drm_dbg(&oa->xe->drm, "Failed to add new OA config\n"); + return err; +} + +/** + * xe_oa_remove_config_ioctl - Removes one OA config + * @dev: @drm_device + * @data: pointer to struct @drm_xe_perf_param + * @file: @drm_file + */ +int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file) +{ + struct xe_oa *oa = &to_xe_device(dev)->oa; + struct xe_oa_config *oa_config; + u64 arg, *ptr = u64_to_user_ptr(data); + int ret; + + if (!oa->xe) { + drm_dbg(&oa->xe->drm, "xe oa interface not available for this system\n"); + return -ENODEV; + } + + if (xe_perf_stream_paranoid && !perfmon_capable()) { + drm_dbg(&oa->xe->drm, "Insufficient privileges to remove xe OA config\n"); + return -EACCES; + } + + ret = get_user(arg, ptr); + if (XE_IOCTL_DBG(oa->xe, ret)) + return ret; + + ret = mutex_lock_interruptible(&oa->metrics_lock); + if (ret) + return ret; + + oa_config = idr_find(&oa->metrics_idr, arg); + if (!oa_config) { + drm_dbg(&oa->xe->drm, "Failed to remove unknown OA config\n"); + ret = -ENOENT; + goto err_unlock; + } + + WARN_ON(arg != oa_config->id); + + sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric); + idr_remove(&oa->metrics_idr, arg); + + mutex_unlock(&oa->metrics_lock); + + drm_dbg(&oa->xe->drm, "Removed config %s id=%i\n", oa_config->uuid, oa_config->id); + + xe_oa_config_put(oa_config); + + return 0; + +err_unlock: + mutex_unlock(&oa->metrics_lock); + return ret; +} + +/** + * xe_oa_register - Xe OA registration + * @xe: @xe_device + * + * Exposes the metrics sysfs directory upon completion of module initialization + */ +void xe_oa_register(struct xe_device *xe) +{ + struct xe_oa *oa = &xe->oa; + + if (!oa->xe) + return; + + oa->metrics_kobj = kobject_create_and_add("metrics", + &xe->drm.primary->kdev->kobj); +} + +/** + * xe_oa_unregister - Xe OA de-registration + * @xe: @xe_device + */ +void xe_oa_unregister(struct xe_device *xe) +{ + struct xe_oa *oa = &xe->oa; + + if (!oa->metrics_kobj) + return; + + kobject_put(oa->metrics_kobj); + oa->metrics_kobj = NULL; +} + static u32 num_oa_units_per_gt(struct xe_gt *gt) { return 1; @@ -239,6 +661,9 @@ int xe_oa_init(struct xe_device *xe) oa->xe = xe; oa->oa_formats = oa_formats; + drmm_mutex_init(&oa->xe->drm, &oa->metrics_lock); + idr_init_base(&oa->metrics_idr, 1); + ret = xe_oa_init_oa_units(oa); if (ret) { drm_err(&xe->drm, "OA initialization failed (%pe)\n", ERR_PTR(ret)); @@ -252,6 +677,12 @@ exit: return ret; } +static int destroy_config(int id, void *p, void *data) +{ + xe_oa_config_put(p); + return 0; +} + /** * xe_oa_fini - OA de-initialization during device remove * @xe: @xe_device @@ -263,5 +694,8 @@ void xe_oa_fini(struct xe_device *xe) if (!oa->xe) return; + idr_for_each(&oa->metrics_idr, destroy_config, oa); + idr_destroy(&oa->metrics_idr); + oa->xe = NULL; } diff --git a/drivers/gpu/drm/xe/xe_oa.h b/drivers/gpu/drm/xe/xe_oa.h index 2647c1947746..5ccc772e047a 100644 --- a/drivers/gpu/drm/xe/xe_oa.h +++ b/drivers/gpu/drm/xe/xe_oa.h @@ -8,9 +8,15 @@ #include "xe_oa_types.h" +struct drm_device; +struct drm_file; struct xe_device; int xe_oa_init(struct xe_device *xe); void xe_oa_fini(struct xe_device *xe); +void xe_oa_register(struct xe_device *xe); +void xe_oa_unregister(struct xe_device *xe); +int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file); +int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file); #endif diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h index e7b91e31f0e8..f8a45015cf49 100644 --- a/drivers/gpu/drm/xe/xe_oa_types.h +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -7,6 +7,7 @@ #define _XE_OA_TYPES_H_ #include +#include #include #include @@ -125,6 +126,15 @@ struct xe_oa { /** @xe: back pointer to xe device */ struct xe_device *xe; + /** @metrics_kobj: kobj for metrics sysfs */ + struct kobject *metrics_kobj; + + /** @metrics_lock: lock protecting add/remove configs */ + struct mutex metrics_lock; + + /** @metrics_idr: List of dynamic configurations (struct xe_oa_config) */ + struct idr metrics_idr; + /** @oa_formats: tracks all OA formats across platforms */ const struct xe_oa_format *oa_formats; diff --git a/drivers/gpu/drm/xe/xe_perf.c b/drivers/gpu/drm/xe/xe_perf.c index f619cf50b453..ca01042d75b1 100644 --- a/drivers/gpu/drm/xe/xe_perf.c +++ b/drivers/gpu/drm/xe/xe_perf.c @@ -8,11 +8,25 @@ #include +#include "xe_oa.h" #include "xe_perf.h" u32 xe_perf_stream_paranoid = true; static struct ctl_table_header *sysctl_header; +static int xe_oa_ioctl(struct drm_device *dev, struct drm_xe_perf_param *arg, + struct drm_file *file) +{ + switch (arg->perf_op) { + case DRM_XE_PERF_OP_ADD_CONFIG: + return xe_oa_add_config_ioctl(dev, arg->param, file); + case DRM_XE_PERF_OP_REMOVE_CONFIG: + return xe_oa_remove_config_ioctl(dev, arg->param, file); + default: + return -EINVAL; + } +} + /** * xe_perf_ioctl - The top level perf layer ioctl * @dev: @drm_device @@ -32,6 +46,8 @@ int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file) return -EINVAL; switch (arg->perf_type) { + case DRM_XE_PERF_TYPE_OA: + return xe_oa_ioctl(dev, arg, file); default: return -EINVAL; } diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 323d899a276b..fd9a4bd9e3d4 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1378,6 +1378,7 @@ struct drm_xe_wait_user_fence { * enum drm_xe_perf_type - Perf stream types */ enum drm_xe_perf_type { + DRM_XE_PERF_TYPE_OA, __DRM_XE_PERF_TYPE_MAX, /* non-ABI */ }; @@ -1469,6 +1470,30 @@ enum drm_xe_oa_format_type { DRM_XE_OA_FMT_TYPE_PEC, }; +/** + * struct drm_xe_oa_config - OA metric configuration + * + * Multiple OA configs can be added using @DRM_XE_PERF_OP_ADD_CONFIG. A + * particular config can be specified when opening an OA stream using + * @DRM_XE_OA_PROPERTY_OA_METRIC_SET property. + */ +struct drm_xe_oa_config { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @uuid: String formatted like "%\08x-%\04x-%\04x-%\04x-%\012x" */ + char uuid[36]; + + /** @n_regs: Number of regs in @regs_ptr */ + __u32 n_regs; + + /** + * @regs_ptr: Pointer to (register address, value) pairs for OA config + * registers. Expected length of buffer is: (2 * sizeof(u32) * @n_regs). + */ + __u64 regs_ptr; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From b6fd51c6211910b1db072a3fa2a17ba85cb3dd51 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:45:58 -0700 Subject: drm/xe/oa/uapi: Define and parse OA stream properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Properties for OA streams are specified by user space, when the stream is opened, as a chain of drm_xe_ext_set_property struct's. Parse and validate these stream properties. v2: Remove struct drm_xe_oa_open_param (Harish Chegondi) Drop DRM_XE_OA_PROPERTY_POLL_OA_PERIOD_US (Umesh) Eliminate comparison with xe_oa_max_sample_rate (Umesh) Drop 'struct drm_xe_oa_record_header' (Umesh) v3: s/DRM_XE_OA_PROPERTY_OA_EXPONENT/ \ DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT/ (Jose) v4: Fix 32 bit build v5: Add non-static function kernel doc (Michal) Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-7-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 364 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_oa.h | 5 + drivers/gpu/drm/xe/xe_perf.c | 2 + include/uapi/drm/xe_drm.h | 72 +++++++++ 4 files changed, 443 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 4122785735d4..9b23eadf56cd 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -3,18 +3,23 @@ * Copyright © 2023-2024 Intel Corporation */ +#include + #include #include +#include "regs/xe_gt_regs.h" #include "regs/xe_oa_regs.h" #include "xe_assert.h" #include "xe_device.h" +#include "xe_exec_queue.h" #include "xe_gt.h" #include "xe_gt_printk.h" #include "xe_macros.h" #include "xe_mmio.h" #include "xe_oa.h" #include "xe_perf.h" +#include "xe_pm.h" #define XE_OA_UNIT_INVALID U32_MAX @@ -40,6 +45,19 @@ struct xe_oa_config { struct rcu_head rcu; }; +struct xe_oa_open_param { + u32 oa_unit_id; + bool sample; + u32 metric_set; + enum xe_oa_format_name oa_format; + int period_exponent; + bool disabled; + int exec_queue_id; + int engine_instance; + struct xe_exec_queue *exec_q; + struct xe_hw_engine *hwe; +}; + #define DRM_FMT(x) DRM_XE_OA_FMT_TYPE_##x static const struct xe_oa_format oa_formats[] = { @@ -82,6 +100,352 @@ static void xe_oa_config_put(struct xe_oa_config *oa_config) kref_put(&oa_config->ref, xe_oa_config_release); } +/** + * xe_oa_timestamp_frequency - Return OA timestamp frequency + * @gt: @xe_gt + * + * OA timestamp frequency = CS timestamp frequency in most platforms. On some + * platforms OA unit ignores the CTC_SHIFT and the 2 timestamps differ. In such + * cases, return the adjusted CS timestamp frequency to the user. + */ +u32 xe_oa_timestamp_frequency(struct xe_gt *gt) +{ + u32 reg, shift; + + /* + * Wa_18013179988:dg2 + * Wa_14015568240:pvc + * Wa_14015846243:mtl + */ + switch (gt_to_xe(gt)->info.platform) { + case XE_DG2: + case XE_PVC: + case XE_METEORLAKE: + xe_pm_runtime_get(gt_to_xe(gt)); + reg = xe_mmio_read32(gt, RPM_CONFIG0); + xe_pm_runtime_put(gt_to_xe(gt)); + + shift = REG_FIELD_GET(RPM_CONFIG0_CTC_SHIFT_PARAMETER_MASK, reg); + return gt->info.reference_clock << (3 - shift); + + default: + return gt->info.reference_clock; + } +} + +static u64 oa_exponent_to_ns(struct xe_gt *gt, int exponent) +{ + u64 nom = (2ULL << exponent) * NSEC_PER_SEC; + u32 den = xe_oa_timestamp_frequency(gt); + + return div_u64(nom + den - 1, den); +} + +static bool engine_supports_oa_format(const struct xe_hw_engine *hwe, int type) +{ + switch (hwe->oa_unit->type) { + case DRM_XE_OA_UNIT_TYPE_OAG: + return type == DRM_XE_OA_FMT_TYPE_OAG || type == DRM_XE_OA_FMT_TYPE_OAR || + type == DRM_XE_OA_FMT_TYPE_OAC || type == DRM_XE_OA_FMT_TYPE_PEC; + case DRM_XE_OA_UNIT_TYPE_OAM: + return type == DRM_XE_OA_FMT_TYPE_OAM || type == DRM_XE_OA_FMT_TYPE_OAM_MPEC; + default: + return false; + } +} + +static int decode_oa_format(struct xe_oa *oa, u64 fmt, enum xe_oa_format_name *name) +{ + u32 counter_size = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE, fmt); + u32 counter_sel = FIELD_GET(DRM_XE_OA_FORMAT_MASK_COUNTER_SEL, fmt); + u32 bc_report = FIELD_GET(DRM_XE_OA_FORMAT_MASK_BC_REPORT, fmt); + u32 type = FIELD_GET(DRM_XE_OA_FORMAT_MASK_FMT_TYPE, fmt); + int idx; + + for_each_set_bit(idx, oa->format_mask, __XE_OA_FORMAT_MAX) { + const struct xe_oa_format *f = &oa->oa_formats[idx]; + + if (counter_size == f->counter_size && bc_report == f->bc_report && + type == f->type && counter_sel == f->counter_select) { + *name = idx; + return 0; + } + } + + return -EINVAL; +} + +/** + * xe_oa_unit_id - Return OA unit ID for a hardware engine + * @hwe: @xe_hw_engine + * + * Return OA unit ID for a hardware engine when available + */ +u16 xe_oa_unit_id(struct xe_hw_engine *hwe) +{ + return hwe->oa_unit && hwe->oa_unit->num_engines ? + hwe->oa_unit->oa_unit_id : U16_MAX; +} + +static int xe_oa_assign_hwe(struct xe_oa *oa, struct xe_oa_open_param *param) +{ + struct xe_gt *gt; + int i, ret = 0; + + if (param->exec_q) { + /* When we have an exec_q, get hwe from the exec_q */ + param->hwe = xe_gt_hw_engine(param->exec_q->gt, param->exec_q->class, + param->engine_instance, true); + } else { + struct xe_hw_engine *hwe; + enum xe_hw_engine_id id; + + /* Else just get the first hwe attached to the oa unit */ + for_each_gt(gt, oa->xe, i) { + for_each_hw_engine(hwe, gt, id) { + if (xe_oa_unit_id(hwe) == param->oa_unit_id) { + param->hwe = hwe; + goto out; + } + } + } + } +out: + if (!param->hwe || xe_oa_unit_id(param->hwe) != param->oa_unit_id) { + drm_dbg(&oa->xe->drm, "Unable to find hwe (%d, %d) for OA unit ID %d\n", + param->exec_q ? param->exec_q->class : -1, + param->engine_instance, param->oa_unit_id); + ret = -EINVAL; + } + + return ret; +} + +static int xe_oa_set_prop_oa_unit_id(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + if (value >= oa->oa_unit_ids) { + drm_dbg(&oa->xe->drm, "OA unit ID out of range %lld\n", value); + return -EINVAL; + } + param->oa_unit_id = value; + return 0; +} + +static int xe_oa_set_prop_sample_oa(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->sample = value; + return 0; +} + +static int xe_oa_set_prop_metric_set(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->metric_set = value; + return 0; +} + +static int xe_oa_set_prop_oa_format(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + int ret = decode_oa_format(oa, value, ¶m->oa_format); + + if (ret) { + drm_dbg(&oa->xe->drm, "Unsupported OA report format %#llx\n", value); + return ret; + } + return 0; +} + +static int xe_oa_set_prop_oa_exponent(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ +#define OA_EXPONENT_MAX 31 + + if (value > OA_EXPONENT_MAX) { + drm_dbg(&oa->xe->drm, "OA timer exponent too high (> %u)\n", OA_EXPONENT_MAX); + return -EINVAL; + } + param->period_exponent = value; + return 0; +} + +static int xe_oa_set_prop_disabled(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->disabled = value; + return 0; +} + +static int xe_oa_set_prop_exec_queue_id(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->exec_queue_id = value; + return 0; +} + +static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->engine_instance = value; + return 0; +} + +typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param); +static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = { + [DRM_XE_OA_PROPERTY_OA_UNIT_ID] = xe_oa_set_prop_oa_unit_id, + [DRM_XE_OA_PROPERTY_SAMPLE_OA] = xe_oa_set_prop_sample_oa, + [DRM_XE_OA_PROPERTY_OA_METRIC_SET] = xe_oa_set_prop_metric_set, + [DRM_XE_OA_PROPERTY_OA_FORMAT] = xe_oa_set_prop_oa_format, + [DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT] = xe_oa_set_prop_oa_exponent, + [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled, + [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id, + [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance, +}; + +static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension, + struct xe_oa_open_param *param) +{ + u64 __user *address = u64_to_user_ptr(extension); + struct drm_xe_ext_set_property ext; + int err; + u32 idx; + + err = __copy_from_user(&ext, address, sizeof(ext)); + if (XE_IOCTL_DBG(oa->xe, err)) + return -EFAULT; + + if (XE_IOCTL_DBG(oa->xe, ext.property >= ARRAY_SIZE(xe_oa_set_property_funcs)) || + XE_IOCTL_DBG(oa->xe, ext.pad)) + return -EINVAL; + + idx = array_index_nospec(ext.property, ARRAY_SIZE(xe_oa_set_property_funcs)); + return xe_oa_set_property_funcs[idx](oa, ext.value, param); +} + +typedef int (*xe_oa_user_extension_fn)(struct xe_oa *oa, u64 extension, + struct xe_oa_open_param *param); +static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = { + [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property, +}; + +static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number, + struct xe_oa_open_param *param) +{ + u64 __user *address = u64_to_user_ptr(extension); + struct drm_xe_user_extension ext; + int err; + u32 idx; + + if (XE_IOCTL_DBG(oa->xe, ext_number >= DRM_XE_OA_PROPERTY_MAX)) + return -E2BIG; + + err = __copy_from_user(&ext, address, sizeof(ext)); + if (XE_IOCTL_DBG(oa->xe, err)) + return -EFAULT; + + if (XE_IOCTL_DBG(oa->xe, ext.pad) || + XE_IOCTL_DBG(oa->xe, ext.name >= ARRAY_SIZE(xe_oa_user_extension_funcs))) + return -EINVAL; + + idx = array_index_nospec(ext.name, ARRAY_SIZE(xe_oa_user_extension_funcs)); + err = xe_oa_user_extension_funcs[idx](oa, extension, param); + if (XE_IOCTL_DBG(oa->xe, err)) + return err; + + if (ext.next_extension) + return xe_oa_user_extensions(oa, ext.next_extension, ++ext_number, param); + + return 0; +} + +/** + * xe_oa_stream_open_ioctl - Opens an OA stream + * @dev: @drm_device + * @data: pointer to struct @drm_xe_oa_config + * @file: @drm_file + * + * The functions opens an OA stream. An OA stream, opened with specified + * properties, enables perf counter samples to be collected, either + * periodically (time based sampling), or on request (using perf queries) + */ +int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *file) +{ + struct xe_oa *oa = &to_xe_device(dev)->oa; + struct xe_file *xef = to_xe_file(file); + struct xe_oa_open_param param = {}; + const struct xe_oa_format *f; + bool privileged_op = true; + int ret; + + if (!oa->xe) { + drm_dbg(&oa->xe->drm, "xe oa interface not available for this system\n"); + return -ENODEV; + } + + ret = xe_oa_user_extensions(oa, data, 0, ¶m); + if (ret) + return ret; + + if (param.exec_queue_id > 0) { + param.exec_q = xe_exec_queue_lookup(xef, param.exec_queue_id); + if (XE_IOCTL_DBG(oa->xe, !param.exec_q)) + return -ENOENT; + } + + /* + * Query based sampling (using MI_REPORT_PERF_COUNT) with OAR/OAC, + * without global stream access, can be an unprivileged operation + */ + if (param.exec_q && !param.sample) + privileged_op = false; + + if (privileged_op && xe_perf_stream_paranoid && !perfmon_capable()) { + drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe perf stream\n"); + ret = -EACCES; + goto err_exec_q; + } + + if (!param.exec_q && !param.sample) { + drm_dbg(&oa->xe->drm, "Only OA report sampling supported\n"); + ret = -EINVAL; + goto err_exec_q; + } + + ret = xe_oa_assign_hwe(oa, ¶m); + if (ret) + goto err_exec_q; + + f = &oa->oa_formats[param.oa_format]; + if (!param.oa_format || !f->size || + !engine_supports_oa_format(param.hwe, f->type)) { + drm_dbg(&oa->xe->drm, "Invalid OA format %d type %d size %d for class %d\n", + param.oa_format, f->type, f->size, param.hwe->class); + ret = -EINVAL; + goto err_exec_q; + } + + if (param.period_exponent > 0) { + u64 oa_period, oa_freq_hz; + + /* Requesting samples from OAG buffer is a privileged operation */ + if (!param.sample) { + drm_dbg(&oa->xe->drm, "OA_EXPONENT specified without SAMPLE_OA\n"); + ret = -EINVAL; + goto err_exec_q; + } + oa_period = oa_exponent_to_ns(param.hwe->gt, param.period_exponent); + oa_freq_hz = div64_u64(NSEC_PER_SEC, oa_period); + drm_dbg(&oa->xe->drm, "Using periodic sampling freq %lld Hz\n", oa_freq_hz); + } +err_exec_q: + if (ret < 0 && param.exec_q) + xe_exec_queue_put(param.exec_q); + return ret; +} + static bool xe_oa_is_valid_flex_addr(struct xe_oa *oa, u32 addr) { static const struct xe_reg flex_eu_regs[] = { diff --git a/drivers/gpu/drm/xe/xe_oa.h b/drivers/gpu/drm/xe/xe_oa.h index 5ccc772e047a..87a38820c317 100644 --- a/drivers/gpu/drm/xe/xe_oa.h +++ b/drivers/gpu/drm/xe/xe_oa.h @@ -11,12 +11,17 @@ struct drm_device; struct drm_file; struct xe_device; +struct xe_gt; +struct xe_hw_engine; int xe_oa_init(struct xe_device *xe); void xe_oa_fini(struct xe_device *xe); void xe_oa_register(struct xe_device *xe); void xe_oa_unregister(struct xe_device *xe); +int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *file); int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file); int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file); +u32 xe_oa_timestamp_frequency(struct xe_gt *gt); +u16 xe_oa_unit_id(struct xe_hw_engine *hwe); #endif diff --git a/drivers/gpu/drm/xe/xe_perf.c b/drivers/gpu/drm/xe/xe_perf.c index ca01042d75b1..d6cd74cadf34 100644 --- a/drivers/gpu/drm/xe/xe_perf.c +++ b/drivers/gpu/drm/xe/xe_perf.c @@ -18,6 +18,8 @@ static int xe_oa_ioctl(struct drm_device *dev, struct drm_xe_perf_param *arg, struct drm_file *file) { switch (arg->perf_op) { + case DRM_XE_PERF_OP_STREAM_OPEN: + return xe_oa_stream_open_ioctl(dev, arg->param, file); case DRM_XE_PERF_OP_ADD_CONFIG: return xe_oa_add_config_ioctl(dev, arg->param, file); case DRM_XE_PERF_OP_REMOVE_CONFIG: diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index fd9a4bd9e3d4..307409f968e2 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1470,6 +1470,78 @@ enum drm_xe_oa_format_type { DRM_XE_OA_FMT_TYPE_PEC, }; +/** + * enum drm_xe_oa_property_id - OA stream property id's + * + * Stream params are specified as a chain of @drm_xe_ext_set_property + * struct's, with @property values from enum @drm_xe_oa_property_id and + * @drm_xe_user_extension base.name set to @DRM_XE_OA_EXTENSION_SET_PROPERTY. + * @param field in struct @drm_xe_perf_param points to the first + * @drm_xe_ext_set_property struct. + */ +enum drm_xe_oa_property_id { +#define DRM_XE_OA_EXTENSION_SET_PROPERTY 0 + /** + * @DRM_XE_OA_PROPERTY_OA_UNIT_ID: ID of the OA unit on which to open + * the OA stream, see @oa_unit_id in 'struct + * drm_xe_query_oa_units'. Defaults to 0 if not provided. + */ + DRM_XE_OA_PROPERTY_OA_UNIT_ID = 1, + + /** + * @DRM_XE_OA_PROPERTY_SAMPLE_OA: A value of 1 requests inclusion of raw + * OA unit reports or stream samples in a global buffer attached to an + * OA unit. + */ + DRM_XE_OA_PROPERTY_SAMPLE_OA, + + /** + * @DRM_XE_OA_PROPERTY_OA_METRIC_SET: OA metrics defining contents of OA + * reports, previously added via @DRM_XE_PERF_OP_ADD_CONFIG. + */ + DRM_XE_OA_PROPERTY_OA_METRIC_SET, + + /** @DRM_XE_OA_PROPERTY_OA_FORMAT: Perf counter report format */ + DRM_XE_OA_PROPERTY_OA_FORMAT, + /* + * OA_FORMAT's are specified the same way as in PRM/Bspec 52198/60942, + * in terms of the following quantities: a. enum @drm_xe_oa_format_type + * b. Counter select c. Counter size and d. BC report. Also refer to the + * oa_formats array in drivers/gpu/drm/xe/xe_oa.c. + */ +#define DRM_XE_OA_FORMAT_MASK_FMT_TYPE (0xff << 0) +#define DRM_XE_OA_FORMAT_MASK_COUNTER_SEL (0xff << 8) +#define DRM_XE_OA_FORMAT_MASK_COUNTER_SIZE (0xff << 16) +#define DRM_XE_OA_FORMAT_MASK_BC_REPORT (0xff << 24) + + /** + * @DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT: Requests periodic OA unit + * sampling with sampling frequency proportional to 2^(period_exponent + 1) + */ + DRM_XE_OA_PROPERTY_OA_PERIOD_EXPONENT, + + /** + * @DRM_XE_OA_PROPERTY_OA_DISABLED: A value of 1 will open the OA + * stream in a DISABLED state (see @DRM_XE_PERF_IOCTL_ENABLE). + */ + DRM_XE_OA_PROPERTY_OA_DISABLED, + + /** + * @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID: Open the stream for a specific + * @exec_queue_id. Perf queries can be executed on this exec queue. + */ + DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID, + + /** + * @DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE: Optional engine instance to + * pass along with @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID or will default to 0. + */ + DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE, + + /** @DRM_XE_OA_PROPERTY_MAX: non-ABI */ + DRM_XE_OA_PROPERTY_MAX +}; + /** * struct drm_xe_oa_config - OA metric configuration * -- cgit v1.2.3 From e936f885f1e96f59d9d05fb6cb5a02b9b9b88a05 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:46:00 -0700 Subject: drm/xe/oa/uapi: Expose OA stream fd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OA stream open perf op returns an fd with its own file_operations for the newly initialized OA stream. These file_operations allow userspace to enable or disable the stream, as well as apply a different metric configuration for the OA stream. Userspace can also poll for data availability. OA stream initialization is completed in this commit by enabling the OA stream. When sampling is enabled this starts a hrtimer which periodically checks for data availablility. v2: Use stream properties for stream reconfiguration with DRM_XE_PERF_IOCTL_CONFIG v3: Hold runtime_pm reference across oa buffer alloc/free v4: Fix 32 bit build Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-9-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 380 +++++++++++++++++++++++++++++++++++++++++++++ include/uapi/drm/xe_drm.h | 4 + 2 files changed, 384 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index c2fd2d22677f..a71111859190 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -3,8 +3,10 @@ * Copyright © 2023-2024 Intel Corporation */ +#include #include #include +#include #include #include @@ -29,6 +31,7 @@ #include "xe_pm.h" #include "xe_sched_job.h" +#define OA_TAKEN(tail, head) (((tail) - (head)) & (XE_OA_BUFFER_SIZE - 1)) #define DEFAULT_POLL_FREQUENCY_HZ 200 #define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ) #define XE_OA_UNIT_INVALID U32_MAX @@ -147,6 +150,205 @@ static const struct xe_oa_regs *__oa_regs(struct xe_oa_stream *stream) return &stream->hwe->oa_unit->regs; } +static u32 xe_oa_hw_tail_read(struct xe_oa_stream *stream) +{ + return xe_mmio_read32(stream->gt, __oa_regs(stream)->oa_tail_ptr) & + OAG_OATAILPTR_MASK; +} + +#define oa_report_header_64bit(__s) \ + ((__s)->oa_buffer.format->header == HDR_64_BIT) + +static u64 oa_report_id(struct xe_oa_stream *stream, void *report) +{ + return oa_report_header_64bit(stream) ? *(u64 *)report : *(u32 *)report; +} + +static u64 oa_timestamp(struct xe_oa_stream *stream, void *report) +{ + return oa_report_header_64bit(stream) ? + *((u64 *)report + 1) : + *((u32 *)report + 1); +} + +static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream) +{ + u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); + int report_size = stream->oa_buffer.format->size; + u32 tail, hw_tail; + unsigned long flags; + bool pollin; + u32 partial_report_size; + + spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); + + hw_tail = xe_oa_hw_tail_read(stream); + hw_tail -= gtt_offset; + + /* + * The tail pointer increases in 64 byte (cacheline size), not in report_size + * increments. Also report size may not be a power of 2. Compute potential + * partially landed report in OA buffer. + */ + partial_report_size = OA_TAKEN(hw_tail, stream->oa_buffer.tail); + partial_report_size %= report_size; + + /* Subtract partial amount off the tail */ + hw_tail = OA_TAKEN(hw_tail, partial_report_size); + + tail = hw_tail; + + /* + * Walk the stream backward until we find a report with report id and timestamp + * not 0. We can't tell whether a report has fully landed in memory before the + * report id and timestamp of the following report have landed. + * + * This is assuming that the writes of the OA unit land in memory in the order + * they were written. If not : (╯°□°)╯︵ ┻━┻ + */ + while (OA_TAKEN(tail, stream->oa_buffer.tail) >= report_size) { + void *report = stream->oa_buffer.vaddr + tail; + + if (oa_report_id(stream, report) || oa_timestamp(stream, report)) + break; + + tail = OA_TAKEN(tail, report_size); + } + + if (OA_TAKEN(hw_tail, tail) > report_size) + drm_dbg(&stream->oa->xe->drm, + "unlanded report(s) head=0x%x tail=0x%x hw_tail=0x%x\n", + stream->oa_buffer.head, tail, hw_tail); + + stream->oa_buffer.tail = tail; + + pollin = OA_TAKEN(stream->oa_buffer.tail, + stream->oa_buffer.head) >= report_size; + + spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags); + + return pollin; +} + +static enum hrtimer_restart xe_oa_poll_check_timer_cb(struct hrtimer *hrtimer) +{ + struct xe_oa_stream *stream = + container_of(hrtimer, typeof(*stream), poll_check_timer); + + if (xe_oa_buffer_check_unlocked(stream)) { + stream->pollin = true; + wake_up(&stream->poll_wq); + } + + hrtimer_forward_now(hrtimer, ns_to_ktime(stream->poll_period_ns)); + + return HRTIMER_RESTART; +} + +static void xe_oa_init_oa_buffer(struct xe_oa_stream *stream) +{ + u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); + u32 oa_buf = gtt_offset | OABUFFER_SIZE_16M | OAG_OABUFFER_MEMORY_SELECT; + unsigned long flags; + + spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); + + xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_status, 0); + xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_head_ptr, + gtt_offset & OAG_OAHEADPTR_MASK); + stream->oa_buffer.head = 0; + + /* + * PRM says: "This MMIO must be set before the OATAILPTR register and after the + * OAHEADPTR register. This is to enable proper functionality of the overflow bit". + */ + xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_buffer, oa_buf); + xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_tail_ptr, + gtt_offset & OAG_OATAILPTR_MASK); + + /* Mark that we need updated tail pointer to read from */ + stream->oa_buffer.tail = 0; + + spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags); + + /* Zero out the OA buffer since we rely on zero report id and timestamp fields */ + memset(stream->oa_buffer.vaddr, 0, stream->oa_buffer.bo->size); +} + +static u32 __format_to_oactrl(const struct xe_oa_format *format, int counter_sel_mask) +{ + return ((format->counter_select << (ffs(counter_sel_mask) - 1)) & counter_sel_mask) | + REG_FIELD_PREP(OA_OACONTROL_REPORT_BC_MASK, format->bc_report) | + REG_FIELD_PREP(OA_OACONTROL_COUNTER_SIZE_MASK, format->counter_size); +} + +static void xe_oa_enable(struct xe_oa_stream *stream) +{ + const struct xe_oa_format *format = stream->oa_buffer.format; + const struct xe_oa_regs *regs; + u32 val; + + /* + * BSpec: 46822: Bit 0. Even if stream->sample is 0, for OAR to function, the OA + * buffer must be correctly initialized + */ + xe_oa_init_oa_buffer(stream); + + regs = __oa_regs(stream); + val = __format_to_oactrl(format, regs->oa_ctrl_counter_select_mask) | + OAG_OACONTROL_OA_COUNTER_ENABLE; + + xe_mmio_write32(stream->gt, regs->oa_ctrl, val); +} + +static void xe_oa_disable(struct xe_oa_stream *stream) +{ + xe_mmio_write32(stream->gt, __oa_regs(stream)->oa_ctrl, 0); + if (xe_mmio_wait32(stream->gt, __oa_regs(stream)->oa_ctrl, + OAG_OACONTROL_OA_COUNTER_ENABLE, 0, 50000, NULL, false)) + drm_err(&stream->oa->xe->drm, + "wait for OA to be disabled timed out\n"); + + if (GRAPHICS_VERx100(stream->oa->xe) <= 1270 && GRAPHICS_VERx100(stream->oa->xe) != 1260) { + /* <= XE_METEORLAKE except XE_PVC */ + xe_mmio_write32(stream->gt, OA_TLB_INV_CR, 1); + if (xe_mmio_wait32(stream->gt, OA_TLB_INV_CR, 1, 0, 50000, NULL, false)) + drm_err(&stream->oa->xe->drm, + "wait for OA tlb invalidate timed out\n"); + } +} + +static __poll_t xe_oa_poll_locked(struct xe_oa_stream *stream, + struct file *file, poll_table *wait) +{ + __poll_t events = 0; + + poll_wait(file, &stream->poll_wq, wait); + + /* + * We don't explicitly check whether there's something to read here since this + * path may be hot depending on what else userspace is polling, or on the timeout + * in use. We rely on hrtimer xe_oa_poll_check_timer_cb to notify us when there + * are samples to read + */ + if (stream->pollin) + events |= EPOLLIN; + + return events; +} + +static __poll_t xe_oa_poll(struct file *file, poll_table *wait) +{ + struct xe_oa_stream *stream = file->private_data; + __poll_t ret; + + mutex_lock(&stream->stream_lock); + ret = xe_oa_poll_locked(stream, file, wait); + mutex_unlock(&stream->stream_lock); + + return ret; +} + static int xe_oa_submit_bb(struct xe_oa_stream *stream, struct xe_bb *bb) { struct xe_sched_job *job; @@ -246,6 +448,27 @@ static void xe_oa_disable_metric_set(struct xe_oa_stream *stream) xe_mmio_rmw32(stream->gt, XELPMP_SQCNT1, sqcnt1, 0); } +static void xe_oa_stream_destroy(struct xe_oa_stream *stream) +{ + struct xe_oa_unit *u = stream->hwe->oa_unit; + struct xe_gt *gt = stream->hwe->gt; + + if (WARN_ON(stream != u->exclusive_stream)) + return; + + WRITE_ONCE(u->exclusive_stream, NULL); + + xe_oa_disable_metric_set(stream); + xe_exec_queue_put(stream->k_exec_q); + + xe_oa_free_oa_buffer(stream); + + XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL)); + xe_pm_runtime_put(stream->oa->xe); + + xe_oa_free_configs(stream); +} + static int xe_oa_alloc_oa_buffer(struct xe_oa_stream *stream) { struct xe_bo *bo; @@ -383,6 +606,148 @@ static int xe_oa_enable_metric_set(struct xe_oa_stream *stream) return xe_oa_emit_oa_config(stream); } +static void xe_oa_stream_enable(struct xe_oa_stream *stream) +{ + stream->pollin = false; + + xe_oa_enable(stream); + + if (stream->sample) + hrtimer_start(&stream->poll_check_timer, + ns_to_ktime(stream->poll_period_ns), + HRTIMER_MODE_REL_PINNED); +} + +static void xe_oa_stream_disable(struct xe_oa_stream *stream) +{ + xe_oa_disable(stream); + + if (stream->sample) + hrtimer_cancel(&stream->poll_check_timer); +} + +static void xe_oa_enable_locked(struct xe_oa_stream *stream) +{ + if (stream->enabled) + return; + + stream->enabled = true; + + xe_oa_stream_enable(stream); +} + +static void xe_oa_disable_locked(struct xe_oa_stream *stream) +{ + if (!stream->enabled) + return; + + stream->enabled = false; + + xe_oa_stream_disable(stream); +} + +static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg) +{ + struct drm_xe_ext_set_property ext; + long ret = stream->oa_config->id; + struct xe_oa_config *config; + int err; + + err = __copy_from_user(&ext, u64_to_user_ptr(arg), sizeof(ext)); + if (XE_IOCTL_DBG(stream->oa->xe, err)) + return -EFAULT; + + if (XE_IOCTL_DBG(stream->oa->xe, ext.pad) || + XE_IOCTL_DBG(stream->oa->xe, ext.base.name != DRM_XE_OA_EXTENSION_SET_PROPERTY) || + XE_IOCTL_DBG(stream->oa->xe, ext.base.next_extension) || + XE_IOCTL_DBG(stream->oa->xe, ext.property != DRM_XE_OA_PROPERTY_OA_METRIC_SET)) + return -EINVAL; + + config = xe_oa_get_oa_config(stream->oa, ext.value); + if (!config) + return -ENODEV; + + if (config != stream->oa_config) { + err = xe_oa_emit_oa_config(stream); + if (!err) + config = xchg(&stream->oa_config, config); + else + ret = err; + } + + xe_oa_config_put(config); + + return ret; +} + +static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, + unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case DRM_XE_PERF_IOCTL_ENABLE: + xe_oa_enable_locked(stream); + return 0; + case DRM_XE_PERF_IOCTL_DISABLE: + xe_oa_disable_locked(stream); + return 0; + case DRM_XE_PERF_IOCTL_CONFIG: + return xe_oa_config_locked(stream, arg); + } + + return -EINVAL; +} + +static long xe_oa_ioctl(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + struct xe_oa_stream *stream = file->private_data; + long ret; + + mutex_lock(&stream->stream_lock); + ret = xe_oa_ioctl_locked(stream, cmd, arg); + mutex_unlock(&stream->stream_lock); + + return ret; +} + +static void xe_oa_destroy_locked(struct xe_oa_stream *stream) +{ + if (stream->enabled) + xe_oa_disable_locked(stream); + + xe_oa_stream_destroy(stream); + + if (stream->exec_q) + xe_exec_queue_put(stream->exec_q); + + kfree(stream); +} + +static int xe_oa_release(struct inode *inode, struct file *file) +{ + struct xe_oa_stream *stream = file->private_data; + struct xe_gt *gt = stream->gt; + + mutex_lock(>->oa.gt_lock); + xe_oa_destroy_locked(stream); + mutex_unlock(>->oa.gt_lock); + + /* Release the reference the perf stream kept on the driver */ + drm_dev_put(>_to_xe(gt)->drm); + + return 0; +} + +static const struct file_operations xe_oa_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .release = xe_oa_release, + .poll = xe_oa_poll, + .unlocked_ioctl = xe_oa_ioctl, +}; + static int xe_oa_stream_init(struct xe_oa_stream *stream, struct xe_oa_open_param *param) { @@ -436,6 +801,10 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream, WRITE_ONCE(u->exclusive_stream, stream); + hrtimer_init(&stream->poll_check_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + stream->poll_check_timer.function = xe_oa_poll_check_timer_cb; + init_waitqueue_head(&stream->poll_wq); + spin_lock_init(&stream->oa_buffer.ptr_lock); mutex_init(&stream->stream_lock); @@ -479,10 +848,21 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa, if (ret) goto err_free; + stream_fd = anon_inode_getfd("[xe_oa]", &xe_oa_fops, stream, 0); + if (stream_fd < 0) { + ret = stream_fd; + goto err_destroy; + } + + if (!param->disabled) + xe_oa_enable_locked(stream); + /* Hold a reference on the drm device till stream_fd is released */ drm_dev_get(&stream->oa->xe->drm); return stream_fd; +err_destroy: + xe_oa_stream_destroy(stream); err_free: kfree(stream); exit: diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 307409f968e2..1e09f786b3e6 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1478,6 +1478,10 @@ enum drm_xe_oa_format_type { * @drm_xe_user_extension base.name set to @DRM_XE_OA_EXTENSION_SET_PROPERTY. * @param field in struct @drm_xe_perf_param points to the first * @drm_xe_ext_set_property struct. + * + * Exactly the same mechanism is also used for stream reconfiguration using + * the @DRM_XE_PERF_IOCTL_CONFIG perf fd ioctl, though only a subset of + * properties below can be specified for stream reconfiguration. */ enum drm_xe_oa_property_id { #define DRM_XE_OA_EXTENSION_SET_PROPERTY 0 -- cgit v1.2.3 From efb315d0a013cdc8b1e49f5c07b1a2972bc624d4 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:46:01 -0700 Subject: drm/xe/oa/uapi: Read file_operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement the OA stream read file_operation. Both blocking and non-blocking reads are supported. As part of read system call, the read copies OA perf data from the OA buffer to the user buffer, after appending packet headers for status and data packets. v2: Drop OA report headers, implement DRM_XE_PERF_IOCTL_STATUS (Umesh) v3: Introduce 'struct drm_xe_oa_stream_status' v4: Define oa_status register bitfields (Umesh) v5: Add extensions to 'struct drm_xe_oa_stream_status' v6: Minor cleanup, eliminate report32 variable v7: Use -EIO to signal to userspace to read OASTATUS using DRM_XE_PERF_IOCTL_STATUS, change previous sites returning -EIO to return -EINVAL Make drm_xe_oa_stream_status bits contiguous (Jose, Umesh) rmw oa_status bits (Umesh) Acked-by: Rodrigo Vivi Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-10-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 201 +++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_oa_types.h | 3 + include/uapi/drm/xe_drm.h | 20 ++++ 3 files changed, 224 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index a71111859190..86d56b080eff 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -164,6 +164,14 @@ static u64 oa_report_id(struct xe_oa_stream *stream, void *report) return oa_report_header_64bit(stream) ? *(u64 *)report : *(u32 *)report; } +static void oa_report_id_clear(struct xe_oa_stream *stream, u32 *report) +{ + if (oa_report_header_64bit(stream)) + *(u64 *)report = 0; + else + *report = 0; +} + static u64 oa_timestamp(struct xe_oa_stream *stream, void *report) { return oa_report_header_64bit(stream) ? @@ -171,6 +179,14 @@ static u64 oa_timestamp(struct xe_oa_stream *stream, void *report) *((u32 *)report + 1); } +static void oa_timestamp_clear(struct xe_oa_stream *stream, u32 *report) +{ + if (oa_report_header_64bit(stream)) + *(u64 *)&report[2] = 0; + else + report[1] = 0; +} + static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream) { u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); @@ -245,6 +261,95 @@ static enum hrtimer_restart xe_oa_poll_check_timer_cb(struct hrtimer *hrtimer) return HRTIMER_RESTART; } +static int xe_oa_append_report(struct xe_oa_stream *stream, char __user *buf, + size_t count, size_t *offset, const u8 *report) +{ + int report_size = stream->oa_buffer.format->size; + int report_size_partial; + u8 *oa_buf_end; + + if ((count - *offset) < report_size) + return -ENOSPC; + + buf += *offset; + + oa_buf_end = stream->oa_buffer.vaddr + XE_OA_BUFFER_SIZE; + report_size_partial = oa_buf_end - report; + + if (report_size_partial < report_size) { + if (copy_to_user(buf, report, report_size_partial)) + return -EFAULT; + buf += report_size_partial; + + if (copy_to_user(buf, stream->oa_buffer.vaddr, + report_size - report_size_partial)) + return -EFAULT; + } else if (copy_to_user(buf, report, report_size)) { + return -EFAULT; + } + + *offset += report_size; + + return 0; +} + +static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf, + size_t count, size_t *offset) +{ + int report_size = stream->oa_buffer.format->size; + u8 *oa_buf_base = stream->oa_buffer.vaddr; + u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); + u32 mask = (XE_OA_BUFFER_SIZE - 1); + size_t start_offset = *offset; + unsigned long flags; + u32 head, tail; + int ret = 0; + + spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); + head = stream->oa_buffer.head; + tail = stream->oa_buffer.tail; + spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags); + + xe_assert(stream->oa->xe, head < XE_OA_BUFFER_SIZE && tail < XE_OA_BUFFER_SIZE); + + for (; OA_TAKEN(tail, head); head = (head + report_size) & mask) { + u8 *report = oa_buf_base + head; + + ret = xe_oa_append_report(stream, buf, count, offset, report); + if (ret) + break; + + if (is_power_of_2(report_size)) { + /* Clear out report id and timestamp to detect unlanded reports */ + oa_report_id_clear(stream, (void *)report); + oa_timestamp_clear(stream, (void *)report); + } else { + u8 *oa_buf_end = stream->oa_buffer.vaddr + XE_OA_BUFFER_SIZE; + u32 part = oa_buf_end - report; + + /* Zero out the entire report */ + if (report_size <= part) { + memset(report, 0, report_size); + } else { + memset(report, 0, part); + memset(oa_buf_base, 0, report_size - part); + } + } + } + + if (start_offset != *offset) { + struct xe_reg oaheadptr = __oa_regs(stream)->oa_head_ptr; + + spin_lock_irqsave(&stream->oa_buffer.ptr_lock, flags); + xe_mmio_write32(stream->gt, oaheadptr, + (head + gtt_offset) & OAG_OAHEADPTR_MASK); + stream->oa_buffer.head = head; + spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags); + } + + return ret; +} + static void xe_oa_init_oa_buffer(struct xe_oa_stream *stream) { u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo); @@ -318,6 +423,78 @@ static void xe_oa_disable(struct xe_oa_stream *stream) } } +static int xe_oa_wait_unlocked(struct xe_oa_stream *stream) +{ + /* We might wait indefinitely if periodic sampling is not enabled */ + if (!stream->periodic) + return -EINVAL; + + return wait_event_interruptible(stream->poll_wq, + xe_oa_buffer_check_unlocked(stream)); +} + +#define OASTATUS_RELEVANT_BITS (OASTATUS_MMIO_TRG_Q_FULL | OASTATUS_COUNTER_OVERFLOW | \ + OASTATUS_BUFFER_OVERFLOW | OASTATUS_REPORT_LOST) + +static int __xe_oa_read(struct xe_oa_stream *stream, char __user *buf, + size_t count, size_t *offset) +{ + /* Only clear our bits to avoid side-effects */ + stream->oa_status = xe_mmio_rmw32(stream->gt, __oa_regs(stream)->oa_status, + OASTATUS_RELEVANT_BITS, 0); + /* + * Signal to userspace that there is non-zero OA status to read via + * @DRM_XE_PERF_IOCTL_STATUS perf fd ioctl + */ + if (stream->oa_status & OASTATUS_RELEVANT_BITS) + return -EIO; + + return xe_oa_append_reports(stream, buf, count, offset); +} + +static ssize_t xe_oa_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct xe_oa_stream *stream = file->private_data; + size_t offset = 0; + int ret; + + /* Can't read from disabled streams */ + if (!stream->enabled || !stream->sample) + return -EINVAL; + + if (!(file->f_flags & O_NONBLOCK)) { + do { + ret = xe_oa_wait_unlocked(stream); + if (ret) + return ret; + + mutex_lock(&stream->stream_lock); + ret = __xe_oa_read(stream, buf, count, &offset); + mutex_unlock(&stream->stream_lock); + } while (!offset && !ret); + } else { + mutex_lock(&stream->stream_lock); + ret = __xe_oa_read(stream, buf, count, &offset); + mutex_unlock(&stream->stream_lock); + } + + /* + * Typically we clear pollin here in order to wait for the new hrtimer callback + * before unblocking. The exception to this is if __xe_oa_read returns -ENOSPC, + * which means that more OA data is available than could fit in the user provided + * buffer. In this case we want the next poll() call to not block. + * + * Also in case of -EIO, we have already waited for data before returning + * -EIO, so need to wait again + */ + if (ret != -ENOSPC && ret != -EIO) + stream->pollin = false; + + /* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, -EINVAL, ... */ + return offset ?: (ret ?: -EAGAIN); +} + static __poll_t xe_oa_poll_locked(struct xe_oa_stream *stream, struct file *file, poll_table *wait) { @@ -680,6 +857,27 @@ static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg) return ret; } +static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg) +{ + struct drm_xe_oa_stream_status status = {}; + void __user *uaddr = (void __user *)arg; + + /* Map from register to uapi bits */ + if (stream->oa_status & OASTATUS_REPORT_LOST) + status.oa_status |= DRM_XE_OASTATUS_REPORT_LOST; + if (stream->oa_status & OASTATUS_BUFFER_OVERFLOW) + status.oa_status |= DRM_XE_OASTATUS_BUFFER_OVERFLOW; + if (stream->oa_status & OASTATUS_COUNTER_OVERFLOW) + status.oa_status |= DRM_XE_OASTATUS_COUNTER_OVERFLOW; + if (stream->oa_status & OASTATUS_MMIO_TRG_Q_FULL) + status.oa_status |= DRM_XE_OASTATUS_MMIO_TRG_Q_FULL; + + if (copy_to_user(uaddr, &status, sizeof(status))) + return -EFAULT; + + return 0; +} + static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, unsigned int cmd, unsigned long arg) @@ -693,6 +891,8 @@ static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, return 0; case DRM_XE_PERF_IOCTL_CONFIG: return xe_oa_config_locked(stream, arg); + case DRM_XE_PERF_IOCTL_STATUS: + return xe_oa_status_locked(stream, arg); } return -EINVAL; @@ -745,6 +945,7 @@ static const struct file_operations xe_oa_fops = { .llseek = no_llseek, .release = xe_oa_release, .poll = xe_oa_poll, + .read = xe_oa_read, .unlocked_ioctl = xe_oa_ioctl, }; diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h index 6700383b1a52..5bb8ce0d71c9 100644 --- a/drivers/gpu/drm/xe/xe_oa_types.h +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -222,5 +222,8 @@ struct xe_oa_stream { /** @poll_period_ns: hrtimer period for checking OA buffer for available data */ u64 poll_period_ns; + + /** @oa_status: temporary storage for oa_status register value */ + u32 oa_status; }; #endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 1e09f786b3e6..03a6e479227a 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1570,6 +1570,26 @@ struct drm_xe_oa_config { __u64 regs_ptr; }; +/** + * struct drm_xe_oa_stream_status - OA stream status returned from + * @DRM_XE_PERF_IOCTL_STATUS perf fd ioctl. Userspace can call the ioctl to + * query stream status in response to EIO errno from perf fd read(). + */ +struct drm_xe_oa_stream_status { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @oa_status: OA stream status (see Bspec 46717/61226) */ + __u64 oa_status; +#define DRM_XE_OASTATUS_MMIO_TRG_Q_FULL (1 << 3) +#define DRM_XE_OASTATUS_COUNTER_OVERFLOW (1 << 2) +#define DRM_XE_OASTATUS_BUFFER_OVERFLOW (1 << 1) +#define DRM_XE_OASTATUS_REPORT_LOST (1 << 0) + + /** @reserved: reserved for future use */ + __u64 reserved[3]; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From dd6b4718c3bab611588922ae8a7736c58eafcc93 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Mon, 17 Jun 2024 18:46:04 -0700 Subject: drm/xe/oa/uapi: Query OA unit properties Implement query for properties of OA units present on a device. v2: Clean up reserved/pad fields (Umesh) Follow the same scheme as other query structs v3: Skip reporting reserved engines attached to OA units v4: Expose oa_buf_size via DRM_XE_PERF_IOCTL_INFO (Umesh) v5: Don't expose capabilities as OR of properties (Umesh) v6: Add extensions to query output structs: drm_xe_oa_unit, drm_xe_query_oa_units and drm_xe_oa_stream_info v7: Change oa_units[] array to __u64 type Acked-by: Rodrigo Vivi Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240618014609.3233427-13-ashutosh.dixit@intel.com --- drivers/gpu/drm/xe/xe_oa.c | 13 +++++++ drivers/gpu/drm/xe/xe_query.c | 77 +++++++++++++++++++++++++++++++++++++++ include/uapi/drm/xe_drm.h | 85 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 42b0ba014e35..038caeb7c9e7 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -1050,6 +1050,17 @@ static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg) return 0; } +static long xe_oa_info_locked(struct xe_oa_stream *stream, unsigned long arg) +{ + struct drm_xe_oa_stream_info info = { .oa_buf_size = XE_OA_BUFFER_SIZE, }; + void __user *uaddr = (void __user *)arg; + + if (copy_to_user(uaddr, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, unsigned int cmd, unsigned long arg) @@ -1065,6 +1076,8 @@ static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, return xe_oa_config_locked(stream, arg); case DRM_XE_PERF_IOCTL_STATUS: return xe_oa_status_locked(stream, arg); + case DRM_XE_PERF_IOCTL_INFO: + return xe_oa_info_locked(stream, arg); } return -EINVAL; diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c index 995effcb904b..4e01df6b1b7a 100644 --- a/drivers/gpu/drm/xe/xe_query.c +++ b/drivers/gpu/drm/xe/xe_query.c @@ -602,6 +602,82 @@ query_uc_fw_version(struct xe_device *xe, struct drm_xe_device_query *query) return 0; } +static size_t calc_oa_unit_query_size(struct xe_device *xe) +{ + size_t size = sizeof(struct drm_xe_query_oa_units); + struct xe_gt *gt; + int i, id; + + for_each_gt(gt, xe, id) { + for (i = 0; i < gt->oa.num_oa_units; i++) { + size += sizeof(struct drm_xe_oa_unit); + size += gt->oa.oa_unit[i].num_engines * + sizeof(struct drm_xe_engine_class_instance); + } + } + + return size; +} + +static int query_oa_units(struct xe_device *xe, + struct drm_xe_device_query *query) +{ + void __user *query_ptr = u64_to_user_ptr(query->data); + size_t size = calc_oa_unit_query_size(xe); + struct drm_xe_query_oa_units *qoa; + enum xe_hw_engine_id hwe_id; + struct drm_xe_oa_unit *du; + struct xe_hw_engine *hwe; + struct xe_oa_unit *u; + int gt_id, i, j, ret; + struct xe_gt *gt; + u8 *pdu; + + if (query->size == 0) { + query->size = size; + return 0; + } else if (XE_IOCTL_DBG(xe, query->size != size)) { + return -EINVAL; + } + + qoa = kzalloc(size, GFP_KERNEL); + if (!qoa) + return -ENOMEM; + + pdu = (u8 *)&qoa->oa_units[0]; + for_each_gt(gt, xe, gt_id) { + for (i = 0; i < gt->oa.num_oa_units; i++) { + u = >->oa.oa_unit[i]; + du = (struct drm_xe_oa_unit *)pdu; + + du->oa_unit_id = u->oa_unit_id; + du->oa_unit_type = u->type; + du->oa_timestamp_freq = xe_oa_timestamp_frequency(gt); + du->capabilities = DRM_XE_OA_CAPS_BASE; + + j = 0; + for_each_hw_engine(hwe, gt, hwe_id) { + if (!xe_hw_engine_is_reserved(hwe) && + xe_oa_unit_id(hwe) == u->oa_unit_id) { + du->eci[j].engine_class = + xe_to_user_engine_class[hwe->class]; + du->eci[j].engine_instance = hwe->logical_instance; + du->eci[j].gt_id = gt->info.id; + j++; + } + } + du->num_engines = j; + pdu += sizeof(*du) + j * sizeof(du->eci[0]); + qoa->num_oa_units++; + } + } + + ret = copy_to_user(query_ptr, qoa, size); + kfree(qoa); + + return ret ? -EFAULT : 0; +} + static int (* const xe_query_funcs[])(struct xe_device *xe, struct drm_xe_device_query *query) = { query_engines, @@ -612,6 +688,7 @@ static int (* const xe_query_funcs[])(struct xe_device *xe, query_gt_topology, query_engine_cycles, query_uc_fw_version, + query_oa_units, }; int xe_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file) diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 03a6e479227a..93e00be44b2d 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -689,6 +689,7 @@ struct drm_xe_device_query { #define DRM_XE_DEVICE_QUERY_GT_TOPOLOGY 5 #define DRM_XE_DEVICE_QUERY_ENGINE_CYCLES 6 #define DRM_XE_DEVICE_QUERY_UC_FW_VERSION 7 +#define DRM_XE_DEVICE_QUERY_OA_UNITS 8 /** @query: The type of data to query */ __u32 query; @@ -1451,6 +1452,75 @@ enum drm_xe_oa_unit_type { DRM_XE_OA_UNIT_TYPE_OAM, }; +/** + * struct drm_xe_oa_unit - describe OA unit + */ +struct drm_xe_oa_unit { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @oa_unit_id: OA unit ID */ + __u32 oa_unit_id; + + /** @oa_unit_type: OA unit type of @drm_xe_oa_unit_type */ + __u32 oa_unit_type; + + /** @capabilities: OA capabilities bit-mask */ + __u64 capabilities; +#define DRM_XE_OA_CAPS_BASE (1 << 0) + + /** @oa_timestamp_freq: OA timestamp freq */ + __u64 oa_timestamp_freq; + + /** @reserved: MBZ */ + __u64 reserved[4]; + + /** @num_engines: number of engines in @eci array */ + __u64 num_engines; + + /** @eci: engines attached to this OA unit */ + struct drm_xe_engine_class_instance eci[]; +}; + +/** + * struct drm_xe_query_oa_units - describe OA units + * + * If a query is made with a struct drm_xe_device_query where .query + * is equal to DRM_XE_DEVICE_QUERY_OA_UNITS, then the reply uses struct + * drm_xe_query_oa_units in .data. + * + * OA unit properties for all OA units can be accessed using a code block + * such as the one below: + * + * .. code-block:: C + * + * struct drm_xe_query_oa_units *qoa; + * struct drm_xe_oa_unit *oau; + * u8 *poau; + * + * // malloc qoa and issue DRM_XE_DEVICE_QUERY_OA_UNITS. Then: + * poau = (u8 *)&qoa->oa_units[0]; + * for (int i = 0; i < qoa->num_oa_units; i++) { + * oau = (struct drm_xe_oa_unit *)poau; + * // Access 'struct drm_xe_oa_unit' fields here + * poau += sizeof(*oau) + oau->num_engines * sizeof(oau->eci[0]); + * } + */ +struct drm_xe_query_oa_units { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + /** @num_oa_units: number of OA units returned in oau[] */ + __u32 num_oa_units; + /** @pad: MBZ */ + __u32 pad; + /** + * @oa_units: struct @drm_xe_oa_unit array returned for this device. + * Written below as a u64 array to avoid problems with nested flexible + * arrays with some compilers + */ + __u64 oa_units[]; +}; + /** * enum drm_xe_oa_format_type - OA format types as specified in PRM/Bspec * 52198/60942 @@ -1590,6 +1660,21 @@ struct drm_xe_oa_stream_status { __u64 reserved[3]; }; +/** + * struct drm_xe_oa_stream_info - OA stream info returned from + * @DRM_XE_PERF_IOCTL_INFO perf fd ioctl + */ +struct drm_xe_oa_stream_info { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @oa_buf_size: OA buffer size */ + __u64 oa_buf_size; + + /** @reserved: reserved for future use */ + __u64 reserved[3]; +}; + #if defined(__cplusplus) } #endif -- cgit v1.2.3 From b9578c49456340ca4d3c7ddbaca054ffc2b51bc1 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 6 Jun 2024 14:02:13 +1200 Subject: dma-buf/heaps: Correct the types of fd_flags and heap_flags dma_heap_allocation_data defines the UAPI as follows: struct dma_heap_allocation_data { __u64 len; __u32 fd; __u32 fd_flags; __u64 heap_flags; }; But dma heaps are casting both fd_flags and heap_flags into unsigned long. This patch makes dma heaps - cma heap and system heap have consistent types with UAPI. Signed-off-by: Barry Song Acked-by: John Stultz Reviewed-by: Carlos Llamas Signed-off-by: Sumit Semwal Link: https://patchwork.freedesktop.org/patch/msgid/20240606020213.49854-1-21cnbao@gmail.com --- drivers/dma-buf/heaps/cma_heap.c | 4 ++-- drivers/dma-buf/heaps/system_heap.c | 4 ++-- include/linux/dma-heap.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 4a63567e93ba..c384004b918e 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -274,8 +274,8 @@ static const struct dma_buf_ops cma_heap_buf_ops = { static struct dma_buf *cma_heap_allocate(struct dma_heap *heap, unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags) + u32 fd_flags, + u64 heap_flags) { struct cma_heap *cma_heap = dma_heap_get_drvdata(heap); struct cma_heap_buffer *buffer; diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 9076d47ed2ef..d78cdb9d01e5 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -333,8 +333,8 @@ static struct page *alloc_largest_available(unsigned long size, static struct dma_buf *system_heap_allocate(struct dma_heap *heap, unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags) + u32 fd_flags, + u64 heap_flags) { struct system_heap_buffer *buffer; DEFINE_DMA_BUF_EXPORT_INFO(exp_info); diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h index 0c05561cad6e..064bad725061 100644 --- a/include/linux/dma-heap.h +++ b/include/linux/dma-heap.h @@ -23,8 +23,8 @@ struct dma_heap; struct dma_heap_ops { struct dma_buf *(*allocate)(struct dma_heap *heap, unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags); + u32 fd_flags, + u64 heap_flags); }; /** -- cgit v1.2.3 From 0ddd2ae586d28e521d37393364d989ce118802e0 Mon Sep 17 00:00:00 2001 From: Zhu Lingshan Date: Tue, 4 Jun 2024 16:49:34 +0800 Subject: drm/ttm: increase ttm pre-fault value to PMD size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ttm page fault handler ttm_bo_vm_fault_reserved() maps TTM_BO_VM_NUM_PREFAULT more pages beforehand due to the principle of locality. However, on some platform the page faults are more costly, this patch intends to increase the number of ttm pre-fault to relieve the number of page faults. When multiple levels of page table is supported, the new default value would be the PMD size, similar to huge page. Signed-off-by: Zhu Lingshan Reported-and-tested-by: Li Jingxiang Link: https://patchwork.freedesktop.org/patch/msgid/20240604084934.225738-1-lingshan.zhu@amd.com Reviewed-by: Christian König Signed-off-by: Christian König --- include/drm/ttm/ttm_bo.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/drm/ttm/ttm_bo.h b/include/drm/ttm/ttm_bo.h index 6ccf96c91f3a..ef0f52f56ebc 100644 --- a/include/drm/ttm/ttm_bo.h +++ b/include/drm/ttm/ttm_bo.h @@ -39,7 +39,11 @@ #include "ttm_device.h" /* Default number of pre-faulted pages in the TTM fault handler */ +#if CONFIG_PGTABLE_LEVELS > 2 +#define TTM_BO_VM_NUM_PREFAULT (1 << (PMD_SHIFT - PAGE_SHIFT)) +#else #define TTM_BO_VM_NUM_PREFAULT 16 +#endif struct iosys_map; -- cgit v1.2.3 From 90c3e2bc9ecbf3210d661fadee4c947d34a88ceb Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 30 Apr 2024 11:43:16 +0100 Subject: firmware: qcom_scm: Add gpu_init_regs call This will used by drm/msm to initialize GPU registers that Qualcomm's firmware doesn't make writeable to the kernel. Reviewed-by: Dmitry Baryshkov Signed-off-by: Connor Abbott Reviewed-by: Konrad Dybcio Acked-by: Bjorn Andersson Patchwork: https://patchwork.freedesktop.org/patch/592039/ Signed-off-by: Rob Clark --- drivers/firmware/qcom/qcom_scm.c | 14 ++++++++++++++ drivers/firmware/qcom/qcom_scm.h | 3 +++ include/linux/firmware/qcom/qcom_scm.h | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+) (limited to 'include') diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 68f4df7e6c3c..0f2e628f5cac 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1394,6 +1394,20 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, } EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh); +int qcom_scm_gpu_init_regs(u32 gpu_req) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_GPU, + .cmd = QCOM_SCM_SVC_GPU_INIT_REGS, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = gpu_req, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + return qcom_scm_call(__scm->dev, &desc, NULL); +} +EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs); + static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) { struct device_node *tcsr; diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index 4532907e8489..484e030bcac9 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -138,6 +138,9 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, #define QCOM_SCM_WAITQ_RESUME 0x02 #define QCOM_SCM_WAITQ_GET_WQ_CTX 0x03 +#define QCOM_SCM_SVC_GPU 0x28 +#define QCOM_SCM_SVC_GPU_INIT_REGS 0x01 + /* common error codes */ #define QCOM_SCM_V2_EBUSY -12 #define QCOM_SCM_ENOMEM -5 diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index aaa19f93ac43..a221a643dc12 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -115,6 +115,29 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, int qcom_scm_lmh_profile_change(u32 profile_id); bool qcom_scm_lmh_dcvsh_available(void); +/* + * Request TZ to program set of access controlled registers necessary + * irrespective of any features + */ +#define QCOM_SCM_GPU_ALWAYS_EN_REQ BIT(0) +/* + * Request TZ to program BCL id to access controlled register when BCL is + * enabled + */ +#define QCOM_SCM_GPU_BCL_EN_REQ BIT(1) +/* + * Request TZ to program set of access controlled register for CLX feature + * when enabled + */ +#define QCOM_SCM_GPU_CLX_EN_REQ BIT(2) +/* + * Request TZ to program tsense ids to access controlled registers for reading + * gpu temperature sensors + */ +#define QCOM_SCM_GPU_TSENSE_EN_REQ BIT(3) + +int qcom_scm_gpu_init_regs(u32 gpu_req); + #ifdef CONFIG_QCOM_QSEECOM int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id); -- cgit v1.2.3 From 41fd54ef74b02233a419b4929d26662e5f105f46 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Tue, 30 Apr 2024 11:43:19 +0100 Subject: drm/msm: Add MSM_PARAM_RAYTRACING uapi Expose the value of the software fuse to userspace. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Connor Abbott Patchwork: https://patchwork.freedesktop.org/patch/592044/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ include/uapi/drm/msm_drm.h | 1 + 2 files changed, 4 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 71a9acc002fe..1c6626747b98 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -376,6 +376,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, case MSM_PARAM_HIGHEST_BANK_BIT: *value = adreno_gpu->ubwc_config.highest_bank_bit; return 0; + case MSM_PARAM_RAYTRACING: + *value = adreno_gpu->has_ray_tracing; + return 0; default: DBG("%s: invalid param: %u", gpu->name, param); return -EINVAL; diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index d8a6b3472760..3fca72f73861 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -87,6 +87,7 @@ struct drm_msm_timespec { #define MSM_PARAM_VA_START 0x0e /* RO: start of valid GPU iova range */ #define MSM_PARAM_VA_SIZE 0x0f /* RO: size of valid GPU iova range (bytes) */ #define MSM_PARAM_HIGHEST_BANK_BIT 0x10 /* RO */ +#define MSM_PARAM_RAYTRACING 0x11 /* RO */ /* For backwards compat. The original support for preemption was based on * a single ring per priority level so # of priority levels equals the # -- cgit v1.2.3 From 467cfe945656df044c8cf9121e5cdbe5b977b497 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Mon, 19 Feb 2024 13:43:55 +0200 Subject: accel/habanalabs/gaudi2: align embedded specs headers Align embedded headers to latest release. Reviewed-by: Tomer Tayar Signed-off-by: Ofir Bitton --- .../accel/habanalabs/include/gaudi2/gaudi2_fw_if.h | 27 ++++++-------------- .../habanalabs/include/gaudi2/gaudi2_reg_map.h | 8 ++++++ include/linux/habanalabs/cpucp_if.h | 10 ++++++-- include/linux/habanalabs/hl_boot_if.h | 29 ++++++++++++++++------ 4 files changed, 45 insertions(+), 29 deletions(-) (limited to 'include') diff --git a/drivers/accel/habanalabs/include/gaudi2/gaudi2_fw_if.h b/drivers/accel/habanalabs/include/gaudi2/gaudi2_fw_if.h index 18ca147b1c86..6ea936c9594e 100644 --- a/drivers/accel/habanalabs/include/gaudi2/gaudi2_fw_if.h +++ b/drivers/accel/habanalabs/include/gaudi2/gaudi2_fw_if.h @@ -45,6 +45,13 @@ #define GAUDI2_ARM_RX_MB_OFFSET (GAUDI2_ARM_RX_MB_ADDR - \ GAUDI2_SP_SRAM_BASE_ADDR) +#define POWER_MODE_LEVELS { \ + 150000, /* 00 */ \ + 250000, /* 01 */ \ + 400000, /* 10 */ \ + /* 11: Normal mode */ \ +} + enum gaudi2_fw_status { GAUDI2_PID_STATUS_UP = 0x1, /* PID on ARC0 is up */ GAUDI2_ARM_STATUS_UP = 0x2, /* ARM Linux Boot complete */ @@ -52,26 +59,6 @@ enum gaudi2_fw_status { GAUDI2_STATUS_LAST = 0xFF }; -struct gaudi2_cold_rst_data { - union { - struct { - u32 recovery_flag: 1; - u32 validation_flag: 1; - u32 efuse_read_flag: 1; - u32 spsram_init_done : 1; - u32 fake_security_enable : 1; - u32 fake_sig_validation_en : 1; - u32 bist_skip_enable : 1; - u32 reserved1 : 1; - u32 fake_bis_compliant : 1; - u32 wd_rst_cause_arm : 1; - u32 wd_rst_cause_arcpid : 1; - u32 reserved : 21; - }; - __le32 data; - }; -}; - enum gaudi2_rst_src { HL_COLD_RST = 1, HL_MANUAL_RST = 2, diff --git a/drivers/accel/habanalabs/include/gaudi2/gaudi2_reg_map.h b/drivers/accel/habanalabs/include/gaudi2/gaudi2_reg_map.h index f3eaeb6d9b7e..1e9c056e437d 100644 --- a/drivers/accel/habanalabs/include/gaudi2/gaudi2_reg_map.h +++ b/drivers/accel/habanalabs/include/gaudi2/gaudi2_reg_map.h @@ -58,4 +58,12 @@ #define mmWD_GPIO_DATAOUT_REG mmPSOC_GPIO3_DATAOUT #define mmSTM_PROFILER_SPE_REG mmPSOC_STM_STMSPER +/* Registers below are used to pass the boot_if data between ARM and ARC1 */ +#define mmARM_MSG_BOOT_ERR_SET mmCPU_IF_SPECIAL_GLBL_SPARE_0 +#define mmARM_MSG_BOOT_ERR_CLR mmCPU_IF_SPECIAL_GLBL_SPARE_1 +#define mmARM_MSG_BOOT_DEV_STS_SET mmCPU_IF_SPECIAL_GLBL_SPARE_2 +#define mmARM_MSG_BOOT_DEV_STS_CLR mmCPU_IF_SPECIAL_GLBL_SPARE_3 +#define mmMGMT_MSG_BOOT_ERR mmCPU_MSTR_IF_SPECIAL_GLBL_SPARE_0 +#define mmMGMT_MSG_BOOT_DEV_STS mmCPU_MSTR_IF_SPECIAL_GLBL_SPARE_1 + #endif /* GAUDI2_REG_MAP_H_ */ diff --git a/include/linux/habanalabs/cpucp_if.h b/include/linux/habanalabs/cpucp_if.h index f316c8d0f3fc..1ac1d68193e3 100644 --- a/include/linux/habanalabs/cpucp_if.h +++ b/include/linux/habanalabs/cpucp_if.h @@ -42,6 +42,12 @@ enum eq_event_id { EQ_EVENT_PWR_BRK_ENTRY, EQ_EVENT_PWR_BRK_EXIT, EQ_EVENT_HEARTBEAT, + EQ_EVENT_CPLD_RESET_REASON, + EQ_EVENT_CPLD_SHUTDOWN, + EQ_EVENT_POWER_EVT_START, + EQ_EVENT_POWER_EVT_END, + EQ_EVENT_THERMAL_EVT_START, + EQ_EVENT_THERMAL_EVT_END, }; /* @@ -1165,7 +1171,7 @@ struct cpucp_security_info { struct cpucp_info { struct cpucp_sensor sensors[CPUCP_MAX_SENSORS]; __u8 kernel_version[VERSION_MAX_LEN]; - __le32 reserved; + __le32 reserved1; __le32 card_type; __le32 card_location; __le32 cpld_version; @@ -1187,7 +1193,7 @@ struct cpucp_info { __u8 substrate_version; __u8 eq_health_check_supported; struct cpucp_security_info sec_info; - __le32 fw_hbm_region_size; + __le32 reserved2; __u8 pll_map[PLL_MAP_LEN]; __le64 mme_binning_mask; __u8 fw_os_version[VERSION_MAX_LEN]; diff --git a/include/linux/habanalabs/hl_boot_if.h b/include/linux/habanalabs/hl_boot_if.h index 93366d5621fd..d2a9fc96424b 100644 --- a/include/linux/habanalabs/hl_boot_if.h +++ b/include/linux/habanalabs/hl_boot_if.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 * - * Copyright 2018-2020 HabanaLabs, Ltd. + * Copyright 2018-2023 HabanaLabs, Ltd. * All Rights Reserved. * */ @@ -49,7 +49,6 @@ enum cpu_boot_err { #define CPU_BOOT_ERR_FATAL_MASK \ ((1 << CPU_BOOT_ERR_DRAM_INIT_FAIL) | \ (1 << CPU_BOOT_ERR_PLL_FAIL) | \ - (1 << CPU_BOOT_ERR_DEVICE_UNUSABLE_FAIL) | \ (1 << CPU_BOOT_ERR_BINNING_FAIL) | \ (1 << CPU_BOOT_ERR_DRAM_SKIPPED) | \ (1 << CPU_BOOT_ERR_ENG_ARC_MEM_SCRUB_FAIL) | \ @@ -194,6 +193,8 @@ enum cpu_boot_dev_sts { CPU_BOOT_DEV_STS_FW_NIC_STAT_EXT_EN = 24, CPU_BOOT_DEV_STS_IS_IDLE_CHECK_EN = 25, CPU_BOOT_DEV_STS_MAP_HWMON_EN = 26, + CPU_BOOT_DEV_STS_NIC_MEM_CLEAR_EN = 27, + CPU_BOOT_DEV_STS_MMU_PGTBL_DRAM_EN = 28, CPU_BOOT_DEV_STS_ENABLED = 31, CPU_BOOT_DEV_STS_SCND_EN = 63, CPU_BOOT_DEV_STS_LAST = 64 /* we have 2 registers of 32 bits */ @@ -331,6 +332,17 @@ enum cpu_boot_dev_sts { * HWMON enum mapping to cpucp enums. * Initialized in: linux * + * CPU_BOOT_DEV_STS0_NIC_MEM_CLEAR_EN + * If set, means f/w supports nic hbm memory clear and + * tmr,txs hbm memory init. + * Initialized in: zephyr-mgmt + * + * CPU_BOOT_DEV_STS_MMU_PGTBL_DRAM_EN + * MMU page tables are located in DRAM. + * F/W initializes security settings for MMU + * page tables to reside in DRAM. + * Initialized in: zephyr-mgmt + * * CPU_BOOT_DEV_STS0_ENABLED Device status register enabled. * This is a main indication that the * running FW populates the device status @@ -367,6 +379,8 @@ enum cpu_boot_dev_sts { #define CPU_BOOT_DEV_STS0_FW_NIC_STAT_EXT_EN (1 << CPU_BOOT_DEV_STS_FW_NIC_STAT_EXT_EN) #define CPU_BOOT_DEV_STS0_IS_IDLE_CHECK_EN (1 << CPU_BOOT_DEV_STS_IS_IDLE_CHECK_EN) #define CPU_BOOT_DEV_STS0_MAP_HWMON_EN (1 << CPU_BOOT_DEV_STS_MAP_HWMON_EN) +#define CPU_BOOT_DEV_STS0_NIC_MEM_CLEAR_EN (1 << CPU_BOOT_DEV_STS_NIC_MEM_CLEAR_EN) +#define CPU_BOOT_DEV_STS0_MMU_PGTBL_DRAM_EN (1 << CPU_BOOT_DEV_STS_MMU_PGTBL_DRAM_EN) #define CPU_BOOT_DEV_STS0_ENABLED (1 << CPU_BOOT_DEV_STS_ENABLED) #define CPU_BOOT_DEV_STS1_ENABLED (1 << CPU_BOOT_DEV_STS_ENABLED) @@ -450,11 +464,11 @@ struct cpu_dyn_regs { __le32 gic_dma_core_irq_ctrl; __le32 gic_host_halt_irq; __le32 gic_host_ints_irq; - __le32 gic_host_soft_rst_irq; + __le32 reserved0; __le32 gic_rot_qm_irq_ctrl; - __le32 cpu_rst_status; + __le32 reserved1; __le32 eng_arc_irq_ctrl; - __le32 reserved1[20]; /* reserve for future use */ + __le32 reserved2[20]; /* reserve for future use */ }; /* TODO: remove the desc magic after the code is updated to use message */ @@ -551,8 +565,9 @@ enum lkd_fw_ascii_msg_lvls { LKD_FW_ASCII_MSG_DBG = 3, }; -#define LKD_FW_ASCII_MSG_MAX_LEN 128 -#define LKD_FW_ASCII_MSG_MAX 4 /* consider ABI when changing */ +#define LKD_FW_ASCII_MSG_MAX_LEN 128 +#define LKD_FW_ASCII_MSG_MAX 4 /* consider ABI when changing */ +#define LKD_FW_ASCII_MSG_MIN_DESC_VERSION 3 struct lkd_fw_ascii_msg { __u8 valid; -- cgit v1.2.3 From c2a27584ff3b7f17da3ed2abfa3956f9d376e3da Mon Sep 17 00:00:00 2001 From: Dani Liberman Date: Mon, 11 Mar 2024 18:31:10 +0200 Subject: accel/habanalabs: separate nonce from max_size in cpucp_packet struct In struct cpucp_packet both nonce and data_max_size members are in an union overlapping each other. This is a problem as they both are used in attestation and info_signed packets. The solution here is to move the nonce member to a different union under the same structure. Signed-off-by: Dani Liberman Reviewed-by: Ofir Bitton Signed-off-by: Ofir Bitton --- include/linux/habanalabs/cpucp_if.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/habanalabs/cpucp_if.h b/include/linux/habanalabs/cpucp_if.h index 1ac1d68193e3..0913415243e8 100644 --- a/include/linux/habanalabs/cpucp_if.h +++ b/include/linux/habanalabs/cpucp_if.h @@ -859,9 +859,6 @@ struct cpucp_packet { * result cannot be used to hold general purpose data. */ __le32 status_mask; - - /* random, used once number, for security packets */ - __le32 nonce; }; union { @@ -870,6 +867,9 @@ struct cpucp_packet { /* For Generic packet sub index */ __le32 pkt_subidx; + + /* random, used once number, for security packets */ + __le32 nonce; }; }; -- cgit v1.2.3 From cebb64f9335b073cc2877fed16c613c56bed82bc Mon Sep 17 00:00:00 2001 From: Vitaly Margolin Date: Mon, 27 May 2024 17:25:37 +0300 Subject: accel/habanalabs: add cpld ts cpld_timestamp cpucp Add cpld_timestamp field to cpucp_info structure and return cpld timestamp as part of cpld version Signed-off-by: Vitaly Margolin Reviewed-by: Ofir Bitton Signed-off-by: Ofir Bitton --- drivers/accel/habanalabs/common/sysfs.c | 5 +++-- include/linux/habanalabs/cpucp_if.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/accel/habanalabs/common/sysfs.c b/drivers/accel/habanalabs/common/sysfs.c index b6c63f8a0c1b..e9f8ccc0bbf9 100644 --- a/drivers/accel/habanalabs/common/sysfs.c +++ b/drivers/accel/habanalabs/common/sysfs.c @@ -142,8 +142,9 @@ static ssize_t cpld_ver_show(struct device *dev, struct device_attribute *attr, { struct hl_device *hdev = dev_get_drvdata(dev); - return sprintf(buf, "0x%08x\n", - le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version)); + return sprintf(buf, "0x%08x%08x\n", + le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_timestamp), + le32_to_cpu(hdev->asic_prop.cpucp_info.cpld_version)); } static ssize_t cpucp_kernel_ver_show(struct device *dev, diff --git a/include/linux/habanalabs/cpucp_if.h b/include/linux/habanalabs/cpucp_if.h index 0913415243e8..1ed17887f1a8 100644 --- a/include/linux/habanalabs/cpucp_if.h +++ b/include/linux/habanalabs/cpucp_if.h @@ -1146,6 +1146,7 @@ struct cpucp_security_info { * (0 = fully functional, 1 = lower-half is not functional, * 2 = upper-half is not functional) * @sec_info: security information + * @cpld_timestamp: CPLD programmed F/W timestamp. * @pll_map: Bit map of supported PLLs for current ASIC version. * @mme_binning_mask: MME binning mask, * bits [0:6] <==> dcore0 mme fma @@ -1193,7 +1194,7 @@ struct cpucp_info { __u8 substrate_version; __u8 eq_health_check_supported; struct cpucp_security_info sec_info; - __le32 reserved2; + __le32 cpld_timestamp; __u8 pll_map[PLL_MAP_LEN]; __le64 mme_binning_mask; __u8 fw_os_version[VERSION_MAX_LEN]; -- cgit v1.2.3 From c4548eee537ed7671170eb370c6c8db12dcfd3e8 Mon Sep 17 00:00:00 2001 From: Tomer Tayar Date: Tue, 16 Apr 2024 19:01:42 +0300 Subject: accel/habanalabs: dump the EQ entries headers on EQ heartbeat failure Add a dump of the EQ entries headers upon a EQ heartbeat failure. Signed-off-by: Tomer Tayar Reviewed-by: Ofir Bitton Signed-off-by: Ofir Bitton --- drivers/accel/habanalabs/common/device.c | 2 ++ drivers/accel/habanalabs/common/habanalabs.h | 1 + drivers/accel/habanalabs/common/irq.c | 25 +++++++++++++++++++++++++ include/linux/habanalabs/cpucp_if.h | 3 +++ 4 files changed, 31 insertions(+) (limited to 'include') diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c index 3efc26dd9497..7bd7c2eb5dd2 100644 --- a/drivers/accel/habanalabs/common/device.c +++ b/drivers/accel/habanalabs/common/device.c @@ -1082,6 +1082,8 @@ static bool hl_device_eq_heartbeat_received(struct hl_device *hdev) atomic_read(&hdev->kernel_queues[cpu_q_id].ci), atomic_read(&hdev->kernel_queues[cpu_q_id].ci) & pq_pi_mask); + hl_eq_dump(hdev, &hdev->event_queue); + return false; } diff --git a/drivers/accel/habanalabs/common/habanalabs.h b/drivers/accel/habanalabs/common/habanalabs.h index f4ac5e9b1974..ce78b331e244 100644 --- a/drivers/accel/habanalabs/common/habanalabs.h +++ b/drivers/accel/habanalabs/common/habanalabs.h @@ -3754,6 +3754,7 @@ int hl_eq_init(struct hl_device *hdev, struct hl_eq *q); void hl_eq_fini(struct hl_device *hdev, struct hl_eq *q); void hl_cq_reset(struct hl_device *hdev, struct hl_cq *q); void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q); +void hl_eq_dump(struct hl_device *hdev, struct hl_eq *q); irqreturn_t hl_irq_handler_cq(int irq, void *arg); irqreturn_t hl_irq_handler_eq(int irq, void *arg); irqreturn_t hl_irq_handler_dec_abnrm(int irq, void *arg); diff --git a/drivers/accel/habanalabs/common/irq.c b/drivers/accel/habanalabs/common/irq.c index 2caf2df4de08..7c9f2f6a2870 100644 --- a/drivers/accel/habanalabs/common/irq.c +++ b/drivers/accel/habanalabs/common/irq.c @@ -697,3 +697,28 @@ void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q) memset(q->kernel_address, 0, q->size); } + +void hl_eq_dump(struct hl_device *hdev, struct hl_eq *q) +{ + u32 eq_length, eqe_size, ctl, ready, mode, type, index; + struct hl_eq_header *hdr; + u8 *ptr; + int i; + + eq_length = HL_EQ_LENGTH; + eqe_size = q->size / HL_EQ_LENGTH; + + dev_info(hdev->dev, "Contents of EQ entries headers:\n"); + + for (i = 0, ptr = q->kernel_address ; i < eq_length ; ++i, ptr += eqe_size) { + hdr = (struct hl_eq_header *) ptr; + ctl = le32_to_cpu(hdr->ctl); + ready = FIELD_GET(EQ_CTL_READY_MASK, ctl); + mode = FIELD_GET(EQ_CTL_EVENT_MODE_MASK, ctl); + type = FIELD_GET(EQ_CTL_EVENT_TYPE_MASK, ctl); + index = FIELD_GET(EQ_CTL_INDEX_MASK, ctl); + + dev_info(hdev->dev, "%02u: %#010x [ready: %u, mode %u, type %04u, index %05u]\n", + i, ctl, ready, mode, type, index); + } +} diff --git a/include/linux/habanalabs/cpucp_if.h b/include/linux/habanalabs/cpucp_if.h index 1ed17887f1a8..7ed3fdd55dda 100644 --- a/include/linux/habanalabs/cpucp_if.h +++ b/include/linux/habanalabs/cpucp_if.h @@ -397,6 +397,9 @@ struct hl_eq_entry { #define EQ_CTL_READY_SHIFT 31 #define EQ_CTL_READY_MASK 0x80000000 +#define EQ_CTL_EVENT_MODE_SHIFT 28 +#define EQ_CTL_EVENT_MODE_MASK 0x70000000 + #define EQ_CTL_EVENT_TYPE_SHIFT 16 #define EQ_CTL_EVENT_TYPE_MASK 0x0FFF0000 -- cgit v1.2.3 From 1c5f18d88eae348cf45f90aaee7b361f593b0701 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 19 Jun 2024 14:31:44 +0300 Subject: drm: Export drm_plane_has_format() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Export drm_plane_has_format() so that drivers can use it. v2: add kerneldoc Reviewed-by: Jani Nikula Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20240619113144.1616-1-ville.syrjala@linux.intel.com Reviewed-by: Daniel Vetter Acked-by: Daniel Stone Acked-by: Thomas Zimmermann --- drivers/gpu/drm/drm_crtc_internal.h | 2 -- drivers/gpu/drm/drm_plane.c | 10 ++++++++++ include/drm/drm_plane.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 898e0e8b51be..e207759ca045 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -272,8 +272,6 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, /* drm_plane.c */ int drm_plane_register_all(struct drm_device *dev); void drm_plane_unregister_all(struct drm_device *dev); -bool drm_plane_has_format(struct drm_plane *plane, - u32 format, u64 modifier); struct drm_mode_rect * __drm_plane_get_damage_clips(const struct drm_plane_state *state); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 268aa2299df5..a28b22fdd7a4 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -877,6 +877,15 @@ int drm_mode_getplane(struct drm_device *dev, void *data, return 0; } +/** + * drm_plane_has_format - Check whether the plane supports this format and modifier combination + * @plane: drm plane + * @format: pixel format (DRM_FORMAT_*) + * @modifier: data layout modifier + * + * Returns: + * Whether the plane supports the specified format and modifier combination. + */ bool drm_plane_has_format(struct drm_plane *plane, u32 format, u64 modifier) { @@ -906,6 +915,7 @@ bool drm_plane_has_format(struct drm_plane *plane, return true; } +EXPORT_SYMBOL(drm_plane_has_format); static int __setplane_check(struct drm_plane *plane, struct drm_crtc *crtc, diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 9507542121fa..dd718c62ac31 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -972,6 +972,8 @@ static inline struct drm_plane *drm_plane_find(struct drm_device *dev, #define drm_for_each_plane(plane, dev) \ list_for_each_entry(plane, &(dev)->mode_config.plane_list, head) +bool drm_plane_has_format(struct drm_plane *plane, + u32 format, u64 modifier); bool drm_any_plane_has_format(struct drm_device *dev, u32 format, u64 modifier); -- cgit v1.2.3 From 12f84e8793af19357e2270b24b9e8d453bb3a1f2 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 22 May 2024 07:33:39 +0200 Subject: drm: Add drm_vblank_work_flush_all(). In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Check that both pending_work and running work are empty when flushing. Co-Developed-by: Chaitanya Kumar Borah Signed-off-by: Maarten Lankhorst Reviewed-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20240522053341.137592-2-maarten.lankhorst@linux.intel.com --- drivers/gpu/drm/drm_vblank_work.c | 22 ++++++++++++++++++++++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 4fe9b1d3b00f..1752ffb44e1d 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(&dev->event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + list_empty(&vblank->pending_work), + dev->event_lock); + spin_unlock_irq(&dev->event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */ -- cgit v1.2.3 From 06ec7893a4b48a1fad9e94cb670862ddd65b6eab Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 24 Jun 2024 20:39:58 +0300 Subject: drm/connector: hdmi: shorten too long function name If CONFIG_MODVERSIONS is enabled, then using the HDMI Connector framework can result in build failures. Rename the function to make it fit into the name requirements. ERROR: modpost: too long symbol "drm_atomic_helper_connector_hdmi_disable_audio_infoframe" [drivers/gpu/drm/msm/msm.ko] Reported-by: Mark Brown Reviewed-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20240624-hdmi-connector-shorten-name-v1-1-5bd3410138db@linaro.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/display/drm_hdmi_state_helper.c | 6 +++--- include/drm/display/drm_hdmi_state_helper.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_hdmi_state_helper.c b/drivers/gpu/drm/display/drm_hdmi_state_helper.c index 2dab3ad8ce64..7854820089ec 100644 --- a/drivers/gpu/drm/display/drm_hdmi_state_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_state_helper.c @@ -716,7 +716,7 @@ drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *co EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); /** - * drm_atomic_helper_connector_hdmi_disable_audio_infoframe - Stop sending the Audio Infoframe + * drm_atomic_helper_connector_hdmi_clear_audio_infoframe - Stop sending the Audio Infoframe * @connector: A pointer to the HDMI connector * * This function is meant for HDMI connector drivers to stop sending their @@ -727,7 +727,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe); * Zero on success, error code on failure. */ int -drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector) +drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector) { struct drm_connector_hdmi_infoframe *infoframe = &connector->hdmi.infoframes.audio; @@ -749,4 +749,4 @@ drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *c return ret; } -EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_disable_audio_infoframe); +EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe); diff --git a/include/drm/display/drm_hdmi_state_helper.h b/include/drm/display/drm_hdmi_state_helper.h index 285f366cf716..2d45fcfa4619 100644 --- a/include/drm/display/drm_hdmi_state_helper.h +++ b/include/drm/display/drm_hdmi_state_helper.h @@ -16,7 +16,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector, struct hdmi_audio_infoframe *frame); -int drm_atomic_helper_connector_hdmi_disable_audio_infoframe(struct drm_connector *connector); +int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector); int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector, struct drm_atomic_state *state); -- cgit v1.2.3 From 3ebc76c424bc0f0768f5c346667e8f51217917ba Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 26 Jun 2024 16:22:08 +0200 Subject: drm/mipi-dsi: add mipi_dsi_usleep_range helper Like for mipi_dsi_msleep(), usleep_range() may often be called in between mipi_dsi_dcs_*() functions and needs a multi compatible counter part. Suggested-by: Dmitry Baryshkov Signed-off-by: Jerome Brunet Link: https://lore.kernel.org/r/20240626142212.1341556-3-jbrunet@baylibre.com Signed-off-by: Neil Armstrong Link: https://patchwork.freedesktop.org/patch/msgid/20240626142212.1341556-3-jbrunet@baylibre.com --- include/drm/drm_mipi_dsi.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 71d121aeef24..0f520eeeaa8e 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h @@ -10,6 +10,7 @@ #define __DRM_MIPI_DSI_H__ #include +#include struct mipi_dsi_host; struct mipi_dsi_device; @@ -297,6 +298,12 @@ ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, msleep(delay); \ } while (0) +#define mipi_dsi_usleep_range(ctx, min, max) \ + do { \ + if (!(ctx)->accum_err) \ + usleep_range(min, max); \ + } while (0) + /** * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking -- cgit v1.2.3 From 7e5161da9d267957b726a29f3efe6cb50fdfed04 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Sun, 23 Jun 2024 13:31:19 -0700 Subject: drm/xe/oa: Fix kernel doc in xe_drm.h Fix kernel doc in xe_drm.h. Also eliminate private/non-abi enum definitions. v2: Remove __DRM_XE_PERF_TYPE_MAX since it is unused (Michal) v3: Also remove DRM_XE_OA_PROPERTY_MAX since it can also be eliminated (Michal) Suggested-by: Michal Wajdeczko Signed-off-by: Ashutosh Dixit Reviewed-by: Michal Wajdeczko Link: https://patchwork.freedesktop.org/patch/msgid/20240623203119.3840283-1-ashutosh.dixit@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/xe_oa.c | 3 ++- include/uapi/drm/xe_drm.h | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 4168b51cf7b5..9263ae9a864e 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -1684,6 +1684,7 @@ static const xe_oa_user_extension_fn xe_oa_user_extension_funcs[] = { [DRM_XE_OA_EXTENSION_SET_PROPERTY] = xe_oa_user_ext_set_property, }; +#define MAX_USER_EXTENSIONS 16 static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number, struct xe_oa_open_param *param) { @@ -1692,7 +1693,7 @@ static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number int err; u32 idx; - if (XE_IOCTL_DBG(oa->xe, ext_number >= DRM_XE_OA_PROPERTY_MAX)) + if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS)) return -E2BIG; err = __copy_from_user(&ext, address, sizeof(ext)); diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 93e00be44b2d..b410553faa9b 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1379,8 +1379,8 @@ struct drm_xe_wait_user_fence { * enum drm_xe_perf_type - Perf stream types */ enum drm_xe_perf_type { + /** @DRM_XE_PERF_TYPE_OA: OA perf stream type */ DRM_XE_PERF_TYPE_OA, - __DRM_XE_PERF_TYPE_MAX, /* non-ABI */ }; /** @@ -1611,9 +1611,6 @@ enum drm_xe_oa_property_id { * pass along with @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID or will default to 0. */ DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE, - - /** @DRM_XE_OA_PROPERTY_MAX: non-ABI */ - DRM_XE_OA_PROPERTY_MAX }; /** -- cgit v1.2.3 From 406d058dc323ae152d380ac90153eb56a75850c1 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Wed, 26 Jun 2024 11:18:17 -0700 Subject: drm/xe/oa/uapi: Allow preemption to be disabled on the stream exec queue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mesa VK_KHR_performance_query use case requires preemption and timeslicing to be disabled for the stream exec queue. Implement this functionality here. v2: Minor change to debug print to print both ret values (Umesh) Acked-by: José Roberto de Souza Reviewed-by: Umesh Nerlige Ramappa Signed-off-by: Ashutosh Dixit Link: https://patchwork.freedesktop.org/patch/msgid/20240626181817.1516229-3-ashutosh.dixit@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/xe_oa.c | 70 +++++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/xe/xe_oa_types.h | 3 ++ include/uapi/drm/xe_drm.h | 6 ++++ 3 files changed, 78 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index a68659fd5386..6cc3f0217341 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -80,6 +80,7 @@ struct xe_oa_open_param { int engine_instance; struct xe_exec_queue *exec_q; struct xe_hw_engine *hwe; + bool no_preempt; }; struct xe_oa_config_bo { @@ -1013,11 +1014,55 @@ static void xe_oa_stream_disable(struct xe_oa_stream *stream) hrtimer_cancel(&stream->poll_check_timer); } +static int xe_oa_enable_preempt_timeslice(struct xe_oa_stream *stream) +{ + struct xe_exec_queue *q = stream->exec_q; + int ret1, ret2; + + /* Best effort recovery: try to revert both to original, irrespective of error */ + ret1 = q->ops->set_timeslice(q, stream->hwe->eclass->sched_props.timeslice_us); + ret2 = q->ops->set_preempt_timeout(q, stream->hwe->eclass->sched_props.preempt_timeout_us); + if (ret1 || ret2) + goto err; + return 0; +err: + drm_dbg(&stream->oa->xe->drm, "%s failed ret1 %d ret2 %d\n", __func__, ret1, ret2); + return ret1 ?: ret2; +} + +static int xe_oa_disable_preempt_timeslice(struct xe_oa_stream *stream) +{ + struct xe_exec_queue *q = stream->exec_q; + int ret; + + /* Setting values to 0 will disable timeslice and preempt_timeout */ + ret = q->ops->set_timeslice(q, 0); + if (ret) + goto err; + + ret = q->ops->set_preempt_timeout(q, 0); + if (ret) + goto err; + + return 0; +err: + xe_oa_enable_preempt_timeslice(stream); + drm_dbg(&stream->oa->xe->drm, "%s failed %d\n", __func__, ret); + return ret; +} + static int xe_oa_enable_locked(struct xe_oa_stream *stream) { if (stream->enabled) return 0; + if (stream->no_preempt) { + int ret = xe_oa_disable_preempt_timeslice(stream); + + if (ret) + return ret; + } + xe_oa_stream_enable(stream); stream->enabled = true; @@ -1026,13 +1071,18 @@ static int xe_oa_enable_locked(struct xe_oa_stream *stream) static int xe_oa_disable_locked(struct xe_oa_stream *stream) { + int ret = 0; + if (!stream->enabled) return 0; xe_oa_stream_disable(stream); + if (stream->no_preempt) + ret = xe_oa_enable_preempt_timeslice(stream); + stream->enabled = false; - return 0; + return ret; } static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg) @@ -1307,6 +1357,7 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream, stream->sample = param->sample; stream->periodic = param->period_exponent > 0; stream->period_exponent = param->period_exponent; + stream->no_preempt = param->no_preempt; /* * For Xe2+, when overrun mode is enabled, there are no partial reports at the end @@ -1651,6 +1702,13 @@ static int xe_oa_set_prop_engine_instance(struct xe_oa *oa, u64 value, return 0; } +static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value, + struct xe_oa_open_param *param) +{ + param->no_preempt = value; + return 0; +} + typedef int (*xe_oa_set_property_fn)(struct xe_oa *oa, u64 value, struct xe_oa_open_param *param); static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = { @@ -1662,6 +1720,7 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = { [DRM_XE_OA_PROPERTY_OA_DISABLED] = xe_oa_set_prop_disabled, [DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID] = xe_oa_set_prop_exec_queue_id, [DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE] = xe_oa_set_prop_engine_instance, + [DRM_XE_OA_PROPERTY_NO_PREEMPT] = xe_oa_set_no_preempt, }; static int xe_oa_user_ext_set_property(struct xe_oa *oa, u64 extension, @@ -1766,6 +1825,15 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f if (param.exec_q && !param.sample) privileged_op = false; + if (param.no_preempt) { + if (!param.exec_q) { + drm_dbg(&oa->xe->drm, "Preemption disable without exec_q!\n"); + ret = -EINVAL; + goto err_exec_q; + } + privileged_op = true; + } + if (privileged_op && xe_perf_stream_paranoid && !perfmon_capable()) { drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe perf stream\n"); ret = -EACCES; diff --git a/drivers/gpu/drm/xe/xe_oa_types.h b/drivers/gpu/drm/xe/xe_oa_types.h index 706d45577dae..540c3ec53a6d 100644 --- a/drivers/gpu/drm/xe/xe_oa_types.h +++ b/drivers/gpu/drm/xe/xe_oa_types.h @@ -235,5 +235,8 @@ struct xe_oa_stream { /** @oa_status: temporary storage for oa_status register value */ u32 oa_status; + + /** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */ + u32 no_preempt; }; #endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index b410553faa9b..12eaa8532b5c 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -1611,6 +1611,12 @@ enum drm_xe_oa_property_id { * pass along with @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID or will default to 0. */ DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE, + + /** + * @DRM_XE_OA_PROPERTY_NO_PREEMPT: Allow preemption and timeslicing + * to be disabled for the stream exec queue. + */ + DRM_XE_OA_PROPERTY_NO_PREEMPT, }; /** -- cgit v1.2.3 From 6d4618ad04e1a14202410648f638b62d3f666d45 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 19 Jun 2024 20:21:47 +0200 Subject: drm/bridge: analogix_dp: remove unused platform power_on_end callback This isn't used, but gives the impression of the power on and power off platform calls being non-symmetrical. Remove the unused callback and rename the power_on_start to simply power_on. Signed-off-by: Lucas Stach Reviewed-by: Robert Foss Tested-by: Heiko Stuebner Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20240619182200.3752465-1-l.stach@pengutronix.de --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 7 ++----- drivers/gpu/drm/exynos/exynos_dp.c | 2 +- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 4 ++-- include/drm/bridge/analogix_dp.h | 3 +-- 4 files changed, 6 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index b5dbff21c187..31fa67d966c7 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1257,8 +1257,8 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) goto out_dp_clk_pre; } - if (dp->plat_data->power_on_start) - dp->plat_data->power_on_start(dp->plat_data); + if (dp->plat_data->power_on) + dp->plat_data->power_on(dp->plat_data); phy_power_on(dp->phy); @@ -1283,9 +1283,6 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) goto out_dp_init; } - if (dp->plat_data->power_on_end) - dp->plat_data->power_on_end(dp->plat_data); - enable_irq(dp->irq); return 0; diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index f48c4343f469..30c8750187ad 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -233,7 +233,7 @@ static int exynos_dp_probe(struct platform_device *pdev) /* The remote port can be either a panel or a bridge */ dp->plat_data.panel = panel; dp->plat_data.dev_type = EXYNOS_DP; - dp->plat_data.power_on_start = exynos_dp_poweron; + dp->plat_data.power_on = exynos_dp_poweron; dp->plat_data.power_off = exynos_dp_poweroff; dp->plat_data.attach = exynos_dp_bridge_attach; dp->plat_data.get_modes = exynos_dp_get_modes; diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 7069a3d4d581..baeb41875a4b 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -92,7 +92,7 @@ static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) return 0; } -static int rockchip_dp_poweron_start(struct analogix_dp_plat_data *plat_data) +static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) { struct rockchip_dp_device *dp = pdata_encoder_to_dp(plat_data); int ret; @@ -397,7 +397,7 @@ static int rockchip_dp_probe(struct platform_device *pdev) dp->data = dp_data; dp->plat_data.panel = panel; dp->plat_data.dev_type = dp->data->chip_type; - dp->plat_data.power_on_start = rockchip_dp_poweron_start; + dp->plat_data.power_on = rockchip_dp_poweron; dp->plat_data.power_off = rockchip_dp_powerdown; dp->plat_data.get_modes = rockchip_dp_get_modes; diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index b0dcc07334a1..8709b6a74c0f 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -29,8 +29,7 @@ struct analogix_dp_plat_data { struct drm_connector *connector; bool skip_connector; - int (*power_on_start)(struct analogix_dp_plat_data *); - int (*power_on_end)(struct analogix_dp_plat_data *); + int (*power_on)(struct analogix_dp_plat_data *); int (*power_off)(struct analogix_dp_plat_data *); int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *, struct drm_connector *); -- cgit v1.2.3 From e7514df007e3b034b65367a32ba19dc61aaa3980 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 19 Jun 2024 20:21:51 +0200 Subject: drm/bridge: analogix_dp: remove unused analogix_dp_remove Now that the clock is handled dynamically through analogix_dp_resume/suspend and it isn't statically enabled in the driver probe routine, there is no need for the remove function anymore. Signed-off-by: Lucas Stach Reviewed-by: Robert Foss Tested-by: Heiko Stuebner Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20240619182200.3752465-5-l.stach@pengutronix.de --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 ----- drivers/gpu/drm/exynos/exynos_dp.c | 3 --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 +-------- include/drm/bridge/analogix_dp.h | 1 - 4 files changed, 1 insertion(+), 17 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 4453d1672686..7a5e25b6aa3a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1805,11 +1805,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp) } EXPORT_SYMBOL_GPL(analogix_dp_unbind); -void analogix_dp_remove(struct analogix_dp_device *dp) -{ -} -EXPORT_SYMBOL_GPL(analogix_dp_remove); - int analogix_dp_start_crc(struct drm_connector *connector) { struct analogix_dp_device *dp = to_dp(connector); diff --git a/drivers/gpu/drm/exynos/exynos_dp.c b/drivers/gpu/drm/exynos/exynos_dp.c index 30c8750187ad..097f8c4617de 100644 --- a/drivers/gpu/drm/exynos/exynos_dp.c +++ b/drivers/gpu/drm/exynos/exynos_dp.c @@ -251,10 +251,7 @@ out: static void exynos_dp_remove(struct platform_device *pdev) { - struct exynos_dp_device *dp = platform_get_drvdata(pdev); - component_del(&pdev->dev, &exynos_dp_ops); - analogix_dp_remove(dp->adp); } static int exynos_dp_suspend(struct device *dev) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 8214265f1497..362c7951ca4a 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -414,21 +414,14 @@ static int rockchip_dp_probe(struct platform_device *pdev) ret = component_add(dev, &rockchip_dp_component_ops); if (ret) - goto err_dp_remove; + return ret; return 0; - -err_dp_remove: - analogix_dp_remove(dp->adp); - return ret; } static void rockchip_dp_remove(struct platform_device *pdev) { - struct rockchip_dp_device *dp = platform_get_drvdata(pdev); - component_del(&pdev->dev, &rockchip_dp_component_ops); - analogix_dp_remove(dp->adp); } static int rockchip_dp_suspend(struct device *dev) diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h index 8709b6a74c0f..6002c5666031 100644 --- a/include/drm/bridge/analogix_dp.h +++ b/include/drm/bridge/analogix_dp.h @@ -44,7 +44,6 @@ struct analogix_dp_device * analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data); int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev); void analogix_dp_unbind(struct analogix_dp_device *dp); -void analogix_dp_remove(struct analogix_dp_device *dp); int analogix_dp_start_crc(struct drm_connector *connector); int analogix_dp_stop_crc(struct drm_connector *connector); -- cgit v1.2.3 From 8d9ffd15ff5c9da7bc6171f2536aaaff40bcab6e Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 1 Jun 2024 14:56:16 -0400 Subject: drm/amdgpu: remove AMD_FMT_MOD_GFX12_DCC_MAX_COMPRESSED_BLOCK_* definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They were added accidentally. Signed-off-by: Marek Olšák Acked-by: Alex Deucher Reviewed-by: Aurabindo Pillai Signed-off-by: Alex Deucher --- include/uapi/drm/drm_fourcc.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index d0063ac6e09f..4168445fbb8b 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1540,9 +1540,6 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18 #define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 -#define AMD_FMT_MOD_GFX12_DCC_MAX_COMPRESSED_BLOCK_SHIFT 3 -#define AMD_FMT_MOD_GFX12_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 /* 0:64B, 1:128B, 2:256B */ - /* * DCC supports embedding some clear colors directly in the DCC surface. * However, on older GPUs the rendering HW ignores the embedded clear color -- cgit v1.2.3 From 8dd1426e2c80e32ac1995007330c8f95ffa28ebb Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 1 Jun 2024 19:53:01 -0400 Subject: drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It verified GFX9-11 swizzle modes on GFX12, which has undefined behavior. Signed-off-by: Marek Olšák Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 27 ++++++++++++++++++++++++++- include/uapi/drm/drm_fourcc.h | 2 ++ 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index b69a4e1b864b..3bb4ca9b8a40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -1082,6 +1082,30 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) block_width = 256 / format_info->cpp[i]; block_height = 1; block_size_log2 = 8; + } else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) { + int swizzle = AMD_FMT_MOD_GET(TILE, modifier); + + switch (swizzle) { + case AMD_FMT_MOD_TILE_GFX12_256B_2D: + block_size_log2 = 8; + break; + case AMD_FMT_MOD_TILE_GFX12_4K_2D: + block_size_log2 = 12; + break; + case AMD_FMT_MOD_TILE_GFX12_64K_2D: + block_size_log2 = 16; + break; + case AMD_FMT_MOD_TILE_GFX12_256K_2D: + block_size_log2 = 18; + break; + default: + drm_dbg_kms(rfb->base.dev, + "Gfx12 swizzle mode with unknown block size: %d\n", swizzle); + return -EINVAL; + } + + get_block_dimensions(block_size_log2, format_info->cpp[i], + &block_width, &block_height); } else { int swizzle = AMD_FMT_MOD_GET(TILE, modifier); @@ -1117,7 +1141,8 @@ static int amdgpu_display_verify_sizes(struct amdgpu_framebuffer *rfb) return ret; } - if (AMD_FMT_MOD_GET(DCC, modifier)) { + if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 && + AMD_FMT_MOD_GET(DCC, modifier)) { if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) { block_size_log2 = get_dcc_block_size(modifier, false, false); get_block_dimensions(block_size_log2 + 8, format_info->cpp[0], diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 4168445fbb8b..2d84a8052b15 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1506,6 +1506,8 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) * 6 - 64KB_3D * 7 - 256KB_3D */ +#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1 +#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2 #define AMD_FMT_MOD_TILE_GFX12_64K_2D 3 #define AMD_FMT_MOD_TILE_GFX12_256K_2D 4 -- cgit v1.2.3 From 58cd0cba82976a5a21bdfc78783952b147837a84 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 28 Jun 2024 19:44:42 +0300 Subject: drm: Add helpers for q4 fixed point values Add helpers to convert between q4 fixed point and integer/fraction values. Also add the format/argument macros required to printk q4 fixed point variables. The q4 notation is based on the short variant described by https://en.wikipedia.org/wiki/Q_(number_format) where only the number of fraction bits in the fixed point value are defined, while the full size is deducted from the container type, that is the size of int for these helpers. Using the fxp_ prefix, which makes moving these helpers outside of drm to a more generic place easier, if they prove to be useful. These are needed by later patches dumping the Display Stream Compression configuration in DRM core and in the i915 driver to replace the corresponding bpp_x16 helpers defined locally in the driver. v2: Use the more generic/descriptive fxp_q4 prefix instead of drm_x16. (Jani) Cc: Jani Nikula Acked-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240628164451.1177612-2-imre.deak@intel.com --- drivers/gpu/drm/display/drm_dp_helper.c | 5 +++-- include/drm/drm_fixed.h | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 79a615667aab..d4c34f364140 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -4151,9 +4152,9 @@ int drm_dp_bw_overhead(int lane_count, int hactive, int symbol_cycles; if (lane_count == 0 || hactive == 0 || bpp_x16 == 0) { - DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 %d.%04d\n", + DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 " FXP_Q4_FMT "\n", lane_count, hactive, - bpp_x16 >> 4, (bpp_x16 & 0xf) * 625); + FXP_Q4_ARGS(bpp_x16)); return 0; } diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h index 81572d32db0c..ef8bc8d72039 100644 --- a/include/drm/drm_fixed.h +++ b/include/drm/drm_fixed.h @@ -214,4 +214,27 @@ static inline s64 drm_fixp_exp(s64 x) return sum; } +static inline int fxp_q4_from_int(int val_int) +{ + return val_int << 4; +} + +static inline int fxp_q4_to_int(int val_q4) +{ + return val_q4 >> 4; +} + +static inline int fxp_q4_to_int_roundup(int val_q4) +{ + return (val_q4 + 0xf) >> 4; +} + +static inline int fxp_q4_to_frac(int val_q4) +{ + return val_q4 & 0xf; +} + +#define FXP_Q4_FMT "%d.%04d" +#define FXP_Q4_ARGS(val_q4) fxp_q4_to_int(val_q4), (fxp_q4_to_frac(val_q4) * 625) + #endif -- cgit v1.2.3 From 74c3f5da233637bdf828e1ce67a5c1083630a47b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 28 Jun 2024 19:44:43 +0300 Subject: drm/display/dsc: Add a helper to dump the DSC configuration Add a helper to dump the Display Stream Compression configuration, taken into use in the i915 driver by a later patch. v2: - Rebase on the s/DRM_X16/FXP_Q4 change. - s/DSC configration/DSC configuration in the function documentation. Acked-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20240628164451.1177612-3-imre.deak@intel.com --- drivers/gpu/drm/display/drm_dsc_helper.c | 91 ++++++++++++++++++++++++++++++++ include/drm/display/drm_dsc_helper.h | 3 ++ 2 files changed, 94 insertions(+) (limited to 'include') diff --git a/drivers/gpu/drm/display/drm_dsc_helper.c b/drivers/gpu/drm/display/drm_dsc_helper.c index 4424380c6cb6..6900f4dac520 100644 --- a/drivers/gpu/drm/display/drm_dsc_helper.c +++ b/drivers/gpu/drm/display/drm_dsc_helper.c @@ -14,6 +14,7 @@ #include #include +#include #include /** @@ -1472,3 +1473,93 @@ u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc) return 2 << (dsc->bits_per_component - 8); } EXPORT_SYMBOL(drm_dsc_flatness_det_thresh); + +static void drm_dsc_dump_config_main_params(struct drm_printer *p, int indent, + const struct drm_dsc_config *cfg) +{ + drm_printf_indent(p, indent, + "dsc-cfg: version: %d.%d, picture: w=%d, h=%d, slice: count=%d, w=%d, h=%d, size=%d\n", + cfg->dsc_version_major, cfg->dsc_version_minor, + cfg->pic_width, cfg->pic_height, + cfg->slice_count, cfg->slice_width, cfg->slice_height, cfg->slice_chunk_size); + drm_printf_indent(p, indent, + "dsc-cfg: mode: block-pred=%s, vbr=%s, rgb=%s, simple-422=%s, native-422=%s, native-420=%s\n", + str_yes_no(cfg->block_pred_enable), str_yes_no(cfg->vbr_enable), + str_yes_no(cfg->convert_rgb), + str_yes_no(cfg->simple_422), str_yes_no(cfg->native_422), str_yes_no(cfg->native_420)); + drm_printf_indent(p, indent, + "dsc-cfg: color-depth: uncompressed-bpc=%d, compressed-bpp=" FXP_Q4_FMT " line-buf-bpp=%d\n", + cfg->bits_per_component, FXP_Q4_ARGS(cfg->bits_per_pixel), cfg->line_buf_depth); + drm_printf_indent(p, indent, + "dsc-cfg: rc-model: size=%d, bits=%d, mux-word-size: %d, initial-delays: xmit=%d, dec=%d\n", + cfg->rc_model_size, cfg->rc_bits, cfg->mux_word_size, + cfg->initial_xmit_delay, cfg->initial_dec_delay); + drm_printf_indent(p, indent, + "dsc-cfg: offsets: initial=%d, final=%d, slice-bpg=%d\n", + cfg->initial_offset, cfg->final_offset, cfg->slice_bpg_offset); + drm_printf_indent(p, indent, + "dsc-cfg: line-bpg-offsets: first=%d, non-first=%d, second=%d, non-second=%d, second-adj=%d\n", + cfg->first_line_bpg_offset, cfg->nfl_bpg_offset, + cfg->second_line_bpg_offset, cfg->nsl_bpg_offset, cfg->second_line_offset_adj); + drm_printf_indent(p, indent, + "dsc-cfg: rc-tgt-offsets: low=%d, high=%d, rc-edge-factor: %d, rc-quant-incr-limits: [0]=%d, [1]=%d\n", + cfg->rc_tgt_offset_low, cfg->rc_tgt_offset_high, + cfg->rc_edge_factor, cfg->rc_quant_incr_limit0, cfg->rc_quant_incr_limit1); + drm_printf_indent(p, indent, + "dsc-cfg: initial-scale: %d, scale-intervals: increment=%d, decrement=%d\n", + cfg->initial_scale_value, cfg->scale_increment_interval, cfg->scale_decrement_interval); + drm_printf_indent(p, indent, + "dsc-cfg: flatness: min-qp=%d, max-qp=%d\n", + cfg->flatness_min_qp, cfg->flatness_max_qp); +} + +static void drm_dsc_dump_config_rc_params(struct drm_printer *p, int indent, + const struct drm_dsc_config *cfg) +{ + const u16 *bt = cfg->rc_buf_thresh; + const struct drm_dsc_rc_range_parameters *rp = cfg->rc_range_params; + + BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_buf_thresh) != 14); + BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_range_params) != 15); + + drm_printf_indent(p, indent, + "dsc-cfg: rc-level: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14\n"); + drm_printf_indent(p, indent, + "dsc-cfg: rc-buf-thresh: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", + bt[0], bt[1], bt[2], bt[3], bt[4], bt[5], bt[6], bt[7], + bt[8], bt[9], bt[10], bt[11], bt[12], bt[13]); + drm_printf_indent(p, indent, + "dsc-cfg: rc-min-qp: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", + rp[0].range_min_qp, rp[1].range_min_qp, rp[2].range_min_qp, rp[3].range_min_qp, + rp[4].range_min_qp, rp[5].range_min_qp, rp[6].range_min_qp, rp[7].range_min_qp, + rp[8].range_min_qp, rp[9].range_min_qp, rp[10].range_min_qp, rp[11].range_min_qp, + rp[12].range_min_qp, rp[13].range_min_qp, rp[14].range_min_qp); + drm_printf_indent(p, indent, + "dsc-cfg: rc-max-qp: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", + rp[0].range_max_qp, rp[1].range_max_qp, rp[2].range_max_qp, rp[3].range_max_qp, + rp[4].range_max_qp, rp[5].range_max_qp, rp[6].range_max_qp, rp[7].range_max_qp, + rp[8].range_max_qp, rp[9].range_max_qp, rp[10].range_max_qp, rp[11].range_max_qp, + rp[12].range_max_qp, rp[13].range_max_qp, rp[14].range_max_qp); + drm_printf_indent(p, indent, + "dsc-cfg: rc-bpg-offset: %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n", + rp[0].range_bpg_offset, rp[1].range_bpg_offset, rp[2].range_bpg_offset, rp[3].range_bpg_offset, + rp[4].range_bpg_offset, rp[5].range_bpg_offset, rp[6].range_bpg_offset, rp[7].range_bpg_offset, + rp[8].range_bpg_offset, rp[9].range_bpg_offset, rp[10].range_bpg_offset, rp[11].range_bpg_offset, + rp[12].range_bpg_offset, rp[13].range_bpg_offset, rp[14].range_bpg_offset); +} + +/** + * drm_dsc_dump_config - Dump the provided DSC configuration + * @p: The printer used for output + * @indent: Tab indentation level (max 5) + * @cfg: DSC configuration to print + * + * Print the provided DSC configuration in @cfg. + */ +void drm_dsc_dump_config(struct drm_printer *p, int indent, + const struct drm_dsc_config *cfg) +{ + drm_dsc_dump_config_main_params(p, indent, cfg); + drm_dsc_dump_config_rc_params(p, indent, cfg); +} +EXPORT_SYMBOL(drm_dsc_dump_config); diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index 913aa2071232..2c2b9033f60f 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -17,6 +17,8 @@ enum drm_dsc_params_type { DRM_DSC_1_2_420, }; +struct drm_printer; + void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header); int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size); void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_sdp, @@ -28,6 +30,7 @@ int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc); u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc); u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg); +void drm_dsc_dump_config(struct drm_printer *p, int indent, const struct drm_dsc_config *cfg); #endif /* _DRM_DSC_HELPER_H_ */ -- cgit v1.2.3 From 63347fe031e3bd738a2a16aee8eba889376e49a8 Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Wed, 3 Jul 2024 09:48:01 -0700 Subject: drm/xe/uapi: Rename xe perf layer as xe observation layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Xe, the perf layer allows capture of HW counter streams. These HW counters are generally performance related but don't have to be necessarily so. Also, the name "perf" is a carryover from i915 and is not preferred. Here we propose the name "observation" for this common layer which allows capture of different types of these counter streams. v2: Rename observability layer to observation layer (Lucas/Rodrigo) v3: Rename sysctl file to "observation_paranoid" (Jose) Fixes: 52c2e956dceb ("drm/xe/perf/uapi: "Perf" layer to support multiple perf counter stream types") Fixes: fe8929bdf835 ("drm/xe/perf/uapi: Add perf_stream_paranoid sysctl") Acked-by: Lucas De Marchi Acked-by: Rodrigo Vivi Signed-off-by: Ashutosh Dixit Reviewed-by: Umesh Nerlige Ramappa Acked-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20240703164801.2561423-1-ashutosh.dixit@intel.com (cherry picked from commit 8169b2097d88d99d7e4a72e20e4b549efe9eb8d7) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/Makefile | 2 +- drivers/gpu/drm/xe/xe_device.c | 4 +- drivers/gpu/drm/xe/xe_device_types.h | 2 +- drivers/gpu/drm/xe/xe_gt_types.h | 2 +- drivers/gpu/drm/xe/xe_module.c | 6 +-- drivers/gpu/drm/xe/xe_oa.c | 34 ++++++------ drivers/gpu/drm/xe/xe_observation.c | 93 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_observation.h | 20 +++++++ drivers/gpu/drm/xe/xe_perf.c | 92 ------------------------------- drivers/gpu/drm/xe/xe_perf.h | 20 ------- include/uapi/drm/xe_drm.h | 102 ++++++++++++++++++----------------- 11 files changed, 190 insertions(+), 187 deletions(-) create mode 100644 drivers/gpu/drm/xe/xe_observation.c create mode 100644 drivers/gpu/drm/xe/xe_observation.h delete mode 100644 drivers/gpu/drm/xe/xe_perf.c delete mode 100644 drivers/gpu/drm/xe/xe_perf.h (limited to 'include') diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index b1e03bfe4a68..628c245c4822 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -96,10 +96,10 @@ xe-y += xe_bb.o \ xe_mocs.o \ xe_module.o \ xe_oa.o \ + xe_observation.o \ xe_pat.o \ xe_pci.o \ xe_pcode.o \ - xe_perf.o \ xe_pm.o \ xe_preempt_fence.o \ xe_pt.o \ diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index cfda7cb5df2c..03492fbcb8fb 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -42,9 +42,9 @@ #include "xe_memirq.h" #include "xe_mmio.h" #include "xe_module.h" +#include "xe_observation.h" #include "xe_pat.h" #include "xe_pcode.h" -#include "xe_perf.h" #include "xe_pm.h" #include "xe_query.h" #include "xe_sriov.h" @@ -142,7 +142,7 @@ static const struct drm_ioctl_desc xe_ioctls[] = { DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(XE_WAIT_USER_FENCE, xe_wait_user_fence_ioctl, DRM_RENDER_ALLOW), - DRM_IOCTL_DEF_DRV(XE_PERF, xe_perf_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW), }; static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index c37be471d11c..3bca6d344744 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -463,7 +463,7 @@ struct xe_device { /** @heci_gsc: graphics security controller */ struct xe_heci_gsc heci_gsc; - /** @oa: oa perf counter subsystem */ + /** @oa: oa observation subsystem */ struct xe_oa oa; /** @needs_flr_on_fini: requests function-reset on fini */ diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index 24bb95de920f..6b5e0b45efb0 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -389,7 +389,7 @@ struct xe_gt { u8 instances_per_class[XE_ENGINE_CLASS_MAX]; } user_engines; - /** @oa: oa perf counter subsystem per gt info */ + /** @oa: oa observation subsystem per gt info */ struct xe_oa_gt oa; }; diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c index 893858a2eea0..499540add465 100644 --- a/drivers/gpu/drm/xe/xe_module.c +++ b/drivers/gpu/drm/xe/xe_module.c @@ -11,7 +11,7 @@ #include "xe_drv.h" #include "xe_hw_fence.h" #include "xe_pci.h" -#include "xe_perf.h" +#include "xe_observation.h" #include "xe_sched_job.h" struct xe_modparam xe_modparam = { @@ -80,8 +80,8 @@ static const struct init_funcs init_funcs[] = { .exit = xe_unregister_pci_driver, }, { - .init = xe_perf_sysctl_register, - .exit = xe_perf_sysctl_unregister, + .init = xe_observation_sysctl_register, + .exit = xe_observation_sysctl_unregister, }, }; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index 4188516a7816..6d69f751bf78 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -32,7 +32,7 @@ #include "xe_macros.h" #include "xe_mmio.h" #include "xe_oa.h" -#include "xe_perf.h" +#include "xe_observation.h" #include "xe_pm.h" #include "xe_sched_job.h" #include "xe_sriov.h" @@ -481,7 +481,7 @@ static int __xe_oa_read(struct xe_oa_stream *stream, char __user *buf, OASTATUS_RELEVANT_BITS, 0); /* * Signal to userspace that there is non-zero OA status to read via - * @DRM_XE_PERF_IOCTL_STATUS perf fd ioctl + * @DRM_XE_OBSERVATION_IOCTL_STATUS observation stream fd ioctl */ if (stream->oa_status & OASTATUS_RELEVANT_BITS) return -EIO; @@ -1158,15 +1158,15 @@ static long xe_oa_ioctl_locked(struct xe_oa_stream *stream, unsigned long arg) { switch (cmd) { - case DRM_XE_PERF_IOCTL_ENABLE: + case DRM_XE_OBSERVATION_IOCTL_ENABLE: return xe_oa_enable_locked(stream); - case DRM_XE_PERF_IOCTL_DISABLE: + case DRM_XE_OBSERVATION_IOCTL_DISABLE: return xe_oa_disable_locked(stream); - case DRM_XE_PERF_IOCTL_CONFIG: + case DRM_XE_OBSERVATION_IOCTL_CONFIG: return xe_oa_config_locked(stream, arg); - case DRM_XE_PERF_IOCTL_STATUS: + case DRM_XE_OBSERVATION_IOCTL_STATUS: return xe_oa_status_locked(stream, arg); - case DRM_XE_PERF_IOCTL_INFO: + case DRM_XE_OBSERVATION_IOCTL_INFO: return xe_oa_info_locked(stream, arg); } @@ -1209,7 +1209,7 @@ static int xe_oa_release(struct inode *inode, struct file *file) xe_oa_destroy_locked(stream); mutex_unlock(>->oa.gt_lock); - /* Release the reference the perf stream kept on the driver */ + /* Release the reference the OA stream kept on the driver */ drm_dev_put(>_to_xe(gt)->drm); return 0; @@ -1222,7 +1222,7 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma) unsigned long start = vma->vm_start; int i, ret; - if (xe_perf_stream_paranoid && !perfmon_capable()) { + if (xe_observation_paranoid && !perfmon_capable()) { drm_dbg(&stream->oa->xe->drm, "Insufficient privilege to map OA buffer\n"); return -EACCES; } @@ -1789,8 +1789,8 @@ static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number * @file: @drm_file * * The functions opens an OA stream. An OA stream, opened with specified - * properties, enables perf counter samples to be collected, either - * periodically (time based sampling), or on request (using perf queries) + * properties, enables OA counter samples to be collected, either + * periodically (time based sampling), or on request (using OA queries) */ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *file) { @@ -1836,8 +1836,8 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f privileged_op = true; } - if (privileged_op && xe_perf_stream_paranoid && !perfmon_capable()) { - drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe perf stream\n"); + if (privileged_op && xe_observation_paranoid && !perfmon_capable()) { + drm_dbg(&oa->xe->drm, "Insufficient privileges to open xe OA stream\n"); ret = -EACCES; goto err_exec_q; } @@ -2097,7 +2097,7 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi return -ENODEV; } - if (xe_perf_stream_paranoid && !perfmon_capable()) { + if (xe_observation_paranoid && !perfmon_capable()) { drm_dbg(&oa->xe->drm, "Insufficient privileges to add xe OA config\n"); return -EACCES; } @@ -2181,7 +2181,7 @@ reg_err: /** * xe_oa_remove_config_ioctl - Removes one OA config * @dev: @drm_device - * @data: pointer to struct @drm_xe_perf_param + * @data: pointer to struct @drm_xe_observation_param * @file: @drm_file */ int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *file) @@ -2197,7 +2197,7 @@ int xe_oa_remove_config_ioctl(struct drm_device *dev, u64 data, struct drm_file return -ENODEV; } - if (xe_perf_stream_paranoid && !perfmon_capable()) { + if (xe_observation_paranoid && !perfmon_capable()) { drm_dbg(&oa->xe->drm, "Insufficient privileges to remove xe OA config\n"); return -EACCES; } @@ -2381,7 +2381,7 @@ static int xe_oa_init_gt(struct xe_gt *gt) /* * Fused off engines can result in oa_unit's with num_engines == 0. These units - * will appear in OA unit query, but no perf streams can be opened on them. + * will appear in OA unit query, but no OA streams can be opened on them. */ gt->oa.num_oa_units = num_oa_units; gt->oa.oa_unit = u; diff --git a/drivers/gpu/drm/xe/xe_observation.c b/drivers/gpu/drm/xe/xe_observation.c new file mode 100644 index 000000000000..fcb584b42a7d --- /dev/null +++ b/drivers/gpu/drm/xe/xe_observation.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#include +#include + +#include + +#include "xe_oa.h" +#include "xe_observation.h" + +u32 xe_observation_paranoid = true; +static struct ctl_table_header *sysctl_header; + +static int xe_oa_ioctl(struct drm_device *dev, struct drm_xe_observation_param *arg, + struct drm_file *file) +{ + switch (arg->observation_op) { + case DRM_XE_OBSERVATION_OP_STREAM_OPEN: + return xe_oa_stream_open_ioctl(dev, arg->param, file); + case DRM_XE_OBSERVATION_OP_ADD_CONFIG: + return xe_oa_add_config_ioctl(dev, arg->param, file); + case DRM_XE_OBSERVATION_OP_REMOVE_CONFIG: + return xe_oa_remove_config_ioctl(dev, arg->param, file); + default: + return -EINVAL; + } +} + +/** + * xe_observation_ioctl - The top level observation layer ioctl + * @dev: @drm_device + * @data: pointer to struct @drm_xe_observation_param + * @file: @drm_file + * + * The function is called for different observation streams types and + * allows execution of different operations supported by those stream + * types. + * + * Return: 0 on success or a negative error code on failure. + */ +int xe_observation_ioctl(struct drm_device *dev, void *data, struct drm_file *file) +{ + struct drm_xe_observation_param *arg = data; + + if (arg->extensions) + return -EINVAL; + + switch (arg->observation_type) { + case DRM_XE_OBSERVATION_TYPE_OA: + return xe_oa_ioctl(dev, arg, file); + default: + return -EINVAL; + } +} + +static struct ctl_table observation_ctl_table[] = { + { + .procname = "observation_paranoid", + .data = &xe_observation_paranoid, + .maxlen = sizeof(xe_observation_paranoid), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, + {} +}; + +/** + * xe_observation_sysctl_register - Register xe_observation_paranoid sysctl + * + * Normally only superuser/root can access observation stream + * data. However, superuser can set xe_observation_paranoid sysctl to 0 to + * allow non-privileged users to also access observation data. + * + * Return: always returns 0 + */ +int xe_observation_sysctl_register(void) +{ + sysctl_header = register_sysctl("dev/xe", observation_ctl_table); + return 0; +} + +/** + * xe_observation_sysctl_unregister - Unregister xe_observation_paranoid sysctl + */ +void xe_observation_sysctl_unregister(void) +{ + unregister_sysctl_table(sysctl_header); +} diff --git a/drivers/gpu/drm/xe/xe_observation.h b/drivers/gpu/drm/xe/xe_observation.h new file mode 100644 index 000000000000..17816998e966 --- /dev/null +++ b/drivers/gpu/drm/xe/xe_observation.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023-2024 Intel Corporation + */ + +#ifndef _XE_OBSERVATION_H_ +#define _XE_OBSERVATION_H_ + +#include + +struct drm_device; +struct drm_file; + +extern u32 xe_observation_paranoid; + +int xe_observation_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int xe_observation_sysctl_register(void); +void xe_observation_sysctl_unregister(void); + +#endif diff --git a/drivers/gpu/drm/xe/xe_perf.c b/drivers/gpu/drm/xe/xe_perf.c deleted file mode 100644 index d6cd74cadf34..000000000000 --- a/drivers/gpu/drm/xe/xe_perf.c +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2023-2024 Intel Corporation - */ - -#include -#include - -#include - -#include "xe_oa.h" -#include "xe_perf.h" - -u32 xe_perf_stream_paranoid = true; -static struct ctl_table_header *sysctl_header; - -static int xe_oa_ioctl(struct drm_device *dev, struct drm_xe_perf_param *arg, - struct drm_file *file) -{ - switch (arg->perf_op) { - case DRM_XE_PERF_OP_STREAM_OPEN: - return xe_oa_stream_open_ioctl(dev, arg->param, file); - case DRM_XE_PERF_OP_ADD_CONFIG: - return xe_oa_add_config_ioctl(dev, arg->param, file); - case DRM_XE_PERF_OP_REMOVE_CONFIG: - return xe_oa_remove_config_ioctl(dev, arg->param, file); - default: - return -EINVAL; - } -} - -/** - * xe_perf_ioctl - The top level perf layer ioctl - * @dev: @drm_device - * @data: pointer to struct @drm_xe_perf_param - * @file: @drm_file - * - * The function is called for different perf streams types and allows execution - * of different operations supported by those perf stream types. - * - * Return: 0 on success or a negative error code on failure. - */ -int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file) -{ - struct drm_xe_perf_param *arg = data; - - if (arg->extensions) - return -EINVAL; - - switch (arg->perf_type) { - case DRM_XE_PERF_TYPE_OA: - return xe_oa_ioctl(dev, arg, file); - default: - return -EINVAL; - } -} - -static struct ctl_table perf_ctl_table[] = { - { - .procname = "perf_stream_paranoid", - .data = &xe_perf_stream_paranoid, - .maxlen = sizeof(xe_perf_stream_paranoid), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = SYSCTL_ZERO, - .extra2 = SYSCTL_ONE, - }, - {} -}; - -/** - * xe_perf_sysctl_register - Register "perf_stream_paranoid" sysctl - * - * Normally only superuser/root can access perf counter data. However, - * superuser can set perf_stream_paranoid sysctl to 0 to allow non-privileged - * users to also access perf data. - * - * Return: always returns 0 - */ -int xe_perf_sysctl_register(void) -{ - sysctl_header = register_sysctl("dev/xe", perf_ctl_table); - return 0; -} - -/** - * xe_perf_sysctl_unregister - Unregister "perf_stream_paranoid" sysctl - */ -void xe_perf_sysctl_unregister(void) -{ - unregister_sysctl_table(sysctl_header); -} diff --git a/drivers/gpu/drm/xe/xe_perf.h b/drivers/gpu/drm/xe/xe_perf.h deleted file mode 100644 index 53a8377a1bb1..000000000000 --- a/drivers/gpu/drm/xe/xe_perf.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023-2024 Intel Corporation - */ - -#ifndef _XE_PERF_H_ -#define _XE_PERF_H_ - -#include - -struct drm_device; -struct drm_file; - -extern u32 xe_perf_stream_paranoid; - -int xe_perf_ioctl(struct drm_device *dev, void *data, struct drm_file *file); -int xe_perf_sysctl_register(void); -void xe_perf_sysctl_unregister(void); - -#endif diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 12eaa8532b5c..33544ef78d3e 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -80,7 +80,7 @@ extern "C" { * - &DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY * - &DRM_IOCTL_XE_EXEC * - &DRM_IOCTL_XE_WAIT_USER_FENCE - * - &DRM_IOCTL_XE_PERF + * - &DRM_IOCTL_XE_OBSERVATION */ /* @@ -101,7 +101,7 @@ extern "C" { #define DRM_XE_EXEC_QUEUE_GET_PROPERTY 0x08 #define DRM_XE_EXEC 0x09 #define DRM_XE_WAIT_USER_FENCE 0x0a -#define DRM_XE_PERF 0x0b +#define DRM_XE_OBSERVATION 0x0b /* Must be kept compact -- no holes */ @@ -116,7 +116,7 @@ extern "C" { #define DRM_IOCTL_XE_EXEC_QUEUE_GET_PROPERTY DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_EXEC_QUEUE_GET_PROPERTY, struct drm_xe_exec_queue_get_property) #define DRM_IOCTL_XE_EXEC DRM_IOW(DRM_COMMAND_BASE + DRM_XE_EXEC, struct drm_xe_exec) #define DRM_IOCTL_XE_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_XE_WAIT_USER_FENCE, struct drm_xe_wait_user_fence) -#define DRM_IOCTL_XE_PERF DRM_IOW(DRM_COMMAND_BASE + DRM_XE_PERF, struct drm_xe_perf_param) +#define DRM_IOCTL_XE_OBSERVATION DRM_IOW(DRM_COMMAND_BASE + DRM_XE_OBSERVATION, struct drm_xe_observation_param) /** * DOC: Xe IOCTL Extensions @@ -1376,66 +1376,67 @@ struct drm_xe_wait_user_fence { }; /** - * enum drm_xe_perf_type - Perf stream types + * enum drm_xe_observation_type - Observation stream types */ -enum drm_xe_perf_type { - /** @DRM_XE_PERF_TYPE_OA: OA perf stream type */ - DRM_XE_PERF_TYPE_OA, +enum drm_xe_observation_type { + /** @DRM_XE_OBSERVATION_TYPE_OA: OA observation stream type */ + DRM_XE_OBSERVATION_TYPE_OA, }; /** - * enum drm_xe_perf_op - Perf stream ops + * enum drm_xe_observation_op - Observation stream ops */ -enum drm_xe_perf_op { - /** @DRM_XE_PERF_OP_STREAM_OPEN: Open a perf counter stream */ - DRM_XE_PERF_OP_STREAM_OPEN, +enum drm_xe_observation_op { + /** @DRM_XE_OBSERVATION_OP_STREAM_OPEN: Open an observation stream */ + DRM_XE_OBSERVATION_OP_STREAM_OPEN, - /** @DRM_XE_PERF_OP_ADD_CONFIG: Add perf stream config */ - DRM_XE_PERF_OP_ADD_CONFIG, + /** @DRM_XE_OBSERVATION_OP_ADD_CONFIG: Add observation stream config */ + DRM_XE_OBSERVATION_OP_ADD_CONFIG, - /** @DRM_XE_PERF_OP_REMOVE_CONFIG: Remove perf stream config */ - DRM_XE_PERF_OP_REMOVE_CONFIG, + /** @DRM_XE_OBSERVATION_OP_REMOVE_CONFIG: Remove observation stream config */ + DRM_XE_OBSERVATION_OP_REMOVE_CONFIG, }; /** - * struct drm_xe_perf_param - Input of &DRM_XE_PERF + * struct drm_xe_observation_param - Input of &DRM_XE_OBSERVATION * - * The perf layer enables multiplexing perf counter streams of multiple - * types. The actual params for a particular stream operation are supplied - * via the @param pointer (use __copy_from_user to get these params). + * The observation layer enables multiplexing observation streams of + * multiple types. The actual params for a particular stream operation are + * supplied via the @param pointer (use __copy_from_user to get these + * params). */ -struct drm_xe_perf_param { +struct drm_xe_observation_param { /** @extensions: Pointer to the first extension struct, if any */ __u64 extensions; - /** @perf_type: Perf stream type, of enum @drm_xe_perf_type */ - __u64 perf_type; - /** @perf_op: Perf op, of enum @drm_xe_perf_op */ - __u64 perf_op; + /** @observation_type: observation stream type, of enum @drm_xe_observation_type */ + __u64 observation_type; + /** @observation_op: observation stream op, of enum @drm_xe_observation_op */ + __u64 observation_op; /** @param: Pointer to actual stream params */ __u64 param; }; /** - * enum drm_xe_perf_ioctls - Perf fd ioctl's + * enum drm_xe_observation_ioctls - Observation stream fd ioctl's * - * Information exchanged between userspace and kernel for perf fd ioctl's - * is stream type specific + * Information exchanged between userspace and kernel for observation fd + * ioctl's is stream type specific */ -enum drm_xe_perf_ioctls { - /** @DRM_XE_PERF_IOCTL_ENABLE: Enable data capture for a stream */ - DRM_XE_PERF_IOCTL_ENABLE = _IO('i', 0x0), +enum drm_xe_observation_ioctls { + /** @DRM_XE_OBSERVATION_IOCTL_ENABLE: Enable data capture for an observation stream */ + DRM_XE_OBSERVATION_IOCTL_ENABLE = _IO('i', 0x0), - /** @DRM_XE_PERF_IOCTL_DISABLE: Disable data capture for a stream */ - DRM_XE_PERF_IOCTL_DISABLE = _IO('i', 0x1), + /** @DRM_XE_OBSERVATION_IOCTL_DISABLE: Disable data capture for a observation stream */ + DRM_XE_OBSERVATION_IOCTL_DISABLE = _IO('i', 0x1), - /** @DRM_XE_PERF_IOCTL_CONFIG: Change stream configuration */ - DRM_XE_PERF_IOCTL_CONFIG = _IO('i', 0x2), + /** @DRM_XE_OBSERVATION_IOCTL_CONFIG: Change observation stream configuration */ + DRM_XE_OBSERVATION_IOCTL_CONFIG = _IO('i', 0x2), - /** @DRM_XE_PERF_IOCTL_STATUS: Return stream status */ - DRM_XE_PERF_IOCTL_STATUS = _IO('i', 0x3), + /** @DRM_XE_OBSERVATION_IOCTL_STATUS: Return observation stream status */ + DRM_XE_OBSERVATION_IOCTL_STATUS = _IO('i', 0x3), - /** @DRM_XE_PERF_IOCTL_INFO: Return stream info */ - DRM_XE_PERF_IOCTL_INFO = _IO('i', 0x4), + /** @DRM_XE_OBSERVATION_IOCTL_INFO: Return observation stream info */ + DRM_XE_OBSERVATION_IOCTL_INFO = _IO('i', 0x4), }; /** @@ -1546,12 +1547,12 @@ enum drm_xe_oa_format_type { * Stream params are specified as a chain of @drm_xe_ext_set_property * struct's, with @property values from enum @drm_xe_oa_property_id and * @drm_xe_user_extension base.name set to @DRM_XE_OA_EXTENSION_SET_PROPERTY. - * @param field in struct @drm_xe_perf_param points to the first + * @param field in struct @drm_xe_observation_param points to the first * @drm_xe_ext_set_property struct. * - * Exactly the same mechanism is also used for stream reconfiguration using - * the @DRM_XE_PERF_IOCTL_CONFIG perf fd ioctl, though only a subset of - * properties below can be specified for stream reconfiguration. + * Exactly the same mechanism is also used for stream reconfiguration using the + * @DRM_XE_OBSERVATION_IOCTL_CONFIG observation stream fd ioctl, though only a + * subset of properties below can be specified for stream reconfiguration. */ enum drm_xe_oa_property_id { #define DRM_XE_OA_EXTENSION_SET_PROPERTY 0 @@ -1571,11 +1572,11 @@ enum drm_xe_oa_property_id { /** * @DRM_XE_OA_PROPERTY_OA_METRIC_SET: OA metrics defining contents of OA - * reports, previously added via @DRM_XE_PERF_OP_ADD_CONFIG. + * reports, previously added via @DRM_XE_OBSERVATION_OP_ADD_CONFIG. */ DRM_XE_OA_PROPERTY_OA_METRIC_SET, - /** @DRM_XE_OA_PROPERTY_OA_FORMAT: Perf counter report format */ + /** @DRM_XE_OA_PROPERTY_OA_FORMAT: OA counter report format */ DRM_XE_OA_PROPERTY_OA_FORMAT, /* * OA_FORMAT's are specified the same way as in PRM/Bspec 52198/60942, @@ -1596,13 +1597,13 @@ enum drm_xe_oa_property_id { /** * @DRM_XE_OA_PROPERTY_OA_DISABLED: A value of 1 will open the OA - * stream in a DISABLED state (see @DRM_XE_PERF_IOCTL_ENABLE). + * stream in a DISABLED state (see @DRM_XE_OBSERVATION_IOCTL_ENABLE). */ DRM_XE_OA_PROPERTY_OA_DISABLED, /** * @DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID: Open the stream for a specific - * @exec_queue_id. Perf queries can be executed on this exec queue. + * @exec_queue_id. OA queries can be executed on this exec queue. */ DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID, @@ -1622,7 +1623,7 @@ enum drm_xe_oa_property_id { /** * struct drm_xe_oa_config - OA metric configuration * - * Multiple OA configs can be added using @DRM_XE_PERF_OP_ADD_CONFIG. A + * Multiple OA configs can be added using @DRM_XE_OBSERVATION_OP_ADD_CONFIG. A * particular config can be specified when opening an OA stream using * @DRM_XE_OA_PROPERTY_OA_METRIC_SET property. */ @@ -1645,8 +1646,9 @@ struct drm_xe_oa_config { /** * struct drm_xe_oa_stream_status - OA stream status returned from - * @DRM_XE_PERF_IOCTL_STATUS perf fd ioctl. Userspace can call the ioctl to - * query stream status in response to EIO errno from perf fd read(). + * @DRM_XE_OBSERVATION_IOCTL_STATUS observation stream fd ioctl. Userspace can + * call the ioctl to query stream status in response to EIO errno from + * observation fd read(). */ struct drm_xe_oa_stream_status { /** @extensions: Pointer to the first extension struct, if any */ @@ -1665,7 +1667,7 @@ struct drm_xe_oa_stream_status { /** * struct drm_xe_oa_stream_info - OA stream info returned from - * @DRM_XE_PERF_IOCTL_INFO perf fd ioctl + * @DRM_XE_OBSERVATION_IOCTL_INFO observation stream fd ioctl */ struct drm_xe_oa_stream_info { /** @extensions: Pointer to the first extension struct, if any */ -- cgit v1.2.3