diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0342-drm-amd-Add-CGS-interfaces.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0342-drm-amd-Add-CGS-interfaces.patch | 1119 |
1 files changed, 1119 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0342-drm-amd-Add-CGS-interfaces.patch b/common/recipes-kernel/linux/files/0342-drm-amd-Add-CGS-interfaces.patch new file mode 100644 index 00000000..2f02bbf2 --- /dev/null +++ b/common/recipes-kernel/linux/files/0342-drm-amd-Add-CGS-interfaces.patch @@ -0,0 +1,1119 @@ +From d03846af92750f83d36ff2110a0cee444979b2a2 Mon Sep 17 00:00:00 2001 +From: Chunming Zhou <David1.Zhou@amd.com> +Date: Tue, 28 Jul 2015 14:20:03 -0400 +Subject: [PATCH 0342/1050] drm/amd: Add CGS interfaces +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CGS (Common Graphics Services) is an AMD cross component +abstraction layer to designed to better encapsulate +specific IP block drivers so different teams can effectively +work on differnet IP block drivers independently. It provides +a common interface for things like accessing registers, +allocating GPU memory, and registering interrupt sources. +The plan is to eventually move more and more IP drivers to +this interface. The first user is the ACP IP driver. + +Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> +Signed-off-by: Chunming Zhou <David1.Zhou@amd.com> +Acked-by: Christian König <christian.koenig@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/Makefile | 3 + + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 8 + + drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 327 ++++++++++++++++++ + drivers/gpu/drm/amd/include/cgs_common.h | 563 +++++++++++++++++++++++++++++++ + drivers/gpu/drm/amd/include/cgs_linux.h | 135 ++++++++ + 5 files changed, 1036 insertions(+) + create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c + create mode 100644 drivers/gpu/drm/amd/include/cgs_common.h + create mode 100644 drivers/gpu/drm/amd/include/cgs_linux.h + +diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile +index 9083605..ccdbb35 100644 +--- a/drivers/gpu/drm/amd/amdgpu/Makefile ++++ b/drivers/gpu/drm/amd/amdgpu/Makefile +@@ -77,6 +77,9 @@ amdgpu-y += \ + amdgpu_amdkfd_gfx_v7.o \ + amdgpu_amdkfd_gfx_v8.o + ++# add cgs ++amdgpu-y += amdgpu_cgs.o ++ + amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o + amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o + amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index baefa63..548e2bb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -42,6 +42,7 @@ + #include <ttm/ttm_module.h> + #include <ttm/ttm_execbuf_util.h> + ++#include <drm/drmP.h> + #include <drm/drm_gem.h> + #include <drm/amdgpu_drm.h> + +@@ -1862,6 +1863,13 @@ extern int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); + + /* ++ * CGS ++ */ ++void *amdgpu_cgs_create_device(struct amdgpu_device *adev); ++void amdgpu_cgs_destroy_device(void *cgs_device); ++ ++ ++/* + * Core structure, functions and helpers. + */ + typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device*, uint32_t); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +new file mode 100644 +index 0000000..aea264a +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +@@ -0,0 +1,327 @@ ++/* ++ * Copyright 2015 Advanced Micro Devices, Inc. ++ * ++ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. ++ * ++ * ++ */ ++#include "amdgpu.h" ++#include "cgs_linux.h" ++ ++struct amdgpu_cgs_device { ++ struct cgs_device base; ++ struct amdgpu_device *adev; ++}; ++ ++#define CGS_FUNC_ADEV \ ++ struct amdgpu_device *adev = \ ++ ((struct amdgpu_cgs_device *)cgs_device)->adev ++ ++static int amdgpu_cgs_gpu_mem_info(void *cgs_device, enum cgs_gpu_mem_type type, ++ uint64_t *mc_start, uint64_t *mc_size, ++ uint64_t *mem_size) ++{ ++ return 0; ++} ++ ++static int amdgpu_cgs_gmap_kmem(void *cgs_device, void *kmem, ++ uint64_t size, ++ uint64_t min_offset, uint64_t max_offset, ++ cgs_handle_t *kmem_handle, uint64_t *mcaddr) ++{ ++ return 0; ++} ++ ++static int amdgpu_cgs_gunmap_kmem(void *cgs_device, cgs_handle_t kmem_handle) ++{ ++ return 0; ++} ++ ++static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device, ++ enum cgs_gpu_mem_type type, ++ uint64_t size, uint64_t align, ++ uint64_t min_offset, uint64_t max_offset, ++ cgs_handle_t *handle) ++{ ++ return 0; ++} ++ ++static int amdgpu_cgs_import_gpu_mem(void *cgs_device, int dmabuf_fd, ++ cgs_handle_t *handle) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_free_gpu_mem(void *cgs_device, cgs_handle_t handle) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_gmap_gpu_mem(void *cgs_device, cgs_handle_t handle, ++ uint64_t *mcaddr) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_gunmap_gpu_mem(void *cgs_device, cgs_handle_t handle) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_kmap_gpu_mem(void *cgs_device, cgs_handle_t handle, ++ void **map) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_kunmap_gpu_mem(void *cgs_device, cgs_handle_t handle) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static uint32_t amdgpu_cgs_read_register(void *cgs_device, unsigned offset) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static void amdgpu_cgs_write_register(void *cgs_device, unsigned offset, ++ uint32_t value) ++{ ++ /* TODO */ ++ return; ++} ++ ++static uint32_t amdgpu_cgs_read_ind_register(void *cgs_device, ++ enum cgs_ind_reg space, ++ unsigned index) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static void amdgpu_cgs_write_ind_register(void *cgs_device, ++ enum cgs_ind_reg space, ++ unsigned index, uint32_t value) ++{ ++ /* TODO */ ++ return; ++} ++ ++static uint8_t amdgpu_cgs_read_pci_config_byte(void *cgs_device, unsigned addr) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static uint16_t amdgpu_cgs_read_pci_config_word(void *cgs_device, unsigned addr) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static uint32_t amdgpu_cgs_read_pci_config_dword(void *cgs_device, ++ unsigned addr) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static void amdgpu_cgs_write_pci_config_byte(void *cgs_device, unsigned addr, ++ uint8_t value) ++{ ++ /* TODO */ ++ return; ++} ++ ++static void amdgpu_cgs_write_pci_config_word(void *cgs_device, unsigned addr, ++ uint16_t value) ++{ ++ /* TODO */ ++ return; ++} ++ ++static void amdgpu_cgs_write_pci_config_dword(void *cgs_device, unsigned addr, ++ uint32_t value) ++{ ++ /* TODO */ ++ return; ++} ++ ++static const void *amdgpu_cgs_atom_get_data_table(void *cgs_device, ++ unsigned table, uint16_t *size, ++ uint8_t *frev, uint8_t *crev) ++{ ++ /* TODO */ ++ return NULL; ++} ++ ++static int amdgpu_cgs_atom_get_cmd_table_revs(void *cgs_device, unsigned table, ++ uint8_t *frev, uint8_t *crev) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_atom_exec_cmd_table(void *cgs_device, unsigned table, ++ void *args) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++ ++static int amdgpu_cgs_create_pm_request(void *cgs_device, cgs_handle_t *request) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_destroy_pm_request(void *cgs_device, cgs_handle_t request) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_set_pm_request(void *cgs_device, cgs_handle_t request, ++ int active) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_pm_request_clock(void *cgs_device, cgs_handle_t request, ++ enum cgs_clock clock, unsigned freq) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_pm_request_engine(void *cgs_device, cgs_handle_t request, ++ enum cgs_engine engine, int powered) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++ ++ ++static int amdgpu_cgs_pm_query_clock_limits(void *cgs_device, ++ enum cgs_clock clock, ++ struct cgs_clock_limits *limits) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask, ++ const uint32_t *voltages) ++{ ++ DRM_ERROR("not implemented"); ++ return -EPERM; ++} ++ ++static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id, ++ unsigned num_types, ++ cgs_irq_source_set_func_t set, ++ cgs_irq_handler_func_t handler, ++ void *private_data) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++static const struct cgs_ops amdgpu_cgs_ops = { ++ amdgpu_cgs_gpu_mem_info, ++ amdgpu_cgs_gmap_kmem, ++ amdgpu_cgs_gunmap_kmem, ++ amdgpu_cgs_alloc_gpu_mem, ++ amdgpu_cgs_free_gpu_mem, ++ amdgpu_cgs_gmap_gpu_mem, ++ amdgpu_cgs_gunmap_gpu_mem, ++ amdgpu_cgs_kmap_gpu_mem, ++ amdgpu_cgs_kunmap_gpu_mem, ++ amdgpu_cgs_read_register, ++ amdgpu_cgs_write_register, ++ amdgpu_cgs_read_ind_register, ++ amdgpu_cgs_write_ind_register, ++ amdgpu_cgs_read_pci_config_byte, ++ amdgpu_cgs_read_pci_config_word, ++ amdgpu_cgs_read_pci_config_dword, ++ amdgpu_cgs_write_pci_config_byte, ++ amdgpu_cgs_write_pci_config_word, ++ amdgpu_cgs_write_pci_config_dword, ++ amdgpu_cgs_atom_get_data_table, ++ amdgpu_cgs_atom_get_cmd_table_revs, ++ amdgpu_cgs_atom_exec_cmd_table, ++ amdgpu_cgs_create_pm_request, ++ amdgpu_cgs_destroy_pm_request, ++ amdgpu_cgs_set_pm_request, ++ amdgpu_cgs_pm_request_clock, ++ amdgpu_cgs_pm_request_engine, ++ amdgpu_cgs_pm_query_clock_limits, ++ amdgpu_cgs_set_camera_voltages ++}; ++ ++static const struct cgs_os_ops amdgpu_cgs_os_ops = { ++ amdgpu_cgs_import_gpu_mem, ++ amdgpu_cgs_add_irq_source, ++ amdgpu_cgs_irq_get, ++ amdgpu_cgs_irq_put ++}; ++ ++void *amdgpu_cgs_create_device(struct amdgpu_device *adev) ++{ ++ struct amdgpu_cgs_device *cgs_device = ++ kmalloc(sizeof(*cgs_device), GFP_KERNEL); ++ ++ if (!cgs_device) { ++ DRM_ERROR("Couldn't allocate CGS device structure\n"); ++ return NULL; ++ } ++ ++ cgs_device->base.ops = &amdgpu_cgs_ops; ++ cgs_device->base.os_ops = &amdgpu_cgs_os_ops; ++ cgs_device->adev = adev; ++ ++ return cgs_device; ++} ++ ++void amdgpu_cgs_destroy_device(void *cgs_device) ++{ ++ kfree(cgs_device); ++} +diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h +new file mode 100644 +index 0000000..f8cdb88 +--- /dev/null ++++ b/drivers/gpu/drm/amd/include/cgs_common.h +@@ -0,0 +1,563 @@ ++/* ++ * Copyright 2015 Advanced Micro Devices, Inc. ++ * ++ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 _CGS_COMMON_H ++#define _CGS_COMMON_H ++ ++/** ++ * enum cgs_gpu_mem_type - GPU memory types ++ */ ++enum cgs_gpu_mem_type { ++ CGS_GPU_MEM_TYPE__VISIBLE_FB, ++ CGS_GPU_MEM_TYPE__INVISIBLE_FB, ++ CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB, ++ CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB, ++ CGS_GPU_MEM_TYPE__GART_CACHEABLE, ++ CGS_GPU_MEM_TYPE__GART_WRITECOMBINE ++}; ++ ++/** ++ * enum cgs_ind_reg - Indirect register spaces ++ */ ++enum cgs_ind_reg { ++ CGS_IND_REG__MMIO, ++ CGS_IND_REG__PCIE, ++ CGS_IND_REG__SMC, ++ CGS_IND_REG__UVD_CTX, ++ CGS_IND_REG__DIDT, ++ CGS_IND_REG__AUDIO_ENDPT ++}; ++ ++/** ++ * enum cgs_clock - Clocks controlled by the SMU ++ */ ++enum cgs_clock { ++ CGS_CLOCK__SCLK, ++ CGS_CLOCK__MCLK, ++ CGS_CLOCK__VCLK, ++ CGS_CLOCK__DCLK, ++ CGS_CLOCK__ECLK, ++ CGS_CLOCK__ACLK, ++ CGS_CLOCK__ICLK, ++ /* ... */ ++}; ++ ++/** ++ * enum cgs_engine - Engines that can be statically power-gated ++ */ ++enum cgs_engine { ++ CGS_ENGINE__UVD, ++ CGS_ENGINE__VCE, ++ CGS_ENGINE__VP8, ++ CGS_ENGINE__ACP_DMA, ++ CGS_ENGINE__ACP_DSP0, ++ CGS_ENGINE__ACP_DSP1, ++ CGS_ENGINE__ISP, ++ /* ... */ ++}; ++ ++/** ++ * enum cgs_voltage_planes - Voltage planes for external camera HW ++ */ ++enum cgs_voltage_planes { ++ CGS_VOLTAGE_PLANE__SENSOR0, ++ CGS_VOLTAGE_PLANE__SENSOR1, ++ /* ... */ ++}; ++ ++/** ++ * struct cgs_clock_limits - Clock limits ++ * ++ * Clocks are specified in 10KHz units. ++ */ ++struct cgs_clock_limits { ++ unsigned min; /**< Minimum supported frequency */ ++ unsigned max; /**< Maxumim supported frequency */ ++ unsigned sustainable; /**< Thermally sustainable frequency */ ++}; ++ ++typedef unsigned long cgs_handle_t; ++ ++/** ++ * cgs_gpu_mem_info() - Return information about memory heaps ++ * @cgs_device: opaque device handle ++ * @type: memory type ++ * @mc_start: Start MC address of the heap (output) ++ * @mc_size: MC address space size (output) ++ * @mem_size: maximum amount of memory available for allocation (output) ++ * ++ * This function returns information about memory heaps. The type ++ * parameter is used to select the memory heap. The mc_start and ++ * mc_size for GART heaps may be bigger than the memory available for ++ * allocation. ++ * ++ * mc_start and mc_size are undefined for non-contiguous FB memory ++ * types, since buffers allocated with these types may or may not be ++ * GART mapped. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_gpu_mem_info_t)(void *cgs_device, enum cgs_gpu_mem_type type, ++ uint64_t *mc_start, uint64_t *mc_size, ++ uint64_t *mem_size); ++ ++/** ++ * cgs_gmap_kmem() - map kernel memory to GART aperture ++ * @cgs_device: opaque device handle ++ * @kmem: pointer to kernel memory ++ * @size: size to map ++ * @min_offset: minimum offset from start of GART aperture ++ * @max_offset: maximum offset from start of GART aperture ++ * @kmem_handle: kernel memory handle (output) ++ * @mcaddr: MC address (output) ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_gmap_kmem_t)(void *cgs_device, void *kmem, uint64_t size, ++ uint64_t min_offset, uint64_t max_offset, ++ cgs_handle_t *kmem_handle, uint64_t *mcaddr); ++ ++/** ++ * cgs_gunmap_kmem() - unmap kernel memory ++ * @cgs_device: opaque device handle ++ * @kmem_handle: kernel memory handle returned by gmap_kmem ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_gunmap_kmem_t)(void *cgs_device, cgs_handle_t kmem_handle); ++ ++/** ++ * cgs_alloc_gpu_mem() - Allocate GPU memory ++ * @cgs_device: opaque device handle ++ * @type: memory type ++ * @size: size in bytes ++ * @align: alignment in bytes ++ * @min_offset: minimum offset from start of heap ++ * @max_offset: maximum offset from start of heap ++ * @handle: memory handle (output) ++ * ++ * The memory types CGS_GPU_MEM_TYPE_*_CONTIG_FB force contiguous ++ * memory allocation. This guarantees that the MC address returned by ++ * cgs_gmap_gpu_mem is not mapped through the GART. The non-contiguous ++ * FB memory types may be GART mapped depending on memory ++ * fragmentation and memory allocator policies. ++ * ++ * If min/max_offset are non-0, the allocation will be forced to ++ * reside between these offsets in its respective memory heap. The ++ * base address that the offset relates to, depends on the memory ++ * type. ++ * ++ * - CGS_GPU_MEM_TYPE__*_CONTIG_FB: FB MC base address ++ * - CGS_GPU_MEM_TYPE__GART_*: GART aperture base address ++ * - others: undefined, don't use with max_offset ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_alloc_gpu_mem_t)(void *cgs_device, enum cgs_gpu_mem_type type, ++ uint64_t size, uint64_t align, ++ uint64_t min_offset, uint64_t max_offset, ++ cgs_handle_t *handle); ++ ++/** ++ * cgs_free_gpu_mem() - Free GPU memory ++ * @cgs_device: opaque device handle ++ * @handle: memory handle returned by alloc or import ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_free_gpu_mem_t)(void *cgs_device, cgs_handle_t handle); ++ ++/** ++ * cgs_gmap_gpu_mem() - GPU-map GPU memory ++ * @cgs_device: opaque device handle ++ * @handle: memory handle returned by alloc or import ++ * @mcaddr: MC address (output) ++ * ++ * Ensures that a buffer is GPU accessible and returns its MC address. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_gmap_gpu_mem_t)(void *cgs_device, cgs_handle_t handle, ++ uint64_t *mcaddr); ++ ++/** ++ * cgs_gunmap_gpu_mem() - GPU-unmap GPU memory ++ * @cgs_device: opaque device handle ++ * @handle: memory handle returned by alloc or import ++ * ++ * Allows the buffer to be migrated while it's not used by the GPU. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_gunmap_gpu_mem_t)(void *cgs_device, cgs_handle_t handle); ++ ++/** ++ * cgs_kmap_gpu_mem() - Kernel-map GPU memory ++ * ++ * @cgs_device: opaque device handle ++ * @handle: memory handle returned by alloc or import ++ * @map: Kernel virtual address the memory was mapped to (output) ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_kmap_gpu_mem_t)(void *cgs_device, cgs_handle_t handle, ++ void **map); ++ ++/** ++ * cgs_kunmap_gpu_mem() - Kernel-unmap GPU memory ++ * @cgs_device: opaque device handle ++ * @handle: memory handle returned by alloc or import ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_kunmap_gpu_mem_t)(void *cgs_device, cgs_handle_t handle); ++ ++/** ++ * cgs_read_register() - Read an MMIO register ++ * @cgs_device: opaque device handle ++ * @offset: register offset ++ * ++ * Return: register value ++ */ ++typedef uint32_t (*cgs_read_register_t)(void *cgs_device, unsigned offset); ++ ++/** ++ * cgs_write_register() - Write an MMIO register ++ * @cgs_device: opaque device handle ++ * @offset: register offset ++ * @value: register value ++ */ ++typedef void (*cgs_write_register_t)(void *cgs_device, unsigned offset, ++ uint32_t value); ++ ++/** ++ * cgs_read_ind_register() - Read an indirect register ++ * @cgs_device: opaque device handle ++ * @offset: register offset ++ * ++ * Return: register value ++ */ ++typedef uint32_t (*cgs_read_ind_register_t)(void *cgs_device, enum cgs_ind_reg space, ++ unsigned index); ++ ++/** ++ * cgs_write_ind_register() - Write an indirect register ++ * @cgs_device: opaque device handle ++ * @offset: register offset ++ * @value: register value ++ */ ++typedef void (*cgs_write_ind_register_t)(void *cgs_device, enum cgs_ind_reg space, ++ unsigned index, uint32_t value); ++ ++/** ++ * cgs_read_pci_config_byte() - Read byte from PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address ++ * ++ * Return: Value read ++ */ ++typedef uint8_t (*cgs_read_pci_config_byte_t)(void *cgs_device, unsigned addr); ++ ++/** ++ * cgs_read_pci_config_word() - Read word from PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address, must be word-aligned ++ * ++ * Return: Value read ++ */ ++typedef uint16_t (*cgs_read_pci_config_word_t)(void *cgs_device, unsigned addr); ++ ++/** ++ * cgs_read_pci_config_dword() - Read dword from PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address, must be dword-aligned ++ * ++ * Return: Value read ++ */ ++typedef uint32_t (*cgs_read_pci_config_dword_t)(void *cgs_device, ++ unsigned addr); ++ ++/** ++ * cgs_write_pci_config_byte() - Write byte to PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address ++ * @value: value to write ++ */ ++typedef void (*cgs_write_pci_config_byte_t)(void *cgs_device, unsigned addr, ++ uint8_t value); ++ ++/** ++ * cgs_write_pci_config_word() - Write byte to PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address, must be word-aligned ++ * @value: value to write ++ */ ++typedef void (*cgs_write_pci_config_word_t)(void *cgs_device, unsigned addr, ++ uint16_t value); ++ ++/** ++ * cgs_write_pci_config_dword() - Write byte to PCI configuration space ++ * @cgs_device: opaque device handle ++ * @addr: address, must be dword-aligned ++ * @value: value to write ++ */ ++typedef void (*cgs_write_pci_config_dword_t)(void *cgs_device, unsigned addr, ++ uint32_t value); ++ ++/** ++ * cgs_atom_get_data_table() - Get a pointer to an ATOM BIOS data table ++ * @cgs_device: opaque device handle ++ * @table: data table index ++ * @size: size of the table (output, may be NULL) ++ * @frev: table format revision (output, may be NULL) ++ * @crev: table content revision (output, may be NULL) ++ * ++ * Return: Pointer to start of the table, or NULL on failure ++ */ ++typedef const void *(*cgs_atom_get_data_table_t)( ++ void *cgs_device, unsigned table, ++ uint16_t *size, uint8_t *frev, uint8_t *crev); ++ ++/** ++ * cgs_atom_get_cmd_table_revs() - Get ATOM BIOS command table revisions ++ * @cgs_device: opaque device handle ++ * @table: data table index ++ * @frev: table format revision (output, may be NULL) ++ * @crev: table content revision (output, may be NULL) ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_atom_get_cmd_table_revs_t)(void *cgs_device, unsigned table, ++ uint8_t *frev, uint8_t *crev); ++ ++/** ++ * cgs_atom_exec_cmd_table() - Execute an ATOM BIOS command table ++ * @cgs_device: opaque device handle ++ * @table: command table index ++ * @args: arguments ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_atom_exec_cmd_table_t)(void *cgs_device, ++ unsigned table, void *args); ++ ++/** ++ * cgs_create_pm_request() - Create a power management request ++ * @cgs_device: opaque device handle ++ * @request: handle of created PM request (output) ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_create_pm_request_t)(void *cgs_device, cgs_handle_t *request); ++ ++/** ++ * cgs_destroy_pm_request() - Destroy a power management request ++ * @cgs_device: opaque device handle ++ * @request: handle of created PM request ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_destroy_pm_request_t)(void *cgs_device, cgs_handle_t request); ++ ++/** ++ * cgs_set_pm_request() - Activate or deactiveate a PM request ++ * @cgs_device: opaque device handle ++ * @request: PM request handle ++ * @active: 0 = deactivate, non-0 = activate ++ * ++ * While a PM request is active, its minimum clock requests are taken ++ * into account as the requested engines are powered up. When the ++ * request is inactive, the engines may be powered down and clocks may ++ * be lower, depending on other PM requests by other driver ++ * components. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_set_pm_request_t)(void *cgs_device, cgs_handle_t request, ++ int active); ++ ++/** ++ * cgs_pm_request_clock() - Request a minimum frequency for a specific clock ++ * @cgs_device: opaque device handle ++ * @request: PM request handle ++ * @clock: which clock? ++ * @freq: requested min. frequency in 10KHz units (0 to clear request) ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_pm_request_clock_t)(void *cgs_device, cgs_handle_t request, ++ enum cgs_clock clock, unsigned freq); ++ ++/** ++ * cgs_pm_request_engine() - Request an engine to be powered up ++ * @cgs_device: opaque device handle ++ * @request: PM request handle ++ * @engine: which engine? ++ * @powered: 0 = powered down, non-0 = powered up ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_pm_request_engine_t)(void *cgs_device, cgs_handle_t request, ++ enum cgs_engine engine, int powered); ++ ++/** ++ * cgs_pm_query_clock_limits() - Query clock frequency limits ++ * @cgs_device: opaque device handle ++ * @clock: which clock? ++ * @limits: clock limits ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_pm_query_clock_limits_t)(void *cgs_device, ++ enum cgs_clock clock, ++ struct cgs_clock_limits *limits); ++ ++/** ++ * cgs_set_camera_voltages() - Apply specific voltages to PMIC voltage planes ++ * @cgs_device: opaque device handle ++ * @mask: bitmask of voltages to change (1<<CGS_VOLTAGE_PLANE__xyz|...) ++ * @voltages: pointer to array of voltage values in 1mV units ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_set_camera_voltages_t)(void *cgs_device, uint32_t mask, ++ const uint32_t *voltages); ++ ++struct cgs_ops { ++ /* memory management calls (similar to KFD interface) */ ++ cgs_gpu_mem_info_t gpu_mem_info; ++ cgs_gmap_kmem_t gmap_kmem; ++ cgs_gunmap_kmem_t gunmap_kmem; ++ cgs_alloc_gpu_mem_t alloc_gpu_mem; ++ cgs_free_gpu_mem_t free_gpu_mem; ++ cgs_gmap_gpu_mem_t gmap_gpu_mem; ++ cgs_gunmap_gpu_mem_t gunmap_gpu_mem; ++ cgs_kmap_gpu_mem_t kmap_gpu_mem; ++ cgs_kunmap_gpu_mem_t kunmap_gpu_mem; ++ /* MMIO access */ ++ cgs_read_register_t read_register; ++ cgs_write_register_t write_register; ++ cgs_read_ind_register_t read_ind_register; ++ cgs_write_ind_register_t write_ind_register; ++ /* PCI configuration space access */ ++ cgs_read_pci_config_byte_t read_pci_config_byte; ++ cgs_read_pci_config_word_t read_pci_config_word; ++ cgs_read_pci_config_dword_t read_pci_config_dword; ++ cgs_write_pci_config_byte_t write_pci_config_byte; ++ cgs_write_pci_config_word_t write_pci_config_word; ++ cgs_write_pci_config_dword_t write_pci_config_dword; ++ /* ATOM BIOS */ ++ cgs_atom_get_data_table_t atom_get_data_table; ++ cgs_atom_get_cmd_table_revs_t atom_get_cmd_table_revs; ++ cgs_atom_exec_cmd_table_t atom_exec_cmd_table; ++ /* Power management */ ++ cgs_create_pm_request_t create_pm_request; ++ cgs_destroy_pm_request_t destroy_pm_request; ++ cgs_set_pm_request_t set_pm_request; ++ cgs_pm_request_clock_t pm_request_clock; ++ cgs_pm_request_engine_t pm_request_engine; ++ cgs_pm_query_clock_limits_t pm_query_clock_limits; ++ cgs_set_camera_voltages_t set_camera_voltages; ++ /* ACPI (TODO) */ ++}; ++ ++struct cgs_os_ops; /* To be define in OS-specific CGS header */ ++ ++struct cgs_device ++{ ++ const struct cgs_ops *ops; ++ const struct cgs_os_ops *os_ops; ++ /* to be embedded at the start of driver private structure */ ++}; ++ ++/* Convenience macros that make CGS indirect function calls look like ++ * normal function calls */ ++#define CGS_CALL(func,dev,...) \ ++ (((struct cgs_device *)dev)->ops->func(dev, ##__VA_ARGS__)) ++#define CGS_OS_CALL(func,dev,...) \ ++ (((struct cgs_device *)dev)->os_ops->func(dev, ##__VA_ARGS__)) ++ ++#define cgs_gpu_mem_info(dev,type,mc_start,mc_size,mem_size) \ ++ CGS_CALL(gpu_mem_info,dev,type,mc_start,mc_size,mem_size) ++#define cgs_gmap_kmem(dev,kmem,size,min_off,max_off,kmem_handle,mcaddr) \ ++ CGS_CALL(gmap_kmem,dev,kmem,size,min_off,max_off,kmem_handle,mcaddr) ++#define cgs_gummap_kmem(dev,kmem_handle) \ ++ CGS_CALL(gunmap_kmem,dev,keme_handle) ++#define cgs_alloc_gpu_mem(dev,type,size,align,min_off,max_off,handle) \ ++ CGS_CALL(alloc_gpu_mem,dev,type,size,align,min_off,max_off,handle) ++#define cgs_free_gpu_mem(dev,handle) \ ++ CGS_CALL(free_gpu_mem,dev,handle) ++#define cgs_gmap_gpu_mem(dev,handle,mcaddr) \ ++ CGS_CALL(gmap_gpu_mem,dev,handle,mcaddr) ++#define cgs_gummap_gpu_mem(dev,handle) \ ++ CGS_CALL(gunmap_gpu_mem,dev,handle) ++#define cgs_kmap_gpu_mem(dev,handle,map) \ ++ CGS_CALL(kmap_gpu_mem,dev,handle,map) ++#define cgs_kunmap_gpu_mem(dev,handle) \ ++ CGS_CALL(kunmap_gpu_mem,dev,handle) ++ ++#define cgs_read_register(dev,offset) \ ++ CGS_CALL(read_register,dev,offset) ++#define cgs_write_register(dev,offset,value) \ ++ CGS_CALL(write_register,dev,offset,value) ++#define cgs_read_ind_register(dev,space,index) \ ++ CGS_CALL(read_ind_register,dev,space,index) ++#define cgs_write_ind_register(dev,space,index,value) \ ++ CGS_CALL(write_ind_register,dev,space,index,value) ++ ++#define cgs_read_pci_config_byte(dev,addr) \ ++ CGS_CALL(read_pci_config_byte,dev,addr) ++#define cgs_read_pci_config_word(dev,addr) \ ++ CGS_CALL(read_pci_config_word,dev,addr) ++#define cgs_read_pci_config_dword(dev,addr) \ ++ CGS_CALL(read_pci_config_dword,dev,addr) ++#define cgs_write_pci_config_byte(dev,addr,value) \ ++ CGS_CALL(write_pci_config_byte,dev,addr,value) ++#define cgs_write_pci_config_word(dev,addr,value) \ ++ CGS_CALL(write_pci_config_word,dev,addr,value) ++#define cgs_write_pci_config_dword(dev,addr,value) \ ++ CGS_CALL(write_pci_config_dword,dev,addr,value) ++ ++#define cgs_atom_get_data_table(dev,table,size,frev,crev) \ ++ CGS_CALL(atom_get_data_table,dev,table,size,frev,crev) ++#define cgs_atom_get_cmd_table_revs(dev,table,frev,crev) \ ++ CGS_CALL(atom_get_cmd_table_revs,dev,table,frev,crev) ++#define cgs_atom_exec_cmd_table(dev,table,args) \ ++ CGS_CALL(atom_exec_cmd_table,dev,table,args) ++ ++#define cgs_create_pm_request(dev,request) \ ++ CGS_CALL(create_pm_request,dev,request) ++#define cgs_destroy_pm_request(dev,request) \ ++ CGS_CALL(destroy_pm_request,dev,request) ++#define cgs_set_pm_request(dev,request,active) \ ++ CGS_CALL(set_pm_request,dev,request,active) ++#define cgs_pm_request_clock(dev,request,clock,freq) \ ++ CGS_CALL(pm_request_clock,dev,request,clock,freq) ++#define cgs_pm_request_engine(dev,request,engine,powered) \ ++ CGS_CALL(pm_request_engine,dev,request,engine,powered) ++#define cgs_pm_query_clock_limits(dev,clock,limits) \ ++ CGS_CALL(pm_query_clock_limits,dev,clock,limits) ++#define cgs_set_camera_voltages(dev,mask,voltages) \ ++ CGS_CALL(set_camera_voltages,dev,mask,voltages) ++ ++#endif /* _CGS_COMMON_H */ +diff --git a/drivers/gpu/drm/amd/include/cgs_linux.h b/drivers/gpu/drm/amd/include/cgs_linux.h +new file mode 100644 +index 0000000..488642f +--- /dev/null ++++ b/drivers/gpu/drm/amd/include/cgs_linux.h +@@ -0,0 +1,135 @@ ++/* ++ * Copyright 2015 Advanced Micro Devices, Inc. ++ * ++ * 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 _CGS_LINUX_H ++#define _CGS_LINUX_H ++ ++#include "cgs_common.h" ++ ++/** ++ * cgs_import_gpu_mem() - Import dmabuf handle ++ * @cgs_device: opaque device handle ++ * @dmabuf_fd: DMABuf file descriptor ++ * @handle: memory handle (output) ++ * ++ * Must be called in the process context that dmabuf_fd belongs to. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_import_gpu_mem_t)(void *cgs_device, int dmabuf_fd, ++ cgs_handle_t *handle); ++ ++/** ++ * cgs_irq_source_set_func() - Callback for enabling/disabling interrupt sources ++ * @private_data: private data provided to cgs_add_irq_source ++ * @src_id: interrupt source ID ++ * @type: interrupt type ++ * @enabled: 0 = disable source, non-0 = enable source ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_irq_source_set_func_t)(void *private_data, ++ unsigned src_id, unsigned type, ++ int enabled); ++ ++/** ++ * cgs_irq_handler_func() - Interrupt handler callback ++ * @private_data: private data provided to cgs_add_irq_source ++ * @src_id: interrupt source ID ++ * @iv_entry: pointer to raw ih ring entry ++ * ++ * This callback runs in interrupt context. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_irq_handler_func_t)(void *private_data, ++ unsigned src_id, const uint32_t *iv_entry); ++ ++/** ++ * cgs_add_irq_source() - Add an IRQ source ++ * @cgs_device: opaque device handle ++ * @src_id: interrupt source ID ++ * @num_types: number of interrupt types that can be independently enabled ++ * @set: callback function to enable/disable an interrupt type ++ * @handler: interrupt handler callback ++ * @private_data: private data to pass to callback functions ++ * ++ * The same IRQ source can be added only once. Adding an IRQ source ++ * indicates ownership of that IRQ source and all its IRQ types. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_add_irq_source_t)(void *cgs_device, unsigned src_id, ++ unsigned num_types, ++ cgs_irq_source_set_func_t set, ++ cgs_irq_handler_func_t handler, ++ void *private_data); ++ ++/** ++ * cgs_irq_get() - Request enabling an IRQ source and type ++ * @cgs_device: opaque device handle ++ * @src_id: interrupt source ID ++ * @type: interrupt type ++ * ++ * cgs_irq_get and cgs_irq_put calls must be balanced. They count ++ * "references" to IRQ sources. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_irq_get_t)(void *cgs_device, unsigned src_id, unsigned type); ++ ++/** ++ * cgs_irq_put() - Indicate IRQ source is no longer needed ++ * @cgs_device: opaque device handle ++ * @src_id: interrupt source ID ++ * @type: interrupt type ++ * ++ * cgs_irq_get and cgs_irq_put calls must be balanced. They count ++ * "references" to IRQ sources. Even after cgs_irq_put is called, the ++ * IRQ handler may still be called if there are more refecences to ++ * the IRQ source. ++ * ++ * Return: 0 on success, -errno otherwise ++ */ ++typedef int (*cgs_irq_put_t)(void *cgs_device, unsigned src_id, unsigned type); ++ ++struct cgs_os_ops { ++ cgs_import_gpu_mem_t import_gpu_mem; ++ ++ /* IRQ handling */ ++ cgs_add_irq_source_t add_irq_source; ++ cgs_irq_get_t irq_get; ++ cgs_irq_put_t irq_put; ++}; ++ ++#define cgs_import_gpu_mem(dev,dmabuf_fd,handle) \ ++ CGS_OS_CALL(import_gpu_mem,dev,dmabuf_fd,handle) ++#define cgs_add_irq_source(dev,src_id,num_types,set,handler,private_data) \ ++ CGS_OS_CALL(add_irq_source,dev,src_id,num_types,set,handler, \ ++ private_data) ++#define cgs_irq_get(dev,src_id,type) \ ++ CGS_OS_CALL(irq_get,dev,src_id,type) ++#define cgs_irq_put(dev,src_id,type) \ ++ CGS_OS_CALL(irq_put,dev,src_id,type) ++ ++#endif /* _CGS_LINUX_H */ +-- +1.9.1 + |