[PATCH 00/11] Add H/W Debugger module support to amdkfd
This patch-set adds the H/W debugger module support to amdkfd. The H/W debugger module support enables a userspace debugger, e.g gdb, to debug GPU kernels running in HSA mode. The available operations in this patch-set are setting watchpoints in the GPU kernel and controlling wave-fronts. It is important to mention that due to security reasons, the userspace process can only debug itself. This means that the process should contain an "agent" that could be connected to remotely by a debugger, which will provide the front-end to the user. There is ongoing work inside AMD to provide such a tool via gdb extensions. In addition, this patch-set enables amdkfd to "kill" all running waves, in case of an infinite GPU kernel (due to bug or malicious attack), by using the debugger infrastructure. This provides greater control to the kernel level, which is always a good thing, IMO. More data is inside the individual commit messages. Please review. Thanks, Oded Alexey Skidanov (1): drm/radeon: Add ATC VMID<-->PASID functions to kfd->kgd Ben Goz (1): drm/amdkfd: Enforce kill all waves on process termination Yair Shachar (9): drm/radeon: Add H/W debugger kfd->kgd functions drm/amdkfd: add H/W debugger IOCTL set definitions drm/amdkfd: Add static user-mode queues support drm/amdkfd: Add skeleton H/W debugger module support drm/amdkfd: Add wave control operation to debugger drm/amdkfd: Add address watch operation to debugger drm/amdkfd: Implement (un)register debugger IOCTLs drm/amdkfd: Implement wave control debugger IOCTL drm/amdkfd: Implement address watch debugger IOCTL drivers/gpu/drm/amd/amdkfd/Makefile| 3 +- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 310 +++ drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c| 886 + drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h| 193 + drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c| 168 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h| 294 +++ drivers/gpu/drm/amd/amdkfd/kfd_device.c| 5 + .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 48 +- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 6 + drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c| 46 +- drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h | 6 +- drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h | 290 +++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 18 + drivers/gpu/drm/amd/amdkfd/kfd_process.c | 8 + .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 18 +- drivers/gpu/drm/amd/include/kgd_kfd_interface.h| 21 + drivers/gpu/drm/radeon/cik_reg.h | 56 +- drivers/gpu/drm/radeon/cikd.h | 9 +- drivers/gpu/drm/radeon/radeon_kfd.c| 151 +++- include/uapi/linux/kfd_ioctl.h | 43 +- 20 files changed, 2548 insertions(+), 31 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h -- 2.1.0
[PATCH 01/11] drm/radeon: Add H/W debugger kfd->kgd functions
From: Yair Shachar This patch adds new interface functions to the kfd2kgd interface file. The new functions allow to perform H/W debugger operations by writing to GPU registers. Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 13 +++ drivers/gpu/drm/radeon/cik_reg.h| 56 +++- drivers/gpu/drm/radeon/radeon_kfd.c | 113 3 files changed, 181 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 4ea21ae..afde1b7 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -163,6 +163,19 @@ struct kfd2kgd_calls { int (*hqd_sdma_destroy)(struct kgd_dev *kgd, void *mqd, unsigned int timeout); + int (*address_watch_disable)(struct kgd_dev *kgd); + int (*address_watch_execute)(struct kgd_dev *kgd, + unsigned int watch_point_id, + uint32_t cntl_val, + uint32_t addr_hi, + uint32_t addr_lo); + int (*wave_control_execute)(struct kgd_dev *kgd, + uint32_t gfx_index_val, + uint32_t sq_cmd); + uint32_t (*address_watch_get_offset)(struct kgd_dev *kgd, + unsigned int watch_point_id, + unsigned int reg_offset); + uint16_t (*get_fw_version)(struct kgd_dev *kgd, enum kgd_engine_type type); }; diff --git a/drivers/gpu/drm/radeon/cik_reg.h b/drivers/gpu/drm/radeon/cik_reg.h index 0ec5d53..4e883fd 100644 --- a/drivers/gpu/drm/radeon/cik_reg.h +++ b/drivers/gpu/drm/radeon/cik_reg.h @@ -149,10 +149,30 @@ #define KFD_CIK_SDMA_QUEUE_OFFSET 0x200 +#define SQ_IND_INDEX 0x8DE0 +#define SQ_CMD 0x8DEC +#define SQ_IND_DATA0x8DE4 + +/* + * The TCP_WATCHx_ addresses that are shown here are in dwords, + * and that's why they are multiplied by 4 + */ +#define TCP_WATCH0_ADDR_H (0x32A0*4) +#define TCP_WATCH1_ADDR_H (0x32A3*4) +#define TCP_WATCH2_ADDR_H (0x32A6*4) +#define TCP_WATCH3_ADDR_H (0x32A9*4) +#define TCP_WATCH0_ADDR_L (0x32A1*4) +#define TCP_WATCH1_ADDR_L (0x32A4*4) +#define TCP_WATCH2_ADDR_L (0x32A7*4) +#define TCP_WATCH3_ADDR_L (0x32AA*4) +#define TCP_WATCH0_CNTL(0x32A2*4) +#define TCP_WATCH1_CNTL(0x32A5*4) +#define TCP_WATCH2_CNTL(0x32A8*4) +#define TCP_WATCH3_CNTL(0x32AB*4) + #define CPC_INT_CNTL 0xC2D0 #define CP_HQD_IQ_RPTR 0xC970u -#define AQL_ENABLE (1U << 0) #define SDMA0_RLC0_RB_CNTL 0xD400u #defineSDMA_RB_VMID(x) (x << 24) #defineSDMA0_RLC0_RB_BASE 0xD404u @@ -186,4 +206,38 @@ #defineSDMA0_CNTL 0xD010 #defineSDMA1_CNTL 0xD810 +enum { + MAX_TRAPID = 8, /* 3 bits in the bitfield. */ + MAX_WATCH_ADDRESSES = 4 +}; + +enum { + ADDRESS_WATCH_REG_ADDR_HI = 0, + ADDRESS_WATCH_REG_ADDR_LO, + ADDRESS_WATCH_REG_CNTL, + ADDRESS_WATCH_REG_MAX +}; + +enum { /* not defined in the CI/KV reg file */ + ADDRESS_WATCH_REG_CNTL_ATC_BIT = 0x1000UL, + ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK = 0x00FF, + ADDRESS_WATCH_REG_ADDLOW_MASK_EXTENSION = 0x0300, + /* extend the mask to 26 bits in order to match the low address field */ + ADDRESS_WATCH_REG_ADDLOW_SHIFT = 6, + ADDRESS_WATCH_REG_ADDHIGH_MASK = 0x +}; + +union TCP_WATCH_CNTL_BITS { + struct { + uint32_t mask:24; + uint32_t vmid:4; + uint32_t atc:1; + uint32_t mode:2; + uint32_t valid:1; + } bitfields, bits; + uint32_t u32All; + signed int i32All; + float f32All; +}; + #endif diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 813a416..fd9590d 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -34,6 +34,13 @@
[PATCH 02/11] drm/amdkfd: add H/W debugger IOCTL set definitions
From: Yair Shachar This patch adds four new IOCTLs to amdkfd. These IOCTLs expose a H/W debugger functionality to the userspace. The IOCTLs are: - AMDKFD_IOC_DBG_REGISTER: The purpose of this IOCTL is to notify amdkfd that a process wants to use GPU debugging facilities on itself only. It is expected that this IOCTL would be called before any other H/W debugger requests are sent to amdkfd and for each GPU where the H/W debugging needs to be enabled. The use of this IOCTL ensures that only one instance of a debugger is active in the system. - AMDKFD_IOC_DBG_UNREGISTER: This IOCTL detaches the debugger/debugged process from the H/W Debug which was established by the AMDKFD_IOC_DBG_REGISTER IOCTL. - AMDKFD_IOC_DBG_ADDRESS_WATCH: This IOCTL allows to set different watchpoints with various conditions as indicated by the IOCTL's arguments. The available number of watchpoints is retrieved from topology. This operation is confined to the current debugged process, which was registered through AMDKFD_IOC_DBG_REGISTER. - AMDKFD_IOC_DBG_WAVE_CONTROL: This IOCTL allows to control a wavefront as indicated by the IOCTL's arguments. For example, you can halt/resume or kill either a single wavefront or a set of wavefronts. This operation is confined to the current debugged process, which was registered through AMDKFD_IOC_DBG_REGISTER. Because the arguments for the address watch IOCTL and wave control IOCTL are dynamic, meaning that they could vary in size, the userspace passes a pointer to a structure (in userspace) that contains the value of the arguments. The kernel driver is responsible to parse this structure and validate its contents. Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 54 include/uapi/linux/kfd_ioctl.h | 43 +++-- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index b2c6109..b358e91 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -432,6 +432,48 @@ out: return err; } +static int kfd_ioctl_dbg_register(struct file *filep, + struct kfd_process *p, void *data) +{ + long status = -EFAULT; + + return status; +} + +static int kfd_ioctl_dbg_unrgesiter(struct file *filep, + struct kfd_process *p, void *data) +{ + long status = -EFAULT; + + return status; +} + +/* + * Parse and generate variable size data structure for address watch. + * Total size of the buffer and # watch points is limited in order + * to prevent kernel abuse. (no bearing to the much smaller HW limitation + * which is enforced by dbgdev module) + * please also note that the watch address itself are not "copied from user", + * since it be set into the HW in user mode values. + * + */ +static int kfd_ioctl_dbg_address_watch(struct file *filep, + struct kfd_process *p, void *data) +{ + long status = -EFAULT; + + return status; +} + +/* Parse and generate fixed size data structure for wave control */ +static int kfd_ioctl_dbg_wave_control(struct file *filep, + struct kfd_process *p, void *data) +{ + long status = -EFAULT; + + return status; +} + static int kfd_ioctl_get_clock_counters(struct file *filep, struct kfd_process *p, void *data) { @@ -612,6 +654,18 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { AMDKFD_IOCTL_DEF(AMDKFD_IOC_WAIT_EVENTS, kfd_ioctl_wait_events, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_REGISTER, + kfd_ioctl_dbg_register, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_UNREGISTER, + kfd_ioctl_dbg_unrgesiter, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_ADDRESS_WATCH, + kfd_ioctl_dbg_address_watch, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_DBG_WAVE_CONTROL, + kfd_ioctl_dbg_wave_control, 0), }; #define AMDKFD_CORE_IOCTL_COUNTARRAY_SIZE(amdkfd_ioctls) diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 4ca35a8..75327e55 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -128,6 +128,32 @@ struct kfd_ioctl_get_process_apertures_args { uint32_t pad; }; +#define MAX_ALLOWED_NUM_POINTS100 +#define MAX_ALLOWED_AW_BUFF_SIZE 4096 +#define MAX_ALLOWED_WAC_BUFF_SIZE 128 + +struct kfd_ioctl_dbg_register_args { + uint32_t gpu_id;/* to KFD */ + uint32_t pad; +}; + +struct kfd_ioctl_dbg_unregister_args { + uint32_t gpu_id;/* to KFD */ + uint32_t pad; +}; + +struct kfd_ioctl_dbg_address_watch_args { + uint32_t gpu_id;/* to KFD */ +
[PATCH 03/11] drm/amdkfd: Add static user-mode queues support
From: Yair Shachar This patch adds support for static user-mode queues in QCM. Queues which are designated as static can NOT be preempted by the CP microcode when it is executing its scheduling algorithm. This is needed for supporting the debugger feature, because we can't allow the CP to preempt queues which are currently being debugged. The number of queues that can be designated as static is limited by the number of HQDs (Hardware Queue Descriptors). Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device.c| 2 + .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 38 ++ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 6 +++ drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c| 46 +- drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h | 6 ++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 + .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 16 7 files changed, 97 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 52cab0f..f1f86db 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -33,6 +33,8 @@ static const struct kfd_device_info kaveri_device_info = { .asic_family = CHIP_KAVERI, .max_pasid_bits = 16, + /* max num of queues for KV.TODO should be a dynamic value */ + .max_no_of_hqd = 24, .ih_ring_entry_size = 4 * sizeof(uint32_t), .event_interrupt_class = &event_interrupt_class_cik, .mqd_size_aligned = MQD_SIZE_ALIGNED diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 4e215bd..a5dc822 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -45,7 +45,8 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd); static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock); -static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock); +static int destroy_queues_cpsch(struct device_queue_manager *dqm, + bool preempt_static_queues, bool lock); static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm, struct queue *q, @@ -775,7 +776,7 @@ static int stop_cpsch(struct device_queue_manager *dqm) BUG_ON(!dqm); - destroy_queues_cpsch(dqm, true); + destroy_queues_cpsch(dqm, true, true); list_for_each_entry(node, &dqm->queues, list) { pdd = qpd_to_pdd(node->qpd); @@ -829,7 +830,8 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, pr_debug("kfd: In %s\n", __func__); mutex_lock(&dqm->lock); - destroy_queues_cpsch(dqm, false); + /* here we actually preempt the DIQ */ + destroy_queues_cpsch(dqm, true, false); list_del(&kq->list); dqm->queue_count--; qpd->is_debug = false; @@ -935,13 +937,15 @@ static int destroy_sdma_queues(struct device_queue_manager *dqm, unsigned int sdma_engine) { return pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_SDMA, - KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, + KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES, 0, false, sdma_engine); } -static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock) +static int destroy_queues_cpsch(struct device_queue_manager *dqm, + bool preempt_static_queues, bool lock) { int retval; + enum kfd_preempt_type_filter preempt_type; BUG_ON(!dqm); @@ -960,8 +964,12 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock) destroy_sdma_queues(dqm, 1); } + preempt_type = preempt_static_queues ? + KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES : + KFD_PREEMPT_TYPE_FILTER_DYNAMIC_QUEUES; + retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE, - KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0); + preempt_type, 0, false, 0); if (retval != 0) goto out; @@ -989,7 +997,7 @@ static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock) if (lock) mutex_lock(&dqm->lock); - retval = destroy_queues_cpsch(dqm, false); + retval = destroy_queues_cpsch(dqm, false, false); if (retval != 0) { pr_err("kfd: the cp might be in an unrecoverable state due to an unsuccessful queues preemption"); goto out; @@ -1024,13 +1032,27 @@ static int destroy_queue
[PATCH 04/11] drm/amdkfd: Add skeleton H/W debugger module support
From: Yair Shachar This patch adds the skeleton H/W debugger module support. This code enables registration and unregistration of a single HSA process at a time. The module saves the process's pasid and use it to verify that only the registered process is allowed to execute debugger operations through the kernel driver. Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/Makefile| 3 +- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c| 142 ++ drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h| 193 ++ drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c| 135 ++ drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h| 287 drivers/gpu/drm/amd/amdkfd/kfd_device.c| 3 + drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h | 290 + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 5 + .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 2 +- 9 files changed, 1058 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers_diq.h diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index 652d254..2855115 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile @@ -12,6 +12,7 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ kfd_kernel_queue_vi.o kfd_packet_manager.o \ kfd_process_queue_manager.o kfd_device_queue_manager.o \ kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ - kfd_interrupt.o kfd_events.o cik_event_interrupt.o + kfd_interrupt.o kfd_events.o cik_event_interrupt.o \ + kfd_dbgdev.o kfd_dbgmgr.o obj-$(CONFIG_HSA_AMD) += amdkfd.o diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c new file mode 100644 index 000..eed4a83 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -0,0 +1,142 @@ +/* + * Copyright 2014 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 +#include +#include +#include +#include +#include +#include + +#include "kfd_pm4_headers.h" +#include "kfd_pm4_headers_diq.h" +#include "kfd_kernel_queue.h" +#include "kfd_priv.h" +#include "kfd_pm4_opcodes.h" +#include "cik_regs.h" +#include "kfd_dbgmgr.h" +#include "kfd_dbgdev.h" +#include "kfd_device_queue_manager.h" +#include "../../radeon/cik_reg.h" + +static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev) +{ + BUG_ON(!dev || !dev->kfd2kgd); + + dev->kfd2kgd->address_watch_disable(dev->kgd); +} + +static int dbgdev_register_nodiq(struct kfd_dbgdev *dbgdev) +{ + BUG_ON(!dbgdev); + + /* +* no action is needed in this case, +* just make sure diq will not be used +*/ + + dbgdev->kq = NULL; + + return 0; +} + +static int dbgdev_register_diq(struct kfd_dbgdev *dbgdev) +{ + struct queue_properties properties; + unsigned int qid; + struct kernel_queue *kq = NULL; + int status; + + BUG_ON(!dbgdev || !dbgdev->pqm || !dbgdev->dev); + + status = pqm_create_queue(dbgdev->pqm, dbgdev->dev, NULL, + &properties, 0, KFD_QUEUE_TYPE_DIQ, + &qid); + + if (status) { + pr_err("amdkfd: Failed to create DIQ\n"); + return status; + } + + pr_debug("DIQ Created with queue id: %d\n", qid); + + kq = pqm_get_kernel_queue(dbgdev->pqm, qid); + + if (kq == NULL) { + pr_err("amdkfd: Er
[PATCH 05/11] drm/amdkfd: Add wave control operation to debugger
From: Yair Shachar The wave control operation supports several command types executed upon existing wave fronts that belong to the currently debugged process. The available commands are: HALT - Freeze wave front(s) execution RESUME - Resume freezed wave front(s) execution KILL - Kill existing wave front(s) Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c| 405 + drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c| 16 + drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h| 5 +- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 + 5 files changed, 430 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index eed4a83..ee33b86 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -47,6 +47,125 @@ static void dbgdev_address_watch_disable_nodiq(struct kfd_dev *dev) dev->kfd2kgd->address_watch_disable(dev->kgd); } +static int dbgdev_diq_submit_ib(struct kfd_dbgdev *dbgdev, + unsigned int pasid, uint64_t vmid0_address, + uint32_t *packet_buff, size_t size_in_bytes) +{ + struct pm4__release_mem *rm_packet; + struct pm4__indirect_buffer_pasid *ib_packet; + struct kfd_mem_obj *mem_obj; + size_t pq_packets_size_in_bytes; + union ULARGE_INTEGER *largep; + union ULARGE_INTEGER addr; + struct kernel_queue *kq; + uint64_t *rm_state; + unsigned int *ib_packet_buff; + int status; + + BUG_ON(!dbgdev || !dbgdev->kq || !packet_buff || !size_in_bytes); + + kq = dbgdev->kq; + + pq_packets_size_in_bytes = sizeof(struct pm4__release_mem) + + sizeof(struct pm4__indirect_buffer_pasid); + + /* +* We acquire a buffer from DIQ +* The receive packet buff will be sitting on the Indirect Buffer +* and in the PQ we put the IB packet + sync packet(s). +*/ + status = kq->ops.acquire_packet_buffer(kq, + pq_packets_size_in_bytes / sizeof(uint32_t), + &ib_packet_buff); + if (status != 0) { + pr_err("amdkfd: acquire_packet_buffer failed\n"); + return status; + } + + memset(ib_packet_buff, 0, pq_packets_size_in_bytes); + + ib_packet = (struct pm4__indirect_buffer_pasid *) (ib_packet_buff); + + ib_packet->header.count = 3; + ib_packet->header.opcode = IT_INDIRECT_BUFFER_PASID; + ib_packet->header.type = PM4_TYPE_3; + + largep = (union ULARGE_INTEGER *) &vmid0_address; + + ib_packet->bitfields2.ib_base_lo = largep->u.low_part >> 2; + ib_packet->bitfields3.ib_base_hi = largep->u.high_part; + + ib_packet->control = (1 << 23) | (1 << 31) | + ((size_in_bytes / sizeof(uint32_t)) & 0xf); + + ib_packet->bitfields5.pasid = pasid; + + /* +* for now we use release mem for GPU-CPU synchronization +* Consider WaitRegMem + WriteData as a better alternative +* we get a GART allocations ( gpu/cpu mapping), +* for the sync variable, and wait until: +* (a) Sync with HW +* (b) Sync var is written by CP to mem. +*/ + rm_packet = (struct pm4__release_mem *) (ib_packet_buff + + (sizeof(struct pm4__indirect_buffer_pasid) / + sizeof(unsigned int))); + + status = kfd_gtt_sa_allocate(dbgdev->dev, sizeof(uint64_t), + &mem_obj); + + if (status != 0) { + pr_err("amdkfd: Failed to allocate GART memory\n"); + kq->ops.rollback_packet(kq); + return status; + } + + rm_state = (uint64_t *) mem_obj->cpu_ptr; + + *rm_state = QUEUESTATE__ACTIVE_COMPLETION_PENDING; + + rm_packet->header.opcode = IT_RELEASE_MEM; + rm_packet->header.type = PM4_TYPE_3; + rm_packet->header.count = sizeof(struct pm4__release_mem) / + sizeof(unsigned int) - 2; + + rm_packet->bitfields2.event_type = CACHE_FLUSH_AND_INV_TS_EVENT; + rm_packet->bitfields2.event_index = + event_index___release_mem__end_of_pipe; + + rm_packet->bitfields2.cache_policy = cache_policy___release_mem__lru; + rm_packet->bitfields2.atc = 0; + rm_packet->bitfields2.tc_wb_action_ena = 1; + + addr.quad_part = mem_obj->gpu_addr; + + rm_packet->bitfields4.address_lo_32b = addr.u.low_part >> 2; + rm_packet->address_hi = addr.u.high_part; + + rm_packet->bitfields3.data_sel = + data_sel___release_mem__send_64_bit_data; + + rm_packet->bitfields3.int_sel =
[PATCH 06/11] drm/amdkfd: Add address watch operation to debugger
From: Yair Shachar The address watch operation gives the ability to specify watch points which will generate a shader breakpoint, based on a specified single address or range of addresses. There is support for read/write/any access modes. Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c | 274 drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.c | 17 ++ drivers/gpu/drm/amd/amdkfd/kfd_dbgmgr.h | 4 + 3 files changed, 295 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index ee33b86..00d8fcf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -236,6 +236,278 @@ static int dbgdev_unregister_diq(struct kfd_dbgdev *dbgdev) return status; } +static void dbgdev_address_watch_set_registers( + const struct dbg_address_watch_info *adw_info, + union TCP_WATCH_ADDR_H_BITS *addrHi, + union TCP_WATCH_ADDR_L_BITS *addrLo, + union TCP_WATCH_CNTL_BITS *cntl, + unsigned int index, unsigned int vmid) +{ + union ULARGE_INTEGER addr; + + BUG_ON(!adw_info || !addrHi || !addrLo || !cntl); + + addr.quad_part = 0; + addrHi->u32All = 0; + addrLo->u32All = 0; + cntl->u32All = 0; + + if (adw_info->watch_mask != NULL) + cntl->bitfields.mask = + (uint32_t) (adw_info->watch_mask[index] & + ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK); + else + cntl->bitfields.mask = ADDRESS_WATCH_REG_CNTL_DEFAULT_MASK; + + addr.quad_part = (unsigned long long) adw_info->watch_address[index]; + + addrHi->bitfields.addr = addr.u.high_part & + ADDRESS_WATCH_REG_ADDHIGH_MASK; + addrLo->bitfields.addr = + (addr.u.low_part >> ADDRESS_WATCH_REG_ADDLOW_SHIFT); + + cntl->bitfields.mode = adw_info->watch_mode[index]; + cntl->bitfields.vmid = (uint32_t) vmid; + /* for now assume it is an ATC address */ + cntl->u32All |= ADDRESS_WATCH_REG_CNTL_ATC_BIT; + + pr_debug("\t\t%20s %08x\n", "set reg mask :", cntl->bitfields.mask); + pr_debug("\t\t%20s %08x\n", "set reg add high :", + addrHi->bitfields.addr); + pr_debug("\t\t%20s %08x\n", "set reg add low :", + addrLo->bitfields.addr); +} + +static int dbgdev_address_watch_nodiq(struct kfd_dbgdev *dbgdev, + struct dbg_address_watch_info *adw_info) +{ + union TCP_WATCH_ADDR_H_BITS addrHi; + union TCP_WATCH_ADDR_L_BITS addrLo; + union TCP_WATCH_CNTL_BITS cntl; + struct kfd_process_device *pdd; + unsigned int i; + + BUG_ON(!dbgdev || !dbgdev->dev || !adw_info); + + /* taking the vmid for that process on the safe way using pdd */ + pdd = kfd_get_process_device_data(dbgdev->dev, + adw_info->process); + if (!pdd) { + pr_err("amdkfd: Failed to get pdd for wave control no DIQ\n"); + return -EFAULT; + } + + addrHi.u32All = 0; + addrLo.u32All = 0; + cntl.u32All = 0; + + if ((adw_info->num_watch_points > MAX_WATCH_ADDRESSES) || + (adw_info->num_watch_points == 0)) { + pr_err("amdkfd: num_watch_points is invalid\n"); + return -EINVAL; + } + + if ((adw_info->watch_mode == NULL) || + (adw_info->watch_address == NULL)) { + pr_err("amdkfd: adw_info fields are not valid\n"); + return -EINVAL; + } + + for (i = 0 ; i < adw_info->num_watch_points ; i++) { + dbgdev_address_watch_set_registers(adw_info, &addrHi, &addrLo, + &cntl, i, pdd->qpd.vmid); + + pr_debug("\t\t%30s\n", "* * * * * * * * * * * * * * * * * *"); + pr_debug("\t\t%20s %08x\n", "register index :", i); + pr_debug("\t\t%20s %08x\n", "vmid is :", pdd->qpd.vmid); + pr_debug("\t\t%20s %08x\n", "Address Low is :", + addrLo.bitfields.addr); + pr_debug("\t\t%20s %08x\n", "Address high is :", + addrHi.bitfields.addr); + pr_debug("\t\t%20s %08x\n", "Address high is :", + addrHi.bitfields.addr); + pr_debug("\t\t%20s %08x\n", "Control Mask is :", + cntl.bitfields.mask); + pr_debug("\t\t%20s %08x\n", "Control Mode is :", + cntl.bitfields.mode); + pr_debug("\t\t%20s %08x\n", "Control Vmid is :", + cntl.bitfields.vmid); + pr_de
[PATCH 07/11] drm/amdkfd: Implement (un)register debugger IOCTLs
From: Yair Shachar Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 72 +++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index b358e91..5b9776d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -35,6 +35,7 @@ #include #include "kfd_priv.h" #include "kfd_device_queue_manager.h" +#include "kfd_dbgmgr.h" static long kfd_ioctl(struct file *, unsigned int, unsigned long); static int kfd_open(struct inode *, struct file *); @@ -435,7 +436,53 @@ out: static int kfd_ioctl_dbg_register(struct file *filep, struct kfd_process *p, void *data) { - long status = -EFAULT; + struct kfd_ioctl_dbg_register_args *args = data; + struct kfd_dev *dev; + struct kfd_dbgmgr *dbgmgr_ptr; + struct kfd_process_device *pdd; + bool create_ok; + long status = 0; + + dev = kfd_device_by_id(args->gpu_id); + if (dev == NULL) + return -EINVAL; + + if (dev->device_info->asic_family == CHIP_CARRIZO) { + pr_debug("kfd_ioctl_dbg_register not supported on CZ\n"); + return -EINVAL; + } + + mutex_lock(get_dbgmgr_mutex()); + mutex_lock(&p->mutex); + + /* +* make sure that we have pdd, if this the first queue created for +* this process +*/ + pdd = kfd_bind_process_to_device(dev, p); + if (IS_ERR(pdd) < 0) { + mutex_unlock(&p->mutex); + mutex_unlock(get_dbgmgr_mutex()); + return PTR_ERR(pdd); + } + + if (dev->dbgmgr == NULL) { + /* In case of a legal call, we have no dbgmgr yet */ + create_ok = kfd_dbgmgr_create(&dbgmgr_ptr, dev); + if (create_ok) { + status = kfd_dbgmgr_register(dbgmgr_ptr, p); + if (status != 0) + kfd_dbgmgr_destroy(dbgmgr_ptr); + else + dev->dbgmgr = dbgmgr_ptr; + } + } else { + pr_debug("debugger already registered\n"); + status = -EINVAL; + } + + mutex_unlock(&p->mutex); + mutex_unlock(get_dbgmgr_mutex()); return status; } @@ -443,7 +490,28 @@ static int kfd_ioctl_dbg_register(struct file *filep, static int kfd_ioctl_dbg_unrgesiter(struct file *filep, struct kfd_process *p, void *data) { - long status = -EFAULT; + struct kfd_ioctl_dbg_unregister_args *args = data; + struct kfd_dev *dev; + long status; + + dev = kfd_device_by_id(args->gpu_id); + if (dev == NULL) + return -EINVAL; + + if (dev->device_info->asic_family == CHIP_CARRIZO) { + pr_debug("kfd_ioctl_dbg_unrgesiter not supported on CZ\n"); + return -EINVAL; + } + + mutex_lock(get_dbgmgr_mutex()); + + status = kfd_dbgmgr_unregister(dev->dbgmgr, p); + if (status == 0) { + kfd_dbgmgr_destroy(dev->dbgmgr); + dev->dbgmgr = NULL; + } + + mutex_unlock(get_dbgmgr_mutex()); return status; } -- 2.1.0
[PATCH 09/11] drm/amdkfd: Implement address watch debugger IOCTL
From: Yair Shachar Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 104 ++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 6288084..fa3f3d6 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -528,7 +528,109 @@ static int kfd_ioctl_dbg_unrgesiter(struct file *filep, static int kfd_ioctl_dbg_address_watch(struct file *filep, struct kfd_process *p, void *data) { - long status = -EFAULT; + struct kfd_ioctl_dbg_address_watch_args *args = data; + struct kfd_dev *dev; + struct dbg_address_watch_info aw_info; + unsigned char *args_buff; + unsigned int args_idx = 0; + uint64_t watch_mask_value = 0; + long status; + + memset((void *) &aw_info, 0, sizeof(struct dbg_address_watch_info)); + + dev = kfd_device_by_id(args->gpu_id); + if (dev == NULL) + return -EINVAL; + + if (dev->device_info->asic_family == CHIP_CARRIZO) { + pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n"); + return -EINVAL; + } + + if (args->buf_size_in_bytes > MAX_ALLOWED_AW_BUFF_SIZE) + return -EINVAL; + + if (args->buf_size_in_bytes <= sizeof(*args)) + return -EINVAL; + + /* this is the actual buffer to work with */ + + args_buff = kzalloc(args->buf_size_in_bytes - + sizeof(*args), GFP_KERNEL); + if (args_buff == NULL) + return -ENOMEM; + + if (args->content_ptr == NULL) { + kfree(args_buff); + return -EINVAL; + } + + status = copy_from_user(args_buff, + (void __user *) args->content_ptr, + args->buf_size_in_bytes - sizeof(*args)); + + if (status != 0) { + pr_debug("Failed to copy address watch user data\n"); + kfree(args_buff); + return -EINVAL; + } + + aw_info.process = p; + + aw_info.num_watch_points = *((uint32_t *)(&args_buff[args_idx])); + args_idx += sizeof(aw_info.num_watch_points); + + aw_info.watch_mode = (enum HSA_DBG_WATCH_MODE *) &args_buff[args_idx]; + args_idx += sizeof(enum HSA_DBG_WATCH_MODE) * aw_info.num_watch_points; + + /* +* set watch address base pointer to point on the array base +* within args_buff +*/ + aw_info.watch_address = (uint64_t *) &args_buff[args_idx]; + + /* skip over the addresses buffer */ + args_idx += sizeof(aw_info.watch_address) * aw_info.num_watch_points; + + if (args_idx >= args->buf_size_in_bytes) { + kfree(args_buff); + return -EINVAL; + } + + watch_mask_value = (uint64_t) args_buff[args_idx]; + + if (watch_mask_value > 0) { + /* +* There is an array of masks. +* set watch mask base pointer to point on the array base +* within args_buff +*/ + aw_info.watch_mask = (uint64_t *) &args_buff[args_idx]; + + /* skip over the masks buffer */ + args_idx += sizeof(aw_info.watch_mask) * + aw_info.num_watch_points; + } else { + /* just the NULL mask, set to NULL and skip over it */ + aw_info.watch_mask = NULL; + args_idx += sizeof(aw_info.watch_mask); + } + + if (args_idx > args->buf_size_in_bytes) { + kfree(args_buff); + return -EINVAL; + } + + /* Currently HSA Event is not supported for DBG */ + aw_info.watch_event = NULL; + + mutex_lock(get_dbgmgr_mutex()); + + status = kfd_dbgmgr_address_watch(dev->dbgmgr, &aw_info); + + mutex_unlock(get_dbgmgr_mutex()); + + kfree(args_buff); return status; } -- 2.1.0
[PATCH 10/11] drm/radeon: Add ATC VMID<-->PASID functions to kfd->kgd
From: Alexey Skidanov This patch adds three new interfaces to kfd2kgd interface file of radeon. The interfaces are: - Check if a specific VMID has a valid PASID mapping - Retrieve the PASID which is mapped to a specific VMID - Issue a VMID invalidation request to the ATC Signed-off-by: Alexey Skidanov Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/include/kgd_kfd_interface.h | 8 ++ drivers/gpu/drm/radeon/cikd.h | 9 -- drivers/gpu/drm/radeon/radeon_kfd.c | 38 +++-- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index afde1b7..9080daa 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -175,6 +175,14 @@ struct kfd2kgd_calls { uint32_t (*address_watch_get_offset)(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset); + bool (*get_atc_vmid_pasid_mapping_valid)( + struct kgd_dev *kgd, + uint8_t vmid); + uint16_t (*get_atc_vmid_pasid_mapping_pasid)( + struct kgd_dev *kgd, + uint8_t vmid); + void (*write_vmid_invalidate_request)(struct kgd_dev *kgd, + uint8_t vmid); uint16_t (*get_fw_version)(struct kgd_dev *kgd, enum kgd_engine_type type); diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index b33ba3b..391ff9d 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h @@ -2148,9 +2148,12 @@ #define VCE_CMD_IB_AUTO0x0005 #define VCE_CMD_SEMAPHORE 0x0006 -#define ATC_VMID0_PASID_MAPPING0x339Cu -#defineATC_VMID_PASID_MAPPING_UPDATE_STATUS0x3398u -#defineATC_VMID_PASID_MAPPING_VALID(1U << 31) +#define ATC_VMID_PASID_MAPPING_UPDATE_STATUS 0x3398u +#define ATC_VMID0_PASID_MAPPING0x339Cu +#define ATC_VMID_PASID_MAPPING_PASID_MASK (0x) +#define ATC_VMID_PASID_MAPPING_PASID_SHIFT 0 +#define ATC_VMID_PASID_MAPPING_VALID_MASK (0x1 << 31) +#define ATC_VMID_PASID_MAPPING_VALID_SHIFT 31 #define ATC_VM_APERTURE0_CNTL 0x3310u #defineATS_ACCESS_MODE_NEVER 0 diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index fd9590d..e476c33 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c @@ -99,6 +99,11 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, unsigned int watch_point_id, unsigned int reg_offset); +static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid); +static uint16_t get_atc_vmid_pasid_mapping_pasid(struct kgd_dev *kgd, + uint8_t vmid); +static void write_vmid_invalidate_request(struct kgd_dev *kgd, uint8_t vmid); + static const struct kfd2kgd_calls kfd2kgd = { .init_gtt_mem_allocation = alloc_gtt_mem, .free_gtt_mem = free_gtt_mem, @@ -119,6 +124,9 @@ static const struct kfd2kgd_calls kfd2kgd = { .address_watch_execute = kgd_address_watch_execute, .wave_control_execute = kgd_wave_control_execute, .address_watch_get_offset = kgd_address_watch_get_offset, + .get_atc_vmid_pasid_mapping_pasid = get_atc_vmid_pasid_mapping_pasid, + .get_atc_vmid_pasid_mapping_valid = get_atc_vmid_pasid_mapping_valid, + .write_vmid_invalidate_request = write_vmid_invalidate_request, .get_fw_version = get_fw_version }; @@ -395,8 +403,8 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, * the SW cleared it. * So the protocol is to always wait & clear. */ - uint32_t pasid_mapping = (pasid == 0) ? 0 : - (uint32_t)pasid | ATC_VMID_PASID_MAPPING_VALID; + uint32_t pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid | + ATC_VMID_PASID_MAPPING_VALID_MASK; write_register(kgd, ATC_VMID0_PASID_MAPPING + vmid*sizeof(uint32_t), pasid_mapping); @@ -778,6 +786,32 @@ static uint32_t kgd_address_watch_get_offset(struct kgd_dev *kgd, return watchRegs[watch_point_id * ADDRESS_WATCH_REG_MAX + reg_offset]; } +static bool get_atc_vmid_pasid_mapping_valid(struct kgd_dev *kgd, uint8_t vmid) +{ + uint32_t reg; + struc
[PATCH 08/11] drm/amdkfd: Implement wave control debugger IOCTL
From: Yair Shachar Signed-off-by: Yair Shachar Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 88 +++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 5b9776d..6288084 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -537,7 +537,93 @@ static int kfd_ioctl_dbg_address_watch(struct file *filep, static int kfd_ioctl_dbg_wave_control(struct file *filep, struct kfd_process *p, void *data) { - long status = -EFAULT; + struct kfd_ioctl_dbg_wave_control_args *args = data; + struct kfd_dev *dev; + struct dbg_wave_control_info wac_info; + unsigned char *args_buff; + uint32_t computed_buff_size; + long status; + unsigned int args_idx = 0; + + memset((void *) &wac_info, 0, sizeof(struct dbg_wave_control_info)); + + /* we use compact form, independent of the packing attribute value */ + computed_buff_size = sizeof(*args) + + sizeof(wac_info.mode) + + sizeof(wac_info.operand) + + sizeof(wac_info.dbgWave_msg.DbgWaveMsg) + + sizeof(wac_info.dbgWave_msg.MemoryVA) + + sizeof(wac_info.trapId); + + dev = kfd_device_by_id(args->gpu_id); + if (dev == NULL) + return -EINVAL; + + if (dev->device_info->asic_family == CHIP_CARRIZO) { + pr_debug("kfd_ioctl_dbg_wave_control not supported on CZ\n"); + return -EINVAL; + } + + /* input size must match the computed "compact" size */ + if (args->buf_size_in_bytes != computed_buff_size) { + pr_debug("size mismatch, computed : actual %u : %u\n", + args->buf_size_in_bytes, computed_buff_size); + return -EINVAL; + } + + /* this is the actual buffer to work with */ + + args_buff = kzalloc(args->buf_size_in_bytes - sizeof(*args), + GFP_KERNEL); + + if (args_buff == NULL) + return -ENOMEM; + + if (args->content_ptr == NULL) { + kfree(args_buff); + return -EINVAL; + } + + /* Now copy the entire buffer from user */ + status = copy_from_user(args_buff, + (void __user *) args->content_ptr, + args->buf_size_in_bytes - sizeof(*args)); + if (status != 0) { + pr_debug("Failed to copy wave control user data\n"); + kfree(args_buff); + return -EINVAL; + } + + /* move ptr to the start of the "pay-load" area */ + wac_info.process = p; + + wac_info.operand = *((enum HSA_DBG_WAVEOP *)(&args_buff[args_idx])); + args_idx += sizeof(wac_info.operand); + + wac_info.mode = *((enum HSA_DBG_WAVEMODE *)(&args_buff[args_idx])); + args_idx += sizeof(wac_info.mode); + + wac_info.trapId = *((uint32_t *)(&args_buff[args_idx])); + args_idx += sizeof(wac_info.trapId); + + wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value = + *((uint32_t *)(&args_buff[args_idx])); + wac_info.dbgWave_msg.MemoryVA = NULL; + + mutex_lock(get_dbgmgr_mutex()); + + pr_debug("Calling dbg manager process %p, operand %u, mode %u, trapId %u, message %u\n", + wac_info.process, wac_info.operand, + wac_info.mode, wac_info.trapId, + wac_info.dbgWave_msg.DbgWaveMsg.WaveMsgInfoGen2.Value); + + status = kfd_dbgmgr_wave_control(dev->dbgmgr, &wac_info); + + pr_debug("Returned status of dbg manager is %ld\n", status); + + mutex_unlock(get_dbgmgr_mutex()); + + kfree(args_buff); return status; } -- 2.1.0
[PATCH 11/11] drm/amdkfd: Enforce kill all waves on process termination
From: Ben Goz This commit makes sure that on process termination, after we're destroying all the active queues, we're killing all the existing wave front of the current process. By doing this we're making sure that if any of the CUs were blocked by infinite loop we're enforcing it to end the shader explicitly. Signed-off-by: Ben Goz Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c| 65 ++ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 8 ++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 7 +++ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 8 +++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index 00d8fcf..96153f2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -792,6 +792,71 @@ static int dbgdev_wave_control_nodiq(struct kfd_dbgdev *dbgdev, reg_sq_cmd.u32All); } +int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p) +{ + int status = 0; + unsigned int vmid; + union SQ_CMD_BITS reg_sq_cmd; + union GRBM_GFX_INDEX_BITS reg_gfx_index; + struct kfd_process_device *pdd; + struct dbg_wave_control_info wac_info; + int temp; + int first_vmid_to_scan = 8; + int last_vmid_to_scan = 15; + + first_vmid_to_scan = ffs(dev->shared_resources.compute_vmid_bitmap) - 1; + temp = dev->shared_resources.compute_vmid_bitmap >> first_vmid_to_scan; + last_vmid_to_scan = first_vmid_to_scan + ffz(temp); + + reg_sq_cmd.u32All = 0; + status = 0; + + wac_info.mode = HSA_DBG_WAVEMODE_BROADCAST_PROCESS; + wac_info.operand = HSA_DBG_WAVEOP_KILL; + + pr_debug("Killing all process wavefronts\n"); + + /* Scan all registers in the range ATC_VMID8_PASID_MAPPING .. +* ATC_VMID15_PASID_MAPPING +* to check which VMID the current process is mapped to. */ + + for (vmid = first_vmid_to_scan; vmid <= last_vmid_to_scan; vmid++) { + if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid + (dev->kgd, vmid)) { + if (dev->kfd2kgd->get_atc_vmid_pasid_mapping_valid + (dev->kgd, vmid) == p->pasid) { + pr_debug("Killing wave fronts of vmid %d and pasid %d\n", + vmid, p->pasid); + break; + } + } + } + + if (vmid > last_vmid_to_scan) { + pr_err("amdkfd: didn't found vmid for pasid (%d)\n", p->pasid); + return -EFAULT; + } + + /* taking the VMID for that process on the safe way using PDD */ + pdd = kfd_get_process_device_data(dev, p); + if (!pdd) + return -EFAULT; + + status = dbgdev_wave_control_set_registers(&wac_info, ®_sq_cmd, + ®_gfx_index); + if (status != 0) + return -EINVAL; + + /* for non DIQ we need to patch the VMID: */ + reg_sq_cmd.bits.vm_id = vmid; + + dev->kfd2kgd->wave_control_execute(dev->kgd, + reg_gfx_index.u32All, + reg_sq_cmd.u32All); + + return 0; +} + void kfd_dbgdev_init(struct kfd_dbgdev *pdbgdev, struct kfd_dev *pdev, enum DBGDEV_TYPE type) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index b08ec05..547b0a5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -946,6 +946,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, { int retval; enum kfd_preempt_type_filter preempt_type; + struct kfd_process *p; BUG_ON(!dqm); @@ -977,8 +978,13 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr, KFD_FENCE_COMPLETED); /* should be timed out */ - amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, + retval = amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED, QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS); + if (retval != 0) { + p = kfd_get_process(current); + p->reset_wavefronts = true; + goto out; + } pm_release_ib(&dqm->packets); dqm->active_runlist = false; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 39a2cf0..2aa0e49 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -5
[PATCH v3] drm/exynos: calculate vrefresh instead of use a fixed value
Gustavo Padovan wrote: > From: Gustavo Padovan > > When mode's vrefresh is zero we should ask DRM core to calculate vrefresh > for us so we can get the correct value instead of relying on fixed value > defined in a macro. But if vrefresh is still zero we should fail the > update. This works better for me: diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index dc834b8..26e8ae4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -346,11 +346,16 @@ static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc, static void fimd_commit(struct exynos_drm_crtc *crtc) { struct fimd_context *ctx = crtc->ctx; - struct drm_display_mode *mode = &crtc->base.mode; + struct drm_display_mode *mode; struct fimd_driver_data *driver_data = ctx->driver_data; void *timing_base = ctx->regs + driver_data->timing_base; u32 val, clkdiv; + if (crtc->base.state) + mode = &crtc->base.state->adjusted_mode; + else + mode = &crtc->base.mode; + if (ctx->suspended) return; Otherwise I get an oops (nullptr deref) on boot, so 'state' is probably not initialized yet at this point. With best wishes, Tobias Jakobi > > Suggested-by: Daniel Stone > Signed-off-by: Gustavo Padovan > --- > drivers/gpu/drm/exynos/exynos_drm_fimd.c | 7 --- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > index 9819fa6..3f9646d 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > @@ -42,7 +42,6 @@ > * CPU Interface. > */ > > -#define FIMD_DEFAULT_FRAMERATE 60 > #define MIN_FB_WIDTH_FOR_16WORD_BURST 128 > > /* position control register for hardware window 0, 2 ~ 4.*/ > @@ -329,7 +328,9 @@ static bool fimd_mode_fixup(struct exynos_drm_crtc *crtc, > struct drm_display_mode *adjusted_mode) > { > if (adjusted_mode->vrefresh == 0) > - adjusted_mode->vrefresh = FIMD_DEFAULT_FRAMERATE; > + adjusted_mode->vrefresh = drm_mode_vrefresh(mode); > + if (adjusted_mode->vrefresh == 0) > + return false; > > return true; > } > @@ -427,7 +428,7 @@ static void fimd_commit(struct exynos_drm_crtc *crtc) > if (ctx->driver_data->has_clksel) > val |= VIDCON0_CLKSEL_LCD; > > - clkdiv = fimd_calc_clkdiv(ctx, mode); > + clkdiv = fimd_calc_clkdiv(ctx, &crtc->base.state->adjusted_mode); > if (clkdiv > 1) > val |= VIDCON0_CLKVAL_F(clkdiv - 1) | VIDCON0_CLKDIR; > >
[RFC PATCH 00/11] drm/i915: Expose OA metrics via perf PMU
On Tue, May 19, 2015 at 3:53 PM, Peter Zijlstra wrote: > On Fri, May 15, 2015 at 02:07:29AM +0100, Robert Bragg wrote: >> On Fri, May 8, 2015 at 5:24 PM, Peter Zijlstra >> wrote: >> > On Thu, May 07, 2015 at 03:15:43PM +0100, Robert Bragg wrote: >> > >> >> I've changed the uapi for configuring the i915_oa specific attributes >> >> when calling perf_event_open(2) whereby instead of cramming lots of >> >> bitfields into the perf_event_attr config members, I'm now >> >> daisy-chaining a drm_i915_oa_event_attr_t structure off of a single >> >> config member that's extensible and validated in the same way as the >> >> perf_event_attr struct. I've found this much nicer to work with while >> >> being neatly extensible too. >> > >> > This worries me a bit.. is there more background for this? >> >> Would it maybe be helpful to see the before and after? I had kept this >> uapi change in a separate patch for a while locally but in the end >> decided to squash it before sending out my updated series. >> >> Although I did find it a bit awkward with the bitfields, I was mainly >> concerned about the extensibility of packing logically separate >> attributes into the config members and had heard similar concerns from >> a few others who had been experimenting with my patches too. >> >> A few simple attributes I can think of a.t.m that we might want to add >> in the future are: >> - control of the OABUFFER size >> - a way to ask the kernel to collect reports at the beginning and end >> of batch buffers, in addition to periodic reports >> - alternative ways to uniquely identify a context to support tools >> profiling a single context not necessarily owned by the current >> process >> >> It could also be interesting to expose some counter configuration >> through these attributes too. E.g. on Broadwell+ we have 14 'Flexible >> EU' counters included in the OA unit reports, each with a 16bit >> configuration. >> >> In a more extreme case it might also be useful to allow userspace to >> specify a complete counter config, which (depending on the >> configuration) could be over 100 32bit values to select the counter >> signals + configure the corresponding combining logic. >> >> Since this pmu is in a device driver it also seemed reasonably >> appropriate to de-couple it slightly from the core perf_event_attr >> structure by allowing driver extensible attributes. >> >> I wonder if it might be less worrisome if the i915_oa_copy_attr() code >> were instead a re-usable utility perhaps maintained in events/core.c, >> so if other pmu drivers were to follow suite there would be less risk >> of a mistake being made here? > > > So I had a peek at: > > > https://01.org/sites/default/files/documentation/observability_performance_counters_haswell.pdf > > In an attempt to inform myself of how the hardware worked. But the > document is rather sparse (and does not include broadwell). Thanks. Sorry I can't easily fix this myself, but there is work ongoing to update this documentation. In the interim I can try and cover some of the key details here... > > So from what I can gather there's two ways to observe the counters, > through MMIO or trough the ring-buffer, which in turn seems triggered by > a MI_REPORT_PERF_COUNT command. There are three ways; mmio, MI_REPORT_PERF_COUNT via the ring-buffer and periodic sampling where the HW writes into a circular 'oabuffer'. I think it's best to discount mmio as a debug feature since none of the counters are useful in isolation and mmio subverts the latching mechanism we get with the other two methods. We typically at least want to relate a counter to the number of clock cycles elapsed or the gpu time, or thread spawn counts. This pmu driver is primarily for exposing periodic metrics, while it's up to applications to choose to emit MI_REPORT_PERF_COUNT commands as part of their command streams so I think we can mostly ignore MI_REPORT_PERF_COUNT here too. > > [ Now the document talks about shortcomings of this scheme, where the > MI_REPORT_PERF_COUNT command can only be placed every other command, but > a single command can contain so much computation that this is not fine > grained enough -- leading to the suggestion of a timer/cycle based > reporting, but that is not actually mentioned afaict ] It's in there, though unfortunately the documentation isn't very clear currently. The 'Performance Event Counting' section seems to be the appropriate place to introduce the periodic sampling feature, but just reading it myself it really only talks about the limitations of reporting like you say. I'll see if I can prod to get this improved. If you see page 18 "Performance Statistics Registers": OACONTROL has a 'Timer Period' field and 'Timer Enable' OABUFFER points to a circular buffer for periodic reports OASTATUS1/2 contain the head/tail pointers > > Now the MI_REPORT_PERF_COUNT can select a vector (Counter Select) of > which events it will write out. > > This covers the regular 'A' counters.
[PATCH] dma-buf: Minor coding style fixes
- WARNING: Missing a blank line after declarations - WARNING: line over 80 characters - WARNING: please, no space before tabs Signed-off-by: Jagan Teki Cc: Sumit Semwal --- drivers/dma-buf/dma-buf.c | 9 +++-- drivers/dma-buf/reservation.c | 9 ++--- drivers/dma-buf/seqno-fence.c | 8 +++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index c5a9138..30a099c 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -285,6 +285,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) struct reservation_object *resv = exp_info->resv; struct file *file; size_t alloc_size = sizeof(struct dma_buf); + if (!exp_info->resv) alloc_size += sizeof(struct reservation_object); else @@ -545,7 +546,8 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return -EINVAL; if (dmabuf->ops->begin_cpu_access) - ret = dmabuf->ops->begin_cpu_access(dmabuf, start, len, direction); + ret = dmabuf->ops->begin_cpu_access(dmabuf, start, + len, direction); return ret; } @@ -649,7 +651,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap); * @dmabuf:[in]buffer that should back the vma * @vma: [in]vma for the mmap * @pgoff: [in]offset in pages where this mmap should start within the - * dma-buf buffer. + * dma-buf buffer. * * This function adjusts the passed in vma so that it points at the file of the * dma_buf operation. It also adjusts the starting pgoff and does bounds @@ -826,6 +828,7 @@ static int dma_buf_describe(struct seq_file *s) static int dma_buf_show(struct seq_file *s, void *unused) { void (*func)(struct seq_file *) = s->private; + func(s); return 0; } @@ -847,7 +850,9 @@ static struct dentry *dma_buf_debugfs_dir; static int dma_buf_init_debugfs(void) { int err = 0; + dma_buf_debugfs_dir = debugfs_create_dir("dma_buf", NULL); + if (IS_ERR(dma_buf_debugfs_dir)) { err = PTR_ERR(dma_buf_debugfs_dir); dma_buf_debugfs_dir = NULL; diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c index 39920d7..c0bd572 100644 --- a/drivers/dma-buf/reservation.c +++ b/drivers/dma-buf/reservation.c @@ -337,7 +337,8 @@ retry: rcu_read_lock(); if (wait_all) { - struct reservation_object_list *fobj = rcu_dereference(obj->fence); + struct reservation_object_list *fobj = + rcu_dereference(obj->fence); if (fobj) shared_count = fobj->shared_count; @@ -429,7 +430,8 @@ retry: if (test_all) { unsigned i; - struct reservation_object_list *fobj = rcu_dereference(obj->fence); + struct reservation_object_list *fobj = + rcu_dereference(obj->fence); if (fobj) shared_count = fobj->shared_count; @@ -462,7 +464,8 @@ retry: goto unlock_retry; if (fence_excl) { - ret = reservation_object_test_signaled_single(fence_excl); + ret = reservation_object_test_signaled_single( + fence_excl); if (ret < 0) goto unlock_retry; } diff --git a/drivers/dma-buf/seqno-fence.c b/drivers/dma-buf/seqno-fence.c index 7d12a39..71127f8 100644 --- a/drivers/dma-buf/seqno-fence.c +++ b/drivers/dma-buf/seqno-fence.c @@ -24,24 +24,28 @@ static const char *seqno_fence_get_driver_name(struct fence *fence) { struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->get_driver_name(fence); } static const char *seqno_fence_get_timeline_name(struct fence *fence) { struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->get_timeline_name(fence); } static bool seqno_enable_signaling(struct fence *fence) { struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->enable_signaling(fence); } static bool seqno_signaled(struct fence *fence) { struct seqno_fence *seqno_fence = to_seqno_fence(fence); + return seqno_fence->ops->signaled && seqno_fence->ops->signaled(fence); } @@ -56,9 +60,11 @@ static void seqno_release(struct fence *fence) fence_free(&f->base); } -static signed long seqno_wait(struct fence *fence, bool intr, signed long timeout) +static signed long seqno_wait(struct fence *fence, bool intr, + signed long ti
[Bug 90534] integrated LVDS displays stays dark (firmware-linux-nonfree-0.43)
https://bugs.freedesktop.org/show_bug.cgi?id=90534 Michel Dänzer changed: What|Removed |Added Component|Driver/Radeon |DRM/Radeon Assignee|xorg-driver-ati at lists.x.org |dri-devel at lists.freedesktop ||.org Product|xorg|DRI QA Contact|xorg-team at lists.x.org | -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/97495a39/attachment.html>
[Bug 90537] radeonsi bo/va conflict on RADEON_GEM_VA (rscreen->ws->buffer_from_handle returns NULL)
https://bugs.freedesktop.org/show_bug.cgi?id=90537 --- Comment #2 from Michel Dänzer --- Created attachment 115936 --> https://bugs.freedesktop.org/attachment.cgi?id=115936&action=edit winsys/radeon: Unmap VA when destroying BO I think this is most likely because we're not unmapping the virtual address range when closing a GEM handle. Does this Mesa patch help? Note that you'll also need the kernel fixes in 4.0.3, or this patch will likely cause kernel hangs. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/96532308/attachment.html>
[Bug 90523] Easily reproducible GPU lockup (verde) with any mesa 10.5.x
https://bugs.freedesktop.org/show_bug.cgi?id=90523 --- Comment #7 from Michel Dänzer --- (In reply to acab from comment #6) > Yes I could, however upsteam appears to maintain llvm in svn. > There is a git repository as well but it lacks branches and tags. The Git repository at http://llvm.org/git/llvm.git does have the release branches. Also, the SVN revision number is included in the Git commit log, so it's easy to find the Git commit corresponding to a given SVN revision e.g. in gitk. > r214336 | rafael.espindola | 2014-07-30 17:04:00 -0400 (Wed, 30 Jul 2014) | > 9 lines > > SimplifyCFG: Avoid miscompilations due to removed lifetime intrinsics. > > Which appears to match commit 7fef5a3d1907c813712fcb2a44d8187a65ba08cd: > [...] > However mesa 10.5.5 doesn't build against that llvm (doesn't like > TM->getSubtargetImpl()->getInstrInfo() in lp_bld_debug.cpp), but it does > build against 3.5.2. 7fef5a3d1907c813712fcb2a44d8187a65ba08cd is on the master branch. The corresponding commit on the release_35 branch is a4cf325e41fca33c7ce7deef39a7bcf25fb38266. However, as I mentioned before, you most likely will run into more similar issues during the bisection, because Mesa can only test for minor versions of LLVM, not for individual revisions. You may need to tweak the Mesa code to make it build in some cases. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/ace3a7b5/attachment.html>
[Nouveau] [PATCH] ram/gf100-: error out if a ridiculous amount of vram is detected
On 21 May 2015 at 06:01, Ilia Mirkin wrote: > Some newer chips have trouble coming up, and we get bad MMIO reads from > them, like 0xbadf100. This ends up translating into crazy amounts of > VRAM, which destroys all sorts of other logic down the line. Instead, > fail device init. Hrm, I'm not sure what I think of doing something like this. Where do we draw the line at validating stuff we read from GPU registers? Either way, we still have a bug, so I'm not sure what we gain from working around it like this. Ben. > > Signed-off-by: Ilia Mirkin > Cc: stable at kernel.org > --- > drm/nouveau/nvkm/subdev/fb/ramgf100.c | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/drm/nouveau/nvkm/subdev/fb/ramgf100.c > b/drm/nouveau/nvkm/subdev/fb/ramgf100.c > index de9f395..9d4d196 100644 > --- a/drm/nouveau/nvkm/subdev/fb/ramgf100.c > +++ b/drm/nouveau/nvkm/subdev/fb/ramgf100.c > @@ -545,6 +545,12 @@ gf100_ram_create_(struct nvkm_object *parent, struct > nvkm_object *engine, > } > } > > + /* if over 1TB of VRAM is reported, something went very wrong, bail */ > + if (ram->size > (1ULL << 40)) { > + nv_error(pfb, "invalid vram size: %llx\n", ram->size); > + return -EINVAL; > + } > + > /* if all controllers have the same amount attached, there's no holes > */ > if (uniform) { > offset = rsvd_head; > -- > 2.3.6 > > ___ > Nouveau mailing list > Nouveau at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/nouveau
[PATCH 1/2] drm/nouveau: add staging module option
On 20 May 2015 at 15:56, Alexandre Courbot wrote: > Add a module option allowing to enable staging/unstable APIs. This will > allow us to experiment freely with experimental APIs for a while before > setting them in stone. > > Signed-off-by: Alexandre Courbot > --- > drm/nouveau/nouveau_drm.c | 18 ++ > drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ > 2 files changed, 21 insertions(+) > > diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c > index 89049335b738..e4bd6ed51e73 100644 > --- a/drm/nouveau/nouveau_drm.c > +++ b/drm/nouveau/nouveau_drm.c > @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), > optimus only default (-1 > int nouveau_runtime_pm = -1; > module_param_named(runpm, nouveau_runtime_pm, int, 0400); > > +MODULE_PARM_DESC(staging, "enable staging APIs"); > +int nouveau_staging = 0; > +module_param_named(staging, nouveau_staging, int, 0400); > + > static struct drm_driver driver_stub; > static struct drm_driver driver_pci; > static struct drm_driver driver_platform; > @@ -895,6 +899,7 @@ nouveau_ioctls[] = { > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, > DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, > DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, > DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > + /* Staging ioctls */ > }; > > long > @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) > DRM_DEBUG_DRIVER("... runpm: %d\n", nouveau_runtime_pm); > DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); > DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate); > + DRM_DEBUG_DRIVER("... staging : %d\n", nouveau_staging); > } > > static const struct dev_pm_ops nouveau_pm_ops = { > @@ -1088,6 +1094,18 @@ err_free: > static int __init > nouveau_drm_init(void) > { > + /* Do not register staging ioctsl if option not specified */ > + if (!nouveau_staging) { > + unsigned i; > + > + /* This keeps us safe is no staging ioctls are defined */ > + i = min(driver_stub.num_ioctls, DRM_NOUVEAU_STAGING_IOCTL); > + while (!nouveau_ioctls[i - 1].func) > + i--; > + > + driver_stub.num_ioctls = i; > + } Hey Alex, I've got no specific objection. But I'm curious as to why you took this approach as opposed to just adding "if (!nouveau_staging) return -EINVAL;" directly in the experimental ioctls? I think, in line with what's been done in other places, having module options per-api is perhaps a better choice too. Ben. > + > driver_pci = driver_stub; > driver_pci.set_busid = drm_pci_set_busid; > driver_platform = driver_stub; > diff --git a/drm/nouveau/uapi/drm/nouveau_drm.h > b/drm/nouveau/uapi/drm/nouveau_drm.h > index 5507eead5863..4e7e21f41b5c 100644 > --- a/drm/nouveau/uapi/drm/nouveau_drm.h > +++ b/drm/nouveau/uapi/drm/nouveau_drm.h > @@ -140,11 +140,14 @@ struct drm_nouveau_gem_cpu_fini { > #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 > #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 > #define DRM_NOUVEAU_GEM_INFO 0x44 > +/* range 0x98..DRM_COMMAND_END (8 entries) is reserved for staging, unstable > ioctls */ > +#define DRM_NOUVEAU_STAGING_IOCTL 0x58 > > #define DRM_IOCTL_NOUVEAU_GEM_NEWDRM_IOWR(DRM_COMMAND_BASE + > DRM_NOUVEAU_GEM_NEW, struct drm_nouveau_gem_new) > #define DRM_IOCTL_NOUVEAU_GEM_PUSHBUFDRM_IOWR(DRM_COMMAND_BASE + > DRM_NOUVEAU_GEM_PUSHBUF, struct drm_nouveau_gem_pushbuf) > #define DRM_IOCTL_NOUVEAU_GEM_CPU_PREP DRM_IOW (DRM_COMMAND_BASE + > DRM_NOUVEAU_GEM_CPU_PREP, struct drm_nouveau_gem_cpu_prep) > #define DRM_IOCTL_NOUVEAU_GEM_CPU_FINI DRM_IOW (DRM_COMMAND_BASE + > DRM_NOUVEAU_GEM_CPU_FINI, struct drm_nouveau_gem_cpu_fini) > #define DRM_IOCTL_NOUVEAU_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + > DRM_NOUVEAU_GEM_INFO, struct drm_nouveau_gem_info) > +/* staging ioctls */ > > #endif /* __NOUVEAU_DRM_H__ */ > -- > 2.4.0 > > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 1/2] drm: bridge: Allow daisy chaining of bridges
Allow drm_bridge objects to link to each other in order to form an encoder chain. The requirement for creating a chain of bridges comes because the MSM drm driver uses up its encoder and bridge objects for blocks within the SoC itself. There isn't anything left to use if the SoC display output is connected to an external encoder IC. Having an additional bridge connected to the existing bridge helps here. In general, it is possible for platforms to have multiple devices between the encoder and the connector/panel that require some sort of configuration. We create drm bridge helper functions corresponding to each op in 'drm_bridge_funcs'. These helpers call the corresponding 'drm_bridge_funcs' op for the entire chain of bridges. These helpers are used internally by drm_atomic_helper.c and drm_crtc_helper.c. The drm_bridge_enable/pre_enable helpers execute enable/pre_enable ops of the bridge closet to the encoder, and proceed until the last bridge in the chain is enabled. The same holds for drm_bridge_mode_set/mode_fixup helpers. The drm_bridge_disable/post_disable helpers disable the last bridge in the chain first, and proceed until the first bridge in the chain is disabled. drm_bridge_attach() remains the same. As before, the driver calling this function should make sure it has set the links correctly. The order in which the bridges are connected to each other determines the order in which the calls are made. One requirement is that every bridge in the chain should point the parent encoder object. This is required since bridge drivers expect a valid encoder pointer in drm_bridge. For example, consider a chain where an encoder's output is connected to bridge1, and bridge1's output is connected to bridge2: /* Like before, attach bridge to an encoder */ bridge1->encoder = encoder; ret = drm_bridge_attach(dev, bridge1); .. /* * set the first bridge's 'next' bridge to bridge2, set its encoder * as bridge1's encoder */ bridge1->next = bridge2 bridge2->encoder = bridge1->encoder; ret = drm_bridge_attach(dev, bridge2); ... ... This method of bridge chaining isn't intrusive and existing drivers that use drm_bridge will behave the same way as before. The bridge helpers also cleans up the atomic and crtc helper files a bit. Reviewed-by: Jani Nikula Reviewed-by: Rob Clark Reviewed-by: Daniel Vetter Signed-off-by: Archit Taneja --- v4: - Fix up the call sequence for post_disable/pre_enable as suggested by Daniel v3: - Add headerdocs for the new functions v2: - Add EXPORT_SYMBOL for the new functions - Fix logic issue in mode_fixup() drivers/gpu/drm/drm_atomic_helper.c | 29 +++ drivers/gpu/drm/drm_bridge.c| 147 drivers/gpu/drm/drm_crtc_helper.c | 54 + include/drm/drm_crtc.h | 14 4 files changed, 191 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 1d2ca52..d6c85c0 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -281,14 +281,11 @@ mode_fixup(struct drm_atomic_state *state) encoder = conn_state->best_encoder; funcs = encoder->helper_private; - if (encoder->bridge && encoder->bridge->funcs->mode_fixup) { - ret = encoder->bridge->funcs->mode_fixup( - encoder->bridge, &crtc_state->mode, - &crtc_state->adjusted_mode); - if (!ret) { - DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); - return -EINVAL; - } + ret = drm_bridge_mode_fixup(encoder->bridge, &crtc_state->mode, + &crtc_state->adjusted_mode); + if (!ret) { + DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); + return -EINVAL; } if (funcs->atomic_check) { @@ -578,8 +575,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) * Each encoder has at most one connector (since we always steal * it away), so we won't call disable hooks twice. */ - if (encoder->bridge) - encoder->bridge->funcs->disable(encoder->bridge); + drm_bridge_disable(encoder->bridge); /* Right function depends upon target state. */ if (connector->state->crtc && funcs->prepare) @@ -589,8 +585,7 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state) else funcs->dpms(encoder, DRM_MODE_DPMS_OFF); - if (encoder->bridge) - encoder->bridge->funcs->post_disable(e
[PATCH v4 2/2] drm/DocBook: Add more drm_bridge documentation
Add DOC sections giving an overview of drm_bridge and how to fill up the drm_bridge_funcs ops. Add these to drm.tpml in DocBook. Add headerdocs for funcs in drm_bridge.c that don't have them yet. Signed-off-by: Archit Taneja --- Documentation/DocBook/drm.tmpl | 12 ++ drivers/gpu/drm/drm_bridge.c | 94 ++ 2 files changed, 106 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9765a4c..1dc0f45 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2439,6 +2439,18 @@ void intel_crt_init(struct drm_device *dev) Tile group !Pdrivers/gpu/drm/drm_crtc.c Tile group + + Bridges + +Overview +!Pdrivers/gpu/drm/drm_bridge.c overview + + +Default bridge callback sequence +!Pdrivers/gpu/drm/drm_bridge.c bridge callbacks + +!Edrivers/gpu/drm/drm_bridge.c + diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index c3a85ce..a7c4e10 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -28,9 +28,42 @@ #include "drm/drmP.h" +/** + * DOC: overview + * + * drm_bridge represents a device that hangs on to an encoder. These are handy + * when a regular drm_encoder entity isn't enough to represent the entire + * encoder chain. + * + * A bridge is always associated to a single drm_encoder at a time, but can be + * either connected to it directly, or through an intermediate bridge: + * + * encoder ---> bridge B ---> bridge A + * + * Here, the output of the encoder feeds to bridge B, and that furthers feeds to + * bridge A. + * + * The driver using the bridge is responsible to make the associations between + * the encoder and bridges. Once these links are made, the bridges will + * participate along with encoder functions to perform mode_set/enable/disable + * through the ops provided in drm_bridge_funcs. + * + * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes, + * crtcs, encoders or connectors. They just provide additional hooks to get the + * desired output at the end of the encoder chain. + */ + static DEFINE_MUTEX(bridge_lock); static LIST_HEAD(bridge_list); +/** + * drm_bridge_add - add the given bridge to the global bridge list + * + * @bridge: bridge control structure + * + * RETURNS: + * Unconditionally returns Zero. + */ int drm_bridge_add(struct drm_bridge *bridge) { mutex_lock(&bridge_lock); @@ -41,6 +74,11 @@ int drm_bridge_add(struct drm_bridge *bridge) } EXPORT_SYMBOL(drm_bridge_add); +/** + * drm_bridge_remove - remove the given bridge from the global bridge list + * + * @bridge: bridge control structure + */ void drm_bridge_remove(struct drm_bridge *bridge) { mutex_lock(&bridge_lock); @@ -49,6 +87,21 @@ void drm_bridge_remove(struct drm_bridge *bridge) } EXPORT_SYMBOL(drm_bridge_remove); +/** + * drm_bridge_attach - associate given bridge to our DRM device + * + * @dev: DRM device + * @bridge: bridge control structure + * + * called by a kms driver to link one of our encoder/bridge to the given + * bridge. + * + * Note that setting up links between the bridge and our encoder/bridge + * objects needs to be handled by the kms driver itself + * + * RETURNS: + * Zero on success, error code on failure + */ int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) { if (!dev || !bridge) @@ -67,6 +120,38 @@ int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) EXPORT_SYMBOL(drm_bridge_attach); /** + * DOC: bridge callbacks + * + * The drm_bridge_funcs ops are populated by the bridge driver. The drm + * internals(atomic and crtc helpers) use the helpers defined in drm_bridge.c + * These helpers call a specific drm_bridge_funcs op for all the bridges + * during encoder configuration. + * + * When creating a bridge driver, one can implement drm_bridge_funcs op with + * the help of these rough rules: + * + * pre_enable: this contains things needed to be done for the bridge before + * its clock and timings are enabled by its source. For a bridge, its source + * is generally the encoder or bridge just before it in the encoder chain. + * + * enable: this contains things needs to be done for the bridge once its + * source is enabled. In other words, enable is called once the source is + * ready with clock and timing needed by the bridge. + * + * disable: this contains things needed to be done for the bridge assuming + * that its source is still enabled, i.e. clock and timings are still on. + * + * post_disable: this contains things needed to be done for the bridge once + * its source is disabled, i.e. once clocks and timings are off. + * + * mode_fixup: this should fixup the given mode for the bridge. It is called + * after the encoder's mode fixup. + * + * mode_set: this sets up the mode for the bridge. It assumes that its source + * (an encoder or a bridge) has set the mode too
[PATCH 1/2] drm/nouveau: add staging module option
On Thu, May 21, 2015 at 1:48 PM, Ben Skeggs wrote: > On 20 May 2015 at 15:56, Alexandre Courbot wrote: >> Add a module option allowing to enable staging/unstable APIs. This will >> allow us to experiment freely with experimental APIs for a while before >> setting them in stone. >> >> Signed-off-by: Alexandre Courbot >> --- >> drm/nouveau/nouveau_drm.c | 18 ++ >> drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ >> 2 files changed, 21 insertions(+) >> >> diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c >> index 89049335b738..e4bd6ed51e73 100644 >> --- a/drm/nouveau/nouveau_drm.c >> +++ b/drm/nouveau/nouveau_drm.c >> @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), >> optimus only default (-1 >> int nouveau_runtime_pm = -1; >> module_param_named(runpm, nouveau_runtime_pm, int, 0400); >> >> +MODULE_PARM_DESC(staging, "enable staging APIs"); >> +int nouveau_staging = 0; >> +module_param_named(staging, nouveau_staging, int, 0400); >> + >> static struct drm_driver driver_stub; >> static struct drm_driver driver_pci; >> static struct drm_driver driver_platform; >> @@ -895,6 +899,7 @@ nouveau_ioctls[] = { >> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, >> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, >> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, >> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >> + /* Staging ioctls */ >> }; >> >> long >> @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) >> DRM_DEBUG_DRIVER("... runpm: %d\n", nouveau_runtime_pm); >> DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); >> DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate); >> + DRM_DEBUG_DRIVER("... staging : %d\n", nouveau_staging); >> } >> >> static const struct dev_pm_ops nouveau_pm_ops = { >> @@ -1088,6 +1094,18 @@ err_free: >> static int __init >> nouveau_drm_init(void) >> { >> + /* Do not register staging ioctsl if option not specified */ >> + if (!nouveau_staging) { >> + unsigned i; >> + >> + /* This keeps us safe is no staging ioctls are defined */ >> + i = min(driver_stub.num_ioctls, DRM_NOUVEAU_STAGING_IOCTL); >> + while (!nouveau_ioctls[i - 1].func) >> + i--; >> + >> + driver_stub.num_ioctls = i; >> + } > Hey Alex, > > I've got no specific objection. But I'm curious as to why you took > this approach as opposed to just adding "if (!nouveau_staging) return > -EINVAL;" directly in the experimental ioctls? Mainly because we will likely forget to add this check (or to remove it) in some of the staging ioctls. The current solution doesn't require us to think about that - and the less things to think about, the better. > I think, in line with > what's been done in other places, having module options per-api is > perhaps a better choice too. Do you mean that each experimental ioctl should have its own enable option? I don't mind going that way if you think it is preferable. And in that case my comment above is void. But actually I wonder if having these experimental ioctls enabled as compile options (either individually or as a whole) would not be better. Some experimental ioctls may require code in staging (like the PUSHBUF_2 ioctl that I would like to submit next), and I don't think it is desirable to force extra code or kernel options (in this case, CONFIG_STAGING) to Nouveau users who will not make use of them. I remember that we concluded in favor or module options on IRC, but in the light of this, wouldn't a config option be a less intrusive choice?
[PATCH 1/2] drm/nouveau: add staging module option
On 21 May 2015 at 15:49, Alexandre Courbot wrote: > On Thu, May 21, 2015 at 1:48 PM, Ben Skeggs wrote: >> On 20 May 2015 at 15:56, Alexandre Courbot wrote: >>> Add a module option allowing to enable staging/unstable APIs. This will >>> allow us to experiment freely with experimental APIs for a while before >>> setting them in stone. >>> >>> Signed-off-by: Alexandre Courbot >>> --- >>> drm/nouveau/nouveau_drm.c | 18 ++ >>> drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ >>> 2 files changed, 21 insertions(+) >>> >>> diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c >>> index 89049335b738..e4bd6ed51e73 100644 >>> --- a/drm/nouveau/nouveau_drm.c >>> +++ b/drm/nouveau/nouveau_drm.c >>> @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), >>> optimus only default (-1 >>> int nouveau_runtime_pm = -1; >>> module_param_named(runpm, nouveau_runtime_pm, int, 0400); >>> >>> +MODULE_PARM_DESC(staging, "enable staging APIs"); >>> +int nouveau_staging = 0; >>> +module_param_named(staging, nouveau_staging, int, 0400); >>> + >>> static struct drm_driver driver_stub; >>> static struct drm_driver driver_pci; >>> static struct drm_driver driver_platform; >>> @@ -895,6 +899,7 @@ nouveau_ioctls[] = { >>> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, >>> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >>> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, >>> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >>> DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, >>> DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), >>> + /* Staging ioctls */ >>> }; >>> >>> long >>> @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) >>> DRM_DEBUG_DRIVER("... runpm: %d\n", nouveau_runtime_pm); >>> DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); >>> DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate); >>> + DRM_DEBUG_DRIVER("... staging : %d\n", nouveau_staging); >>> } >>> >>> static const struct dev_pm_ops nouveau_pm_ops = { >>> @@ -1088,6 +1094,18 @@ err_free: >>> static int __init >>> nouveau_drm_init(void) >>> { >>> + /* Do not register staging ioctsl if option not specified */ >>> + if (!nouveau_staging) { >>> + unsigned i; >>> + >>> + /* This keeps us safe is no staging ioctls are defined */ >>> + i = min(driver_stub.num_ioctls, DRM_NOUVEAU_STAGING_IOCTL); >>> + while (!nouveau_ioctls[i - 1].func) >>> + i--; >>> + >>> + driver_stub.num_ioctls = i; >>> + } >> Hey Alex, >> >> I've got no specific objection. But I'm curious as to why you took >> this approach as opposed to just adding "if (!nouveau_staging) return >> -EINVAL;" directly in the experimental ioctls? > > Mainly because we will likely forget to add this check (or to remove > it) in some of the staging ioctls. The current solution doesn't > require us to think about that - and the less things to think about, > the better. > >> I think, in line with >> what's been done in other places, having module options per-api is >> perhaps a better choice too. > > Do you mean that each experimental ioctl should have its own enable > option? I don't mind going that way if you think it is preferable. And > in that case my comment above is void. That would be more preferable I think, and obvious as to what exactly you're enabling. > > But actually I wonder if having these experimental ioctls enabled as > compile options (either individually or as a whole) would not be > better. Some experimental ioctls may require code in staging (like the > PUSHBUF_2 ioctl that I would like to submit next), and I don't think > it is desirable to force extra code or kernel options (in this case, > CONFIG_STAGING) to Nouveau users who will not make use of them. I > remember that we concluded in favor or module options on IRC, but in > the light of this, wouldn't a config option be a less intrusive > choice? Right, but the whole point of this is to encourage the ioctls to not live there for too long, and progress to fully supported interfaces. Ben.
[PATCH 1/2] drm/nouveau: add staging module option
On Thu, May 21, 2015 at 2:55 PM, Ben Skeggs wrote: > On 21 May 2015 at 15:49, Alexandre Courbot wrote: >> On Thu, May 21, 2015 at 1:48 PM, Ben Skeggs wrote: >>> On 20 May 2015 at 15:56, Alexandre Courbot wrote: Add a module option allowing to enable staging/unstable APIs. This will allow us to experiment freely with experimental APIs for a while before setting them in stone. Signed-off-by: Alexandre Courbot --- drm/nouveau/nouveau_drm.c | 18 ++ drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c index 89049335b738..e4bd6ed51e73 100644 --- a/drm/nouveau/nouveau_drm.c +++ b/drm/nouveau/nouveau_drm.c @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1 int nouveau_runtime_pm = -1; module_param_named(runpm, nouveau_runtime_pm, int, 0400); +MODULE_PARM_DESC(staging, "enable staging APIs"); +int nouveau_staging = 0; +module_param_named(staging, nouveau_staging, int, 0400); + static struct drm_driver driver_stub; static struct drm_driver driver_pci; static struct drm_driver driver_platform; @@ -895,6 +899,7 @@ nouveau_ioctls[] = { DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), + /* Staging ioctls */ }; long @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) DRM_DEBUG_DRIVER("... runpm: %d\n", nouveau_runtime_pm); DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate); + DRM_DEBUG_DRIVER("... staging : %d\n", nouveau_staging); } static const struct dev_pm_ops nouveau_pm_ops = { @@ -1088,6 +1094,18 @@ err_free: static int __init nouveau_drm_init(void) { + /* Do not register staging ioctsl if option not specified */ + if (!nouveau_staging) { + unsigned i; + + /* This keeps us safe is no staging ioctls are defined */ + i = min(driver_stub.num_ioctls, DRM_NOUVEAU_STAGING_IOCTL); + while (!nouveau_ioctls[i - 1].func) + i--; + + driver_stub.num_ioctls = i; + } >>> Hey Alex, >>> >>> I've got no specific objection. But I'm curious as to why you took >>> this approach as opposed to just adding "if (!nouveau_staging) return >>> -EINVAL;" directly in the experimental ioctls? >> >> Mainly because we will likely forget to add this check (or to remove >> it) in some of the staging ioctls. The current solution doesn't >> require us to think about that - and the less things to think about, >> the better. >> >>> I think, in line with >>> what's been done in other places, having module options per-api is >>> perhaps a better choice too. >> >> Do you mean that each experimental ioctl should have its own enable >> option? I don't mind going that way if you think it is preferable. And >> in that case my comment above is void. > That would be more preferable I think, and obvious as to what exactly > you're enabling. > >> >> But actually I wonder if having these experimental ioctls enabled as >> compile options (either individually or as a whole) would not be >> better. Some experimental ioctls may require code in staging (like the >> PUSHBUF_2 ioctl that I would like to submit next), and I don't think >> it is desirable to force extra code or kernel options (in this case, >> CONFIG_STAGING) to Nouveau users who will not make use of them. I >> remember that we concluded in favor or module options on IRC, but in >> the light of this, wouldn't a config option be a less intrusive >> choice? > Right, but the whole point of this is to encourage the ioctls to not > live there for too long, and progress to fully supported interfaces. Definitely, but my concern is that doing this will make Nouveau depend on STAGING for at least short periods of time. Do we really want this?
[PATCH] dma-buf: Minor coding style fixes
Hi Jagan, On 21 May 2015 at 01:09, Jagan Teki wrote: > - WARNING: Missing a blank line after declarations > - WARNING: line over 80 characters > - WARNING: please, no space before tabs > > Signed-off-by: Jagan Teki > Cc: Sumit Semwal Thanks for the patch; I've queued it up in for-next. Best regards, ~Sumit.
[PATCH v2] nouveau: add coherent BO attribute
Add a flag allowing Nouveau to specify that an object should be coherent at allocation time. This is required for some class of objects like fences which are randomly-accessed by both the CPU and GPU. This flag instructs the kernel driver to make sure the object remains coherent even on architectures for which coherency is not guaranteed by the bus. Signed-off-by: Alexandre Courbot --- Changes since v1: None, just added Martin so he can merge the patch. R-b and A-b wanted. :) include/drm/nouveau_drm.h | 1 + nouveau/abi16.c | 3 +++ nouveau/nouveau.h | 1 + 3 files changed, 5 insertions(+) diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index b18cad02419b..87aefc5e9d2f 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -96,6 +96,7 @@ struct drm_nouveau_setparam { #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) +#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4) #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0xff00 #define NOUVEAU_GEM_TILE_16BPP 0x0001 diff --git a/nouveau/abi16.c b/nouveau/abi16.c index 538f3a730dbe..4ca0bfbaf592 100644 --- a/nouveau/abi16.c +++ b/nouveau/abi16.c @@ -195,6 +195,9 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, if (bo->flags & NOUVEAU_BO_MAP) info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; + if (bo->flags & NOUVEAU_BO_COHERENT) + info->domain |= NOUVEAU_GEM_DOMAIN_COHERENT; + if (!(bo->flags & NOUVEAU_BO_CONTIG)) info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG; diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h index a55e2b020778..4adda0e3594c 100644 --- a/nouveau/nouveau.h +++ b/nouveau/nouveau.h @@ -127,6 +127,7 @@ union nouveau_bo_config { #define NOUVEAU_BO_MAP 0x8000 #define NOUVEAU_BO_CONTIG 0x4000 #define NOUVEAU_BO_NOSNOOP 0x2000 +#define NOUVEAU_BO_COHERENT 0x1000 struct nouveau_bo { struct nouveau_device *device; -- 2.4.0
[PATCH] nouveau: add coherent BO attribute
On Wed, May 20, 2015 at 3:53 PM, Martin Peres wrote: > On 20/05/15 08:11, Alexandre Courbot wrote: >> >> On Fri, May 15, 2015 at 8:39 PM, Maarten Lankhorst >> wrote: >>> >>> Op 15-05-15 om 09:11 schreef Alexandre Courbot: Re-pinging Marteen on an email address that still exists :P On Wed, Apr 22, 2015 at 6:08 PM, Alexandre Courbot wrote: > > On Sun, Mar 15, 2015 at 5:41 PM, Alexandre Courbot > wrote: >> >> On 03/14/2015 04:33 AM, Maarten Lankhorst wrote: >>> >>> Hey, >>> >>> Op 13-03-15 om 07:27 schreef Alexandre Courbot: Add a flag allowing Nouveau to specify that an object should be coherent at allocation time. This is required for some class of objects like fences which are randomly-accessed by both the CPU and GPU. This flag instructs the kernel driver to make sure the object remains coherent even on architectures for which coherency is not guaranteed by the bus. Signed-off-by: Alexandre Courbot >>> >>> I don't see a problem with this patch, but similar patches to intel >>> to >>> libdrm have been shot down when the changes weren't in an official >>> kernel >>> yet, so I think this should wait until the change is at least in >>> drm-next. >>> ;-) >> >> Sounds good. I will ping you again once the kernel change reaches >> -next. > > Hi Marteen, > > The kernel change required for this patch is now in -next. Do you > think we can merge it now? >>> >>> I think it would be ok to merge now. >> >> Great - who could do this? :P > > > I could do it. Please provide me with the patch with the necessary R-b and I > can push it to our libdrm (and/or mesa). Thanks, I just sent a v2 with you included. I have yet to receive formal R-b and A-b for it though.
[Bug 87856] Driver load fails with no error on ppc64 host
https://bugs.freedesktop.org/show_bug.cgi?id=87856 --- Comment #9 from kristof --- Hi Alex, Workaround progress : delete xorg.conf; Why ? According radeon man page : http://manpages.debian.org/cgi-bin/man.cgi?sektion=4&query=radeon&apropos=0&manpath=sid&locale=en Option "AccelMethod" "string" Chooses between available acceleration architectures. Valid values are EXA (for pre-TAHITI GPUs) and glamor (for R300 or higher). The default is glamor as of TAHITI, otherwise EXA. By checking my Xorg.0.log, I realized that "EXA" submodule is loaded instead "glamor" ... (noticed in my workaround firmware non-free installed + mesalib not patched) Since my gpu is a R300 (RV380-X600) family submodule should be "glamor", right or mistake from me due to misunderstanding something ? Regards and have a nice day, Kristof -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/2e373de2/attachment-0001.html>
[PATCH v4 2/2] drm/DocBook: Add more drm_bridge documentation
On Thu, May 21, 2015 at 11:03:17AM +0530, Archit Taneja wrote: > Add DOC sections giving an overview of drm_bridge and how to fill up the > drm_bridge_funcs ops. Add these to drm.tpml in DocBook. > > Add headerdocs for funcs in drm_bridge.c that don't have them yet. > > Signed-off-by: Archit Taneja > --- > Documentation/DocBook/drm.tmpl | 12 ++ > drivers/gpu/drm/drm_bridge.c | 94 > ++ > 2 files changed, 106 insertions(+) > > diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl > index 9765a4c..1dc0f45 100644 > --- a/Documentation/DocBook/drm.tmpl > +++ b/Documentation/DocBook/drm.tmpl > @@ -2439,6 +2439,18 @@ void intel_crt_init(struct drm_device *dev) > Tile group > !Pdrivers/gpu/drm/drm_crtc.c Tile group > > + > + Bridges > + > + Overview > +!Pdrivers/gpu/drm/drm_bridge.c overview > + > + > + Default bridge callback sequence > +!Pdrivers/gpu/drm/drm_bridge.c bridge callbacks > + > +!Edrivers/gpu/drm/drm_bridge.c > + > > > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > index c3a85ce..a7c4e10 100644 > --- a/drivers/gpu/drm/drm_bridge.c > +++ b/drivers/gpu/drm/drm_bridge.c > @@ -28,9 +28,42 @@ > > #include "drm/drmP.h" > > +/** > + * DOC: overview > + * > + * drm_bridge represents a device that hangs on to an encoder. These are > handy > + * when a regular drm_encoder entity isn't enough to represent the entire > + * encoder chain. > + * > + * A bridge is always associated to a single drm_encoder at a time, but can > be > + * either connected to it directly, or through an intermediate bridge: > + * > + * encoder ---> bridge B ---> bridge A > + * > + * Here, the output of the encoder feeds to bridge B, and that furthers > feeds to > + * bridge A. > + * > + * The driver using the bridge is responsible to make the associations > between > + * the encoder and bridges. Once these links are made, the bridges will > + * participate along with encoder functions to perform > mode_set/enable/disable > + * through the ops provided in drm_bridge_funcs. > + * > + * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes, > + * crtcs, encoders or connectors. They just provide additional hooks to get > the > + * desired output at the end of the encoder chain. > + */ > + > static DEFINE_MUTEX(bridge_lock); > static LIST_HEAD(bridge_list); > > +/** > + * drm_bridge_add - add the given bridge to the global bridge list > + * > + * @bridge: bridge control structure > + * > + * RETURNS: > + * Unconditionally returns Zero. > + */ > int drm_bridge_add(struct drm_bridge *bridge) > { > mutex_lock(&bridge_lock); > @@ -41,6 +74,11 @@ int drm_bridge_add(struct drm_bridge *bridge) > } > EXPORT_SYMBOL(drm_bridge_add); > > +/** > + * drm_bridge_remove - remove the given bridge from the global bridge list > + * > + * @bridge: bridge control structure > + */ > void drm_bridge_remove(struct drm_bridge *bridge) > { > mutex_lock(&bridge_lock); > @@ -49,6 +87,21 @@ void drm_bridge_remove(struct drm_bridge *bridge) > } > EXPORT_SYMBOL(drm_bridge_remove); > > +/** > + * drm_bridge_attach - associate given bridge to our DRM device > + * > + * @dev: DRM device > + * @bridge: bridge control structure > + * > + * called by a kms driver to link one of our encoder/bridge to the given > + * bridge. > + * > + * Note that setting up links between the bridge and our encoder/bridge > + * objects needs to be handled by the kms driver itself > + * > + * RETURNS: > + * Zero on success, error code on failure > + */ > int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) > { > if (!dev || !bridge) > @@ -67,6 +120,38 @@ int drm_bridge_attach(struct drm_device *dev, struct > drm_bridge *bridge) > EXPORT_SYMBOL(drm_bridge_attach); > > /** > + * DOC: bridge callbacks > + * > + * The drm_bridge_funcs ops are populated by the bridge driver. The drm > + * internals(atomic and crtc helpers) use the helpers defined in drm_bridge.c > + * These helpers call a specific drm_bridge_funcs op for all the bridges > + * during encoder configuration. > + * > + * When creating a bridge driver, one can implement drm_bridge_funcs op with > + * the help of these rough rules: > + * > + * pre_enable: this contains things needed to be done for the bridge before > + * its clock and timings are enabled by its source. For a bridge, its source > + * is generally the encoder or bridge just before it in the encoder chain. > + * > + * enable: this contains things needs to be done for the bridge once its s/needs/needed/ > + * source is enabled. In other words, enable is called once the source is > + * ready with clock and timing needed by the bridge. > + * > + * disable: this contains things needed to be done for the bridge assuming > + * that its source is still enabled, i.e. clock and timings are still on. > + * > + * post_disabl
[Intel-gfx] [RFC PATCH 00/11] drm/i915: Expose OA metrics via perf PMU
On Thu, May 21, 2015 at 12:17:48AM +0100, Robert Bragg wrote: > On Tue, May 19, 2015 at 3:53 PM, Peter Zijlstra > wrote: > > On Fri, May 15, 2015 at 02:07:29AM +0100, Robert Bragg wrote: > >> On Fri, May 8, 2015 at 5:24 PM, Peter Zijlstra > >> wrote: > >> > On Thu, May 07, 2015 at 03:15:43PM +0100, Robert Bragg wrote: > >> > > >> >> I've changed the uapi for configuring the i915_oa specific attributes > >> >> when calling perf_event_open(2) whereby instead of cramming lots of > >> >> bitfields into the perf_event_attr config members, I'm now > >> >> daisy-chaining a drm_i915_oa_event_attr_t structure off of a single > >> >> config member that's extensible and validated in the same way as the > >> >> perf_event_attr struct. I've found this much nicer to work with while > >> >> being neatly extensible too. > >> > > >> > This worries me a bit.. is there more background for this? > >> > >> Would it maybe be helpful to see the before and after? I had kept this > >> uapi change in a separate patch for a while locally but in the end > >> decided to squash it before sending out my updated series. > >> > >> Although I did find it a bit awkward with the bitfields, I was mainly > >> concerned about the extensibility of packing logically separate > >> attributes into the config members and had heard similar concerns from > >> a few others who had been experimenting with my patches too. > >> > >> A few simple attributes I can think of a.t.m that we might want to add > >> in the future are: > >> - control of the OABUFFER size > >> - a way to ask the kernel to collect reports at the beginning and end > >> of batch buffers, in addition to periodic reports > >> - alternative ways to uniquely identify a context to support tools > >> profiling a single context not necessarily owned by the current > >> process > >> > >> It could also be interesting to expose some counter configuration > >> through these attributes too. E.g. on Broadwell+ we have 14 'Flexible > >> EU' counters included in the OA unit reports, each with a 16bit > >> configuration. > >> > >> In a more extreme case it might also be useful to allow userspace to > >> specify a complete counter config, which (depending on the > >> configuration) could be over 100 32bit values to select the counter > >> signals + configure the corresponding combining logic. > >> > >> Since this pmu is in a device driver it also seemed reasonably > >> appropriate to de-couple it slightly from the core perf_event_attr > >> structure by allowing driver extensible attributes. > >> > >> I wonder if it might be less worrisome if the i915_oa_copy_attr() code > >> were instead a re-usable utility perhaps maintained in events/core.c, > >> so if other pmu drivers were to follow suite there would be less risk > >> of a mistake being made here? > > > > > > So I had a peek at: > > > > > > https://01.org/sites/default/files/documentation/observability_performance_counters_haswell.pdf > > > > In an attempt to inform myself of how the hardware worked. But the > > document is rather sparse (and does not include broadwell). > > Thanks. Sorry I can't easily fix this myself, but there is work > ongoing to update this documentation. In the interim I can try and > cover some of the key details here... Yeah the docs are decidely less than stellar and especially lack examples for how to use the flexible counters properly :( A few additional comments from me below. > > So from what I can gather there's two ways to observe the counters, > > through MMIO or trough the ring-buffer, which in turn seems triggered by > > a MI_REPORT_PERF_COUNT command. > > There are three ways; mmio, MI_REPORT_PERF_COUNT via the ring-buffer > and periodic sampling where the HW writes into a circular 'oabuffer'. > > I think it's best to discount mmio as a debug feature since none of > the counters are useful in isolation and mmio subverts the latching > mechanism we get with the other two methods. We typically at least > want to relate a counter to the number of clock cycles elapsed or the > gpu time, or thread spawn counts. > > This pmu driver is primarily for exposing periodic metrics, while > it's up to applications to choose to emit MI_REPORT_PERF_COUNT > commands as part of their command streams so I think we can mostly > ignore MI_REPORT_PERF_COUNT here too. Yeah this is a crucial bit here - userspace inserts MI_REPORT_PERF_COUNT into the gpu batchbuffer. And the gpu stores the samples at the userspace provided address in the per-process gpu address space. Which means that the kernel never ever sees these samples, nor can it get (efficiently at least) at the target memory. The mid-batchbuffer placement of perf samples is important since wrapping just the entire batch is way too coarse. And timer-based sampling isn't aligned to the different cmds, which means you can't restrict per sampling to e.g. only a specific shader. Right now the gpu doesn't provide any means to restrict sampling except emitting a full pi
[Intel-gfx] [PATCH] drm/edid: Fix DDC probe for passive DP dongles
On Thu, 21 May 2015, Todd Previte wrote: > Passive DP->DVI/HDMI dongles show up to the system as HDMI devices, as they > do not have a sink device in them to respond to any AUX traffic. When > probing these dongles over the DDC, sometimes they will NAK the first attempt > even though the transaction is valid and they support the DDC protocol. The > retry loop inside of drm_do_probe_ddc_edid() would normally catch this case > and try the transaction again, resulting in success. > > That, however, was thwarted by the fix for fdo.org bug #41059. The patch is: > commit 9292f37e1f5c79400254dca46f83313488093825 > Author: Eugeni Dodonov > Date: Thu Jan 5 09:34:28 2012 -0200 > > drm: give up on edid retries when i2c bus is not responding Some extra background: That commit refers to the i2c bit banging code, while i915 now prefers gmbus, and only falls back to big banging on certain failures. (See gmbux_xfer() in i915/intel_i2c.c). This means that in most cases i915 is no longer susceptible to the 5*3 timeout loops, but it also means we don't have the i2c bit banging retry at all on -ENXIO, like Todd notes. The questions are, is one retry after -ENXIO in drm_do_probe_ddc_edid enough now? Should we revert the original commit instead since the underlying algorithm has changed? Or should we return something other than -ENXIO from our gmbus code to not hit this exit with no retries path? > This added code to exit immediately if the return code from the > i2c_transfer function was -ENXIO in order to reduce the amount of time spent > in waiting for unresponsive or disconnected devices. For the DP dongles, > this means that the second retry never happens which results in a failed > EDID probe and a black screen. > > To work around this problem without undoing the fix for bug #41059, the > number of retries is checked along with the return code. This allows for a > device to NAK once and still continue operations. A second NAK will result > in breaking the loop as it would have before and stopping the DDC probe. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924 Maybe throw this at other dongle bugs you can find too? We're going to need Tested-bys though. BR, Jani. > Signed-off-by: Todd Previte > Cc: intel-gfx at lists.freedesktop.org > --- > drivers/gpu/drm/drm_edid.c | 5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > index 7087da3..e8047bd 100644 > --- a/drivers/gpu/drm/drm_edid.c > +++ b/drivers/gpu/drm/drm_edid.c > @@ -1238,7 +1238,10 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned > int block, size_t len) >*/ > ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers); > > - if (ret == -ENXIO) { > + /* Passive DP->DVI/HDMI dongles sometimes NAK the first probe > + * Try to probe again but if it NAKs, stop trying > + */ > + if (ret == -ENXIO && retries < 5) { > DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", > adapter->name); > break; > -- > 1.9.1 > > ___ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Jani Nikula, Intel Open Source Technology Center
drm/atomic: add commit_planes_on_crtc helper
On Wed, May 20, 2015 at 10:43:55PM +0300, Dan Carpenter wrote: > Hello Maarten Lankhorst, > > This is a semi-automatic email about new static checker warnings. > > The patch 32975e952e85: "drm/atomic: add commit_planes_on_crtc > helper" from May 19, 2015, leads to the following Smatch complaint: > > drivers/gpu/drm/drm_atomic_helper.c:1244 > drm_atomic_helper_commit_planes_on_crtc() >error: we previously assumed 'crtc_funcs' could be null (see line 1221) > > drivers/gpu/drm/drm_atomic_helper.c > 1220crtc_funcs = crtc->helper_private; > 1221if (crtc_funcs && crtc_funcs->atomic_begin) > ^^ > Check. > > 1222crtc_funcs->atomic_begin(crtc); > 1223 > 1224drm_for_each_plane_mask(plane, crtc->dev, plane_mask) { > 1225struct drm_plane_state *old_plane_state = > 1226 > drm_atomic_get_existing_plane_state(old_state, plane); > 1227const struct drm_plane_helper_funcs > *plane_funcs; > 1228 > 1229plane_funcs = plane->helper_private; > 1230 > 1231if (!old_plane_state || !plane_funcs) > 1232continue; > 1233 > 1234WARN_ON(plane->state->crtc && > plane->state->crtc != crtc); > 1235 > 1236if (drm_atomic_plane_disabling(plane, > old_plane_state) && > 1237plane_funcs->atomic_disable) > 1238plane_funcs->atomic_disable(plane, > old_plane_state); > 1239else if (plane->state->crtc || > 1240 drm_atomic_plane_disabling(plane, > old_plane_state)) > 1241plane_funcs->atomic_update(plane, > old_plane_state); > 1242} > 1243 > 1244if (crtc_funcs->atomic_flush) > ^^ > Unchecked dereference. Indeed, thanks for the report. I've squashed in a small fixup. -Daniel > > 1245crtc_funcs->atomic_flush(crtc); > 1246} > > regards, > dan carpenter > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH 1/2] drm/nouveau: add staging module option
On 21 May 2015 at 16:04, Alexandre Courbot wrote: > On Thu, May 21, 2015 at 2:55 PM, Ben Skeggs wrote: >> On 21 May 2015 at 15:49, Alexandre Courbot wrote: >>> On Thu, May 21, 2015 at 1:48 PM, Ben Skeggs wrote: On 20 May 2015 at 15:56, Alexandre Courbot wrote: > Add a module option allowing to enable staging/unstable APIs. This will > allow us to experiment freely with experimental APIs for a while before > setting them in stone. > > Signed-off-by: Alexandre Courbot > --- > drm/nouveau/nouveau_drm.c | 18 ++ > drm/nouveau/uapi/drm/nouveau_drm.h | 3 +++ > 2 files changed, 21 insertions(+) > > diff --git a/drm/nouveau/nouveau_drm.c b/drm/nouveau/nouveau_drm.c > index 89049335b738..e4bd6ed51e73 100644 > --- a/drm/nouveau/nouveau_drm.c > +++ b/drm/nouveau/nouveau_drm.c > @@ -75,6 +75,10 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable > (1), optimus only default (-1 > int nouveau_runtime_pm = -1; > module_param_named(runpm, nouveau_runtime_pm, int, 0400); > > +MODULE_PARM_DESC(staging, "enable staging APIs"); > +int nouveau_staging = 0; > +module_param_named(staging, nouveau_staging, int, 0400); > + > static struct drm_driver driver_stub; > static struct drm_driver driver_pci; > static struct drm_driver driver_platform; > @@ -895,6 +899,7 @@ nouveau_ioctls[] = { > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, > nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, > nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, > DRM_UNLOCKED|DRM_AUTH|DRM_RENDER_ALLOW), > + /* Staging ioctls */ > }; > > long > @@ -1027,6 +1032,7 @@ static void nouveau_display_options(void) > DRM_DEBUG_DRIVER("... runpm: %d\n", nouveau_runtime_pm); > DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); > DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate); > + DRM_DEBUG_DRIVER("... staging : %d\n", nouveau_staging); > } > > static const struct dev_pm_ops nouveau_pm_ops = { > @@ -1088,6 +1094,18 @@ err_free: > static int __init > nouveau_drm_init(void) > { > + /* Do not register staging ioctsl if option not specified */ > + if (!nouveau_staging) { > + unsigned i; > + > + /* This keeps us safe is no staging ioctls are defined */ > + i = min(driver_stub.num_ioctls, > DRM_NOUVEAU_STAGING_IOCTL); > + while (!nouveau_ioctls[i - 1].func) > + i--; > + > + driver_stub.num_ioctls = i; > + } Hey Alex, I've got no specific objection. But I'm curious as to why you took this approach as opposed to just adding "if (!nouveau_staging) return -EINVAL;" directly in the experimental ioctls? >>> >>> Mainly because we will likely forget to add this check (or to remove >>> it) in some of the staging ioctls. The current solution doesn't >>> require us to think about that - and the less things to think about, >>> the better. >>> I think, in line with what's been done in other places, having module options per-api is perhaps a better choice too. >>> >>> Do you mean that each experimental ioctl should have its own enable >>> option? I don't mind going that way if you think it is preferable. And >>> in that case my comment above is void. >> That would be more preferable I think, and obvious as to what exactly >> you're enabling. >> >>> >>> But actually I wonder if having these experimental ioctls enabled as >>> compile options (either individually or as a whole) would not be >>> better. Some experimental ioctls may require code in staging (like the >>> PUSHBUF_2 ioctl that I would like to submit next), and I don't think >>> it is desirable to force extra code or kernel options (in this case, >>> CONFIG_STAGING) to Nouveau users who will not make use of them. I >>> remember that we concluded in favor or module options on IRC, but in >>> the light of this, wouldn't a config option be a less intrusive >>> choice? >> Right, but the whole point of this is to encourage the ioctls to not >> live there for too long, and progress to fully supported interfaces. > > Definitely, but my concern is that doing this will make Nouveau depend > on STAGING for at least short periods of time. Do we really want this? I admit to having slightly misread your last paragraph. For cases such as thas, a config option that depends on STAGING *and* the kernel parameter should be used. What is pushbuf2 doing that requires staging btw? You've linked me to patches previously, but I missed that. Ben.
[Nouveau] [PATCH v2] nouveau: add coherent BO attribute
On 21 May 2015 at 16:08, Alexandre Courbot wrote: > Add a flag allowing Nouveau to specify that an object should be coherent > at allocation time. This is required for some class of objects like > fences which are randomly-accessed by both the CPU and GPU. This flag > instructs the kernel driver to make sure the object remains coherent > even on architectures for which coherency is not guaranteed by the bus. > > Signed-off-by: Alexandre Courbot Reviewed-by: Ben Skeggs > --- > Changes since v1: > None, just added Martin so he can merge the patch. R-b and A-b wanted. :) > > include/drm/nouveau_drm.h | 1 + > nouveau/abi16.c | 3 +++ > nouveau/nouveau.h | 1 + > 3 files changed, 5 insertions(+) > > diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h > index b18cad02419b..87aefc5e9d2f 100644 > --- a/include/drm/nouveau_drm.h > +++ b/include/drm/nouveau_drm.h > @@ -96,6 +96,7 @@ struct drm_nouveau_setparam { > #define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1) > #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) > #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) > +#define NOUVEAU_GEM_DOMAIN_COHERENT (1 << 4) > > #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0xff00 > #define NOUVEAU_GEM_TILE_16BPP 0x0001 > diff --git a/nouveau/abi16.c b/nouveau/abi16.c > index 538f3a730dbe..4ca0bfbaf592 100644 > --- a/nouveau/abi16.c > +++ b/nouveau/abi16.c > @@ -195,6 +195,9 @@ abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, > if (bo->flags & NOUVEAU_BO_MAP) > info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; > > + if (bo->flags & NOUVEAU_BO_COHERENT) > + info->domain |= NOUVEAU_GEM_DOMAIN_COHERENT; > + > if (!(bo->flags & NOUVEAU_BO_CONTIG)) > info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG; > > diff --git a/nouveau/nouveau.h b/nouveau/nouveau.h > index a55e2b020778..4adda0e3594c 100644 > --- a/nouveau/nouveau.h > +++ b/nouveau/nouveau.h > @@ -127,6 +127,7 @@ union nouveau_bo_config { > #define NOUVEAU_BO_MAP 0x8000 > #define NOUVEAU_BO_CONTIG 0x4000 > #define NOUVEAU_BO_NOSNOOP 0x2000 > +#define NOUVEAU_BO_COHERENT 0x1000 > > struct nouveau_bo { > struct nouveau_device *device; > -- > 2.4.0 > > ___ > Nouveau mailing list > Nouveau at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/nouveau
[PATCH] drm/vgem: implement virtual GEM
On Thu, Apr 02, 2015 at 10:30:53AM +0200, Thomas Hellstrom wrote: > On 11/25/2014 02:08 AM, Zachary Reizner wrote: > > After looking into removing platform_device, I found that using > > dma_buf_attach with a NULL device always returns an error, thereby > > preventing me from using VGEM for import and mmap. The solution seems > > to be to skip using dma_buf_attach, and instead use dma_buf_mmap when > > user-space tries to mmap a gem object that was imported into VGEM. The > > drawback to this approach is that most drivers stub their > > dma_buf_ops->mmap implementation. Presumably mmap could be implemented > > for the drivers that this would make sense for. Are there any > > comments, questions, or concerns for this proposed solution? > > I see now that this driver has entered -next, and I'm sorry this comment > didn't arrive before. I simply missed this discussion :( > > My biggest concern, as stated many many times before, is that dma-buf > mmap is a horrible interface for incoherent drivers, and for drivers > that use odd format (tiled) dma-bufs, basically since it doesn't supply > a dirtied region. Therefore (correct me if I'm wrong) there has been an > agreement that for purposes outside of ARM SOC, we should simply not > implement dma-buf mmap for other uses than for internal driver use. > > So assume a real driver implements dma-buf mmap, but it is crawling due > to coherency- or untiling / tiling operations. How do you tell a generic > user of the vgem driver *NOT* to mmap for performance reasons? Or is > this driver only intended for ARM SOC systems? Seconded. Somehow I thought we've pulled in vgem to support software rendering like llvmpipe, and I remember that that's been the original justification. TIL that that's indeed not the case and google is splattering their cros tree with dma_buf->mmap implementations this is obviously not the case and the intention really seems to be to use dma_buf->mmap and vgem as the generic interface to expose buffer objects of real drivers to software rendering. Given that neither vgem nor dma_buf->mmap has any sane concept of handling coherency I'm really unhappy about this and tempted to just submit the revert for vgem before 4.1 ships. I'll chat with relevant people a bit more. Worse I chatted with Stephane today and he brushed this off as not-my-problem and if this hurts intel intel should fix this. That's not how a proper usptream interface is getting designd, and coherency handling is an even more serious problem on arm an virtual hw like vmwgfx. On intel (well at least big core thanks to the huge coherent cache fabric) this is mostly a non-issue, except that the patch in the cros tree obviously gets things wrong. Decently pissed tbh. Cheers, Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[Bug 90534] integrated LVDS displays stays dark (firmware-linux-nonfree-0.43)
https://bugs.freedesktop.org/show_bug.cgi?id=90534 --- Comment #10 from Elmar Stellnberger --- Created attachment 115944 --> https://bugs.freedesktop.org/attachment.cgi?id=115944&action=edit dmesg Here comes the dmesg (same parameters as before). Note that I have 1920x1200 also on the console vt01-vt05 so that it apparently ignores the uvesafb.mode_option=1600x1200-24 at 60,mtrr:3,ywrap option (some elder kernels made use of it; I considered it somewhat better readable to have 1600x1200 on the console because then the font size gets larger.). -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/3cdee600/attachment-0001.html>
[PATCH v4 2/2] drm/DocBook: Add more drm_bridge documentation
On Thu, May 21, 2015 at 10:03:38AM +0200, Daniel Vetter wrote: > On Thu, May 21, 2015 at 11:03:17AM +0530, Archit Taneja wrote: > > Add DOC sections giving an overview of drm_bridge and how to fill up the > > drm_bridge_funcs ops. Add these to drm.tpml in DocBook. > > > > Add headerdocs for funcs in drm_bridge.c that don't have them yet. > > > > Signed-off-by: Archit Taneja > > --- > > Documentation/DocBook/drm.tmpl | 12 ++ > > drivers/gpu/drm/drm_bridge.c | 94 > > ++ > > 2 files changed, 106 insertions(+) > > > > diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl > > index 9765a4c..1dc0f45 100644 > > --- a/Documentation/DocBook/drm.tmpl > > +++ b/Documentation/DocBook/drm.tmpl > > @@ -2439,6 +2439,18 @@ void intel_crt_init(struct drm_device *dev) > > Tile group > > !Pdrivers/gpu/drm/drm_crtc.c Tile group > > > > + > > + Bridges > > + > > +Overview > > +!Pdrivers/gpu/drm/drm_bridge.c overview > > + > > + > > +Default bridge callback sequence > > +!Pdrivers/gpu/drm/drm_bridge.c bridge callbacks > > + > > +!Edrivers/gpu/drm/drm_bridge.c > > + > > > > > > > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c > > index c3a85ce..a7c4e10 100644 > > --- a/drivers/gpu/drm/drm_bridge.c > > +++ b/drivers/gpu/drm/drm_bridge.c > > @@ -28,9 +28,42 @@ > > > > #include "drm/drmP.h" > > > > +/** > > + * DOC: overview > > + * > > + * drm_bridge represents a device that hangs on to an encoder. These are > > handy > > + * when a regular drm_encoder entity isn't enough to represent the entire > > + * encoder chain. > > + * > > + * A bridge is always associated to a single drm_encoder at a time, but > > can be > > + * either connected to it directly, or through an intermediate bridge: > > + * > > + * encoder ---> bridge B ---> bridge A > > + * > > + * Here, the output of the encoder feeds to bridge B, and that furthers > > feeds to > > + * bridge A. > > + * > > + * The driver using the bridge is responsible to make the associations > > between > > + * the encoder and bridges. Once these links are made, the bridges will > > + * participate along with encoder functions to perform > > mode_set/enable/disable > > + * through the ops provided in drm_bridge_funcs. > > + * > > + * drm_bridge, like drm_panel, aren't drm_mode_object entities like planes, > > + * crtcs, encoders or connectors. They just provide additional hooks to > > get the > > + * desired output at the end of the encoder chain. > > + */ > > + > > static DEFINE_MUTEX(bridge_lock); > > static LIST_HEAD(bridge_list); > > > > +/** > > + * drm_bridge_add - add the given bridge to the global bridge list > > + * > > + * @bridge: bridge control structure > > + * > > + * RETURNS: > > + * Unconditionally returns Zero. > > + */ > > int drm_bridge_add(struct drm_bridge *bridge) > > { > > mutex_lock(&bridge_lock); > > @@ -41,6 +74,11 @@ int drm_bridge_add(struct drm_bridge *bridge) > > } > > EXPORT_SYMBOL(drm_bridge_add); > > > > +/** > > + * drm_bridge_remove - remove the given bridge from the global bridge list > > + * > > + * @bridge: bridge control structure > > + */ > > void drm_bridge_remove(struct drm_bridge *bridge) > > { > > mutex_lock(&bridge_lock); > > @@ -49,6 +87,21 @@ void drm_bridge_remove(struct drm_bridge *bridge) > > } > > EXPORT_SYMBOL(drm_bridge_remove); > > > > +/** > > + * drm_bridge_attach - associate given bridge to our DRM device > > + * > > + * @dev: DRM device > > + * @bridge: bridge control structure > > + * > > + * called by a kms driver to link one of our encoder/bridge to the given > > + * bridge. > > + * > > + * Note that setting up links between the bridge and our encoder/bridge > > + * objects needs to be handled by the kms driver itself > > + * > > + * RETURNS: > > + * Zero on success, error code on failure > > + */ > > int drm_bridge_attach(struct drm_device *dev, struct drm_bridge *bridge) > > { > > if (!dev || !bridge) > > @@ -67,6 +120,38 @@ int drm_bridge_attach(struct drm_device *dev, struct > > drm_bridge *bridge) > > EXPORT_SYMBOL(drm_bridge_attach); > > > > /** > > + * DOC: bridge callbacks > > + * > > + * The drm_bridge_funcs ops are populated by the bridge driver. The drm > > + * internals(atomic and crtc helpers) use the helpers defined in > > drm_bridge.c > > + * These helpers call a specific drm_bridge_funcs op for all the bridges > > + * during encoder configuration. > > + * > > + * When creating a bridge driver, one can implement drm_bridge_funcs op > > with > > + * the help of these rough rules: > > + * > > + * pre_enable: this contains things needed to be done for the bridge before > > + * its clock and timings are enabled by its source. For a bridge, its > > source > > + * is generally the encoder or bridge just before it in the encoder chain. > > + * > > + * enable: this contains things needs to be done for the b
[Intel-gfx] [PATCH] drm/edid: Fix DDC probe for passive DP dongles
On Thu, May 21, 2015 at 11:28:48AM +0300, Jani Nikula wrote: > On Thu, 21 May 2015, Todd Previte wrote: > > Passive DP->DVI/HDMI dongles show up to the system as HDMI devices, as they > > do not have a sink device in them to respond to any AUX traffic. When > > probing these dongles over the DDC, sometimes they will NAK the first > > attempt > > even though the transaction is valid and they support the DDC protocol. The > > retry loop inside of drm_do_probe_ddc_edid() would normally catch this case > > and try the transaction again, resulting in success. > > > > That, however, was thwarted by the fix for fdo.org bug #41059. The patch is: > > commit 9292f37e1f5c79400254dca46f83313488093825 > > Author: Eugeni Dodonov > > Date: Thu Jan 5 09:34:28 2012 -0200 > > > > drm: give up on edid retries when i2c bus is not responding > > Some extra background: > > That commit refers to the i2c bit banging code, while i915 now prefers > gmbus, and only falls back to big banging on certain failures. (See > gmbux_xfer() in i915/intel_i2c.c). This means that in most cases i915 is > no longer susceptible to the 5*3 timeout loops, but it also means we > don't have the i2c bit banging retry at all on -ENXIO, like Todd notes. > > The questions are, is one retry after -ENXIO in drm_do_probe_ddc_edid > enough now? Should we revert the original commit instead since the > underlying algorithm has changed? Or should we return something other > than -ENXIO from our gmbus code to not hit this exit with no retries > path? Jani&I dug around a bit on this on irc and it looks like a proper i2c implementation should indeed retry on the first ENXIO, except when the I2C_M_IGNORE_NAK flag is set. There's piles of examples how to do it, but it's clear that we've never done this properly in our gmbus driver. Can you please test whether fixing that in intel_i2c.c does resolve the issue too? It would at least explain a lot of the fallback troubles we've had with gmbus and i2c slaves not waking up in time, which all got magically resolved by falling back to the bit-banging interface (which does this retrying already). Thanks, Daniel > > > This added code to exit immediately if the return code from the > > i2c_transfer function was -ENXIO in order to reduce the amount of time spent > > in waiting for unresponsive or disconnected devices. For the DP dongles, > > this means that the second retry never happens which results in a failed > > EDID probe and a black screen. > > > > To work around this problem without undoing the fix for bug #41059, the > > number of retries is checked along with the return code. This allows for a > > device to NAK once and still continue operations. A second NAK will result > > in breaking the loop as it would have before and stopping the DDC probe. > > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924 > > Maybe throw this at other dongle bugs you can find too? > > We're going to need Tested-bys though. > > BR, > Jani. > > > > Signed-off-by: Todd Previte > > Cc: intel-gfx at lists.freedesktop.org > > --- > > drivers/gpu/drm/drm_edid.c | 5 - > > 1 file changed, 4 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c > > index 7087da3..e8047bd 100644 > > --- a/drivers/gpu/drm/drm_edid.c > > +++ b/drivers/gpu/drm/drm_edid.c > > @@ -1238,7 +1238,10 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned > > int block, size_t len) > > */ > > ret = i2c_transfer(adapter, &msgs[3 - xfers], xfers); > > > > - if (ret == -ENXIO) { > > + /* Passive DP->DVI/HDMI dongles sometimes NAK the first probe > > +* Try to probe again but if it NAKs, stop trying > > +*/ > > + if (ret == -ENXIO && retries < 5) { > > DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", > > adapter->name); > > break; > > -- > > 1.9.1 > > > > ___ > > Intel-gfx mailing list > > Intel-gfx at lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/intel-gfx > > -- > Jani Nikula, Intel Open Source Technology Center > ___ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PULL] drm-intel-fixes
Hi Dave, one fix for screen flickering. There's a stable backport from Ander [1] that combines this and a few other commits to fix the flickering on v4.0, reported in [2] among others. Having this upstream is obviously a requirement for stable. BR, Jani. [1] http://mid.gmane.org/1432128754-11840-1-git-send-email-ander.conselvan.de.oliveira at intel.com [2] https://bugzilla.redhat.com/show_bug.cgi?id=1218688 The following changes since commit e26081808edadfd257c6c9d81014e3b25e9a6118: Linux 4.1-rc4 (2015-05-18 10:13:47 -0700) are available in the git repository at: git://anongit.freedesktop.org/drm-intel tags/drm-intel-fixes-2015-05-21 for you to fetch changes up to 54da691deb123c045259ebf4f5c67381244f58f1: drm/i915: fix screen flickering (2015-05-19 10:28:34 +0300) Thomas Gummerer (1): drm/i915: fix screen flickering drivers/gpu/drm/i915/intel_pm.c | 24 +++- 1 file changed, 11 insertions(+), 13 deletions(-) -- Jani Nikula, Intel Open Source Technology Center
[Bug 87856] Driver load fails with no error on ppc64 host
https://bugs.freedesktop.org/show_bug.cgi?id=87856 --- Comment #10 from Alex Deucher --- (In reply to kristof from comment #9) > By checking my Xorg.0.log, I realized that "EXA" submodule is loaded instead > "glamor" ... (noticed in my workaround firmware non-free installed + mesalib > not patched) > Since my gpu is a R300 (RV380-X600) family submodule should be "glamor", > right or mistake from me due to misunderstanding something ? All pre-SI cards use EXA by default. I'm not even sure the r300 cards are capable of using glamor anymore. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/38872d93/attachment.html>
[PATCH libdrm] tegra: Add VIC clear test
This patch adds a simple test for testing Video-Image-Compositor engine on Tegra124 SoC. The test case opens a channel and performs a surface clear. Signed-off-by: Arto Merilainen --- tests/tegra/Makefile.am | 3 +- tests/tegra/host1x.h | 52 ++ tests/tegra/submit_vic.c | 315 +++ tests/tegra/vic.h| 426 +++ 4 files changed, 795 insertions(+), 1 deletion(-) create mode 100644 tests/tegra/host1x.h create mode 100644 tests/tegra/submit_vic.c create mode 100644 tests/tegra/vic.h diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am index 8e625c8fedb8..e3ef60e42039 100644 --- a/tests/tegra/Makefile.am +++ b/tests/tegra/Makefile.am @@ -10,4 +10,5 @@ LDADD = \ ../../libdrm.la noinst_PROGRAMS = \ - openclose + openclose \ + submit_vic diff --git a/tests/tegra/host1x.h b/tests/tegra/host1x.h new file mode 100644 index ..9a72c8e69f85 --- /dev/null +++ b/tests/tegra/host1x.h @@ -0,0 +1,52 @@ +/* + * Copyright © 2015 NVIDIA 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 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 HOST1X_H +#define HOST1X_H + +#include + +enum host1x_class { + HOST1X_CLASS_HOST1X = 0x1, + HOST1X_CLASS_GR2D = 0x51, + HOST1X_CLASS_GR2D_SB = 0x52, + HOST1X_CLASS_VIC = 0x5D, + HOST1X_CLASS_GR3D = 0x60, +}; + +static inline uint32_t host1x_opcode_setclass( + unsigned class_id, unsigned offset, unsigned mask) +{ + return (0 << 28) | (offset << 16) | (class_id << 6) | mask; +} + +static inline uint32_t host1x_opcode_incr(unsigned offset, unsigned count) +{ + return (1 << 28) | (offset << 16) | count; +} + +static inline uint32_t host1x_opcode_nonincr(unsigned offset, unsigned count) +{ + return (2 << 28) | (offset << 16) | count; +} + +#endif diff --git a/tests/tegra/submit_vic.c b/tests/tegra/submit_vic.c new file mode 100644 index ..472fde93a528 --- /dev/null +++ b/tests/tegra/submit_vic.c @@ -0,0 +1,315 @@ +/* + * Copyright © 2015 NVIDIA 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 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include "host1x.h" +#include "vic.h" +#include "xf86drm.h" +#include "tegra.h" + +static const char default_device[] = "/dev/dri/card0"; + +int main(int argc, char *argv[]) +{ + struct drm_tegra_get_syncpt get_syncpt_args; + struct drm_tegra_bo *cmdbuf_bo, *histbuf_bo, *outbuf_bo, + *configbuf_bo; + uint32_t cmdbuf_bo_handle, histbuf_bo_handle, + outbuf_bo_handle, configbuf_bo_handle; + struct drm_tegra_open_channel open_channel_args = {0}; + struct drm_tegra_syncpt submit_syncpt_incr = {0}; + struct drm_tegra_cmdbuf submit_cmdbuf = {0}; + s
[PATCH 0/4] Add VIC support for Tegra124
This series adds Video-Image-Compositor (VIC) support for Tegra124. The unit replaced gr2d engine on T124 and it is effectively used for similar operations: making simple surface copy and fill operations. The series consists of four patches: The first patch fixes an issue in the host1x submit routine which has prevented using same buffer object for multiple command buffers. The second patch makes a simple improvement to the firewall to allow implementing address register validator for VIC. The last two patches in the series make the real modifications to Tegra DRM and device tree to enable the engine on T124. The series has been tested on Jetson TK1 by first disabling IOMMU (*), enabling CMA and running a VIC clear test case that is posted to dri-devel and linux-tegra mailing lists. The firmware image for VIC is publicly available as part of Linux For Tegra driver package [0]. [0] https://developer.nvidia.com/linux-tegra (*) Currently Tegra DRM does not support mapping the host1x command buffers into kernel address space in case IOMMU is enabled. Arto Merilainen (4): host1x: Store device address to all bufs host1x: Pass register value in firewall drm/tegra: Add VIC support ARM: tegra: Add VIC for Tegra124 arch/arm/boot/dts/tegra124.dtsi | 11 + drivers/gpu/drm/tegra/Makefile | 3 +- drivers/gpu/drm/tegra/drm.c | 9 +- drivers/gpu/drm/tegra/drm.h | 5 +- drivers/gpu/drm/tegra/gr2d.c| 4 +- drivers/gpu/drm/tegra/gr3d.c| 4 +- drivers/gpu/drm/tegra/vic.c | 593 drivers/gpu/drm/tegra/vic.h | 116 drivers/gpu/host1x/job.c| 44 ++- include/linux/host1x.h | 5 +- 10 files changed, 769 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/tegra/vic.c create mode 100644 drivers/gpu/drm/tegra/vic.h -- 1.8.1.5
[PATCH 1/4] host1x: Store device address to all bufs
Currently job pinning is optimized to handle only the first buffer using a certain host1x_bo object and all subsequent buffers using the same host1x_bo are considered done. In most cases this is correct, however, in case the same host1x_bo is used in multiple gathers inside the same job, we skip also storing the device address (physical or iova) to this buffer. This patch reworks the host1x_job_pin() to store the device address to all gathers. Signed-off-by: Andrew Chew Signed-off-by: Arto Merilainen --- drivers/gpu/host1x/job.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index 63bd63f3c7df..b72aa918fa69 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -1,7 +1,7 @@ /* * Tegra host1x Job * - * Copyright (c) 2010-2013, NVIDIA Corporation. + * Copyright (c) 2010-2015, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -538,9 +538,12 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) g->base = job->gather_addr_phys[i]; - for (j = i + 1; j < job->num_gathers; j++) - if (job->gathers[j].bo == g->bo) + for (j = i + 1; j < job->num_gathers; j++) { + if (job->gathers[j].bo == g->bo) { job->gathers[j].handled = true; + job->gathers[j].base = g->base; + } + } err = do_relocs(job, g->bo); if (err) -- 1.8.1.5
[PATCH 2/4] host1x: Pass register value in firewall
In gr2d and gr3d units the register offset was sufficient for determining if the register in interest is used for storing a register value. However, in VIC this is not the case. The operations are passed through two registers, METHOD0 and METHOD1. Depending on content of METHOD0, METHOD1 can be either address or data field. This patch updates the firewall interface to deliver also the register value to allow book-keeping inside the engine driver. Signed-off-by: Arto Merilainen --- drivers/gpu/drm/tegra/drm.h | 4 ++-- drivers/gpu/drm/tegra/gr2d.c | 4 ++-- drivers/gpu/drm/tegra/gr3d.c | 4 ++-- drivers/gpu/host1x/job.c | 35 +++ include/linux/host1x.h | 4 ++-- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 659b2fcc986d..0e7756e720c5 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 Avionic Design GmbH - * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2012-2015 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -70,7 +70,7 @@ struct tegra_drm_client_ops { int (*open_channel)(struct tegra_drm_client *client, struct tegra_drm_context *context); void (*close_channel)(struct tegra_drm_context *context); - int (*is_addr_reg)(struct device *dev, u32 class, u32 offset); + int (*is_addr_reg)(struct device *dev, u32 class, u32 offset, u32 val); int (*submit)(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file); diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index 02cd3e37a6ec..7e4424f15cdf 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013, NVIDIA Corporation. + * Copyright (c) 2012-2015, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -84,7 +84,7 @@ static void gr2d_close_channel(struct tegra_drm_context *context) host1x_channel_put(context->channel); } -static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset) +static int gr2d_is_addr_reg(struct device *dev, u32 class, u32 offset, u32 val) { struct gr2d *gr2d = dev_get_drvdata(dev); diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 0b3f2b977ba0..9ceaf35a856b 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Avionic Design GmbH - * Copyright (C) 2013 NVIDIA Corporation + * Copyright (C) 2013-2015 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -94,7 +94,7 @@ static void gr3d_close_channel(struct tegra_drm_context *context) host1x_channel_put(context->channel); } -static int gr3d_is_addr_reg(struct device *dev, u32 class, u32 offset) +static int gr3d_is_addr_reg(struct device *dev, u32 class, u32 offset, u32 val) { struct gr3d *gr3d = dev_get_drvdata(dev); diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index b72aa918fa69..77d977bbf922 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c @@ -295,9 +295,10 @@ struct host1x_firewall { u32 count; }; -static int check_register(struct host1x_firewall *fw, unsigned long offset) +static int check_register(struct host1x_firewall *fw, + unsigned long offset, u32 val) { - if (fw->job->is_addr_reg(fw->dev, fw->class, offset)) { + if (fw->job->is_addr_reg(fw->dev, fw->class, offset, val)) { if (!fw->num_relocs) return -EINVAL; @@ -311,18 +312,21 @@ static int check_register(struct host1x_firewall *fw, unsigned long offset) return 0; } -static int check_mask(struct host1x_firewall *fw) +static int check_mask(struct host1x_firewall *fw, struct host1x_job_gather *g) { + u32 *cmdbuf_base = (u32 *)fw->job->gather_copy_mapped + + (g->offset / sizeof(u32)); u32 mask = fw->mask; u32 reg = fw->reg; int ret; while (mask) { + u32 val = cmdbuf_base[fw->offset]; if (fw->words == 0) return -EINVAL; if (mask & 1) { - ret = check_register(fw, reg); + ret = check_register(fw, reg, val); if (ret < 0) return ret; @@ -336,17 +340,20 @@ static int check_mask(struct host1
[PATCH 3/4] drm/tegra: Add VIC support
This patch adds support for Video Image Compositor engine which can be used for 2d operations. The engine has a microcontroller (Falcon) that acts as a frontend for the rest of the unit. In order to properly utilize the engine, the frontend must be booted before pushing any commands. Signed-off-by: Andrew Chew Signed-off-by: Arto Merilainen --- drivers/gpu/drm/tegra/Makefile | 3 +- drivers/gpu/drm/tegra/drm.c| 9 +- drivers/gpu/drm/tegra/drm.h| 1 + drivers/gpu/drm/tegra/vic.c| 593 + drivers/gpu/drm/tegra/vic.h| 116 include/linux/host1x.h | 1 + 6 files changed, 721 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/tegra/vic.c create mode 100644 drivers/gpu/drm/tegra/vic.h diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile index 2c66a8db9da4..3bc3566e00b6 100644 --- a/drivers/gpu/drm/tegra/Makefile +++ b/drivers/gpu/drm/tegra/Makefile @@ -13,6 +13,7 @@ tegra-drm-y := \ sor.o \ dpaux.o \ gr2d.o \ - gr3d.o + gr3d.o \ + vic.o obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index bfad15a913a0..d947f5f4d801 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 Avionic Design GmbH - * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. + * Copyright (C) 2012-2015 NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -1048,6 +1048,7 @@ static const struct of_device_id host1x_drm_subdevs[] = { { .compatible = "nvidia,tegra124-dc", }, { .compatible = "nvidia,tegra124-sor", }, { .compatible = "nvidia,tegra124-hdmi", }, + { .compatible = "nvidia,tegra124-vic", }, { /* sentinel */ } }; @@ -1097,8 +1098,14 @@ static int __init host1x_drm_init(void) if (err < 0) goto unregister_gr2d; + err = platform_driver_register(&tegra_vic_driver); + if (err < 0) + goto unregister_gr3d; + return 0; +unregister_gr3d: + platform_driver_unregister(&tegra_gr3d_driver); unregister_gr2d: platform_driver_unregister(&tegra_gr2d_driver); unregister_dpaux: diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h index 0e7756e720c5..a9c02a80d6bf 100644 --- a/drivers/gpu/drm/tegra/drm.h +++ b/drivers/gpu/drm/tegra/drm.h @@ -275,5 +275,6 @@ extern struct platform_driver tegra_hdmi_driver; extern struct platform_driver tegra_dpaux_driver; extern struct platform_driver tegra_gr2d_driver; extern struct platform_driver tegra_gr3d_driver; +extern struct platform_driver tegra_vic_driver; #endif /* HOST1X_DRM_H */ diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c new file mode 100644 index ..b7c5a96697ed --- /dev/null +++ b/drivers/gpu/drm/tegra/vic.c @@ -0,0 +1,593 @@ +/* + * Copyright (c) 2015, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drm.h" +#include "gem.h" +#include "vic.h" + +#define VIC_IDLE_TIMEOUT_DEFAULT 1 /* 10 milliseconds */ +#define VIC_IDLE_CHECK_PERIOD 10 /* 10 usec */ + +struct vic; + +struct vic_config { + /* firmware name */ + char *ucode_name; + + /* class id */ + u32 class_id; + + /* powergate id */ + int powergate_id; +}; + +struct vic { + struct { + u32 bin_data_offset; + u32 data_offset; + u32 data_size; + u32 code_offset; + u32 size; + } os, fce; + + struct tegra_bo *ucode_bo; + bool ucode_valid; + void *ucode_vaddr; + + bool booted; + + void __iomem *regs; + struct tegra_drm_client client; + struct host1x_channel *channel; + struct iommu_domain *domain; + struct device *dev; + struct clk *clk; + struct reset_control *rst; + + /* Platform configuration */ + struct vic_config *config; + + /* for firewall - this determines if method 1 should be regarded +* as an address register */ + bool method_data_is_addr_reg; +}; + +static inline struct vic *to_vic(struct tegra_drm_client *client) +{ + return container_of(client, struct vic, client); +} + +void vic_writel(struct vic *vic, u32 v, u32 r) +{ + writel(v, vic->regs + r); +} + +u32 vic_readl(struct vic *vic, u32 r) +{ + return readl(vic->regs + r); +} + +static int vic_wait_idle(struct vic *vic) +{ + u
[PATCH 4/4] ARM: tegra: Add VIC for Tegra124
This patch adds VIC device tree node for Video Image Compositor. Signed-off-by: Arto Merilainen --- arch/arm/boot/dts/tegra124.dtsi | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 13cc7ca5e031..626355693a41 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -136,6 +136,17 @@ status = "disabled"; }; + vic at 5434 { + compatible = "nvidia,tegra124-vic"; + reg = <0x0 0x5434 0x0 0x0004>; + clocks = <&tegra_car TEGRA124_CLK_VIC03>; + clock-names = "vic03"; + resets = <&tegra_car TEGRA124_CLK_VIC03>; + reset-names = "vic03"; + + iommus = <&mc TEGRA_SWGROUP_VIC>; + }; + sor at 0,5454 { compatible = "nvidia,tegra124-sor"; reg = <0x0 0x5454 0x0 0x0004>; -- 1.8.1.5
[PATCH] drm/vgem: implement virtual GEM
On 05/21/2015 11:13 AM, Daniel Vetter wrote: > On Thu, Apr 02, 2015 at 10:30:53AM +0200, Thomas Hellstrom wrote: >> On 11/25/2014 02:08 AM, Zachary Reizner wrote: >>> After looking into removing platform_device, I found that using >>> dma_buf_attach with a NULL device always returns an error, thereby >>> preventing me from using VGEM for import and mmap. The solution seems >>> to be to skip using dma_buf_attach, and instead use dma_buf_mmap when >>> user-space tries to mmap a gem object that was imported into VGEM. The >>> drawback to this approach is that most drivers stub their >>> dma_buf_ops->mmap implementation. Presumably mmap could be implemented >>> for the drivers that this would make sense for. Are there any >>> comments, questions, or concerns for this proposed solution? >> I see now that this driver has entered -next, and I'm sorry this comment >> didn't arrive before. I simply missed this discussion :( >> >> My biggest concern, as stated many many times before, is that dma-buf >> mmap is a horrible interface for incoherent drivers, and for drivers >> that use odd format (tiled) dma-bufs, basically since it doesn't supply >> a dirtied region. Therefore (correct me if I'm wrong) there has been an >> agreement that for purposes outside of ARM SOC, we should simply not >> implement dma-buf mmap for other uses than for internal driver use. >> >> So assume a real driver implements dma-buf mmap, but it is crawling due >> to coherency- or untiling / tiling operations. How do you tell a generic >> user of the vgem driver *NOT* to mmap for performance reasons? Or is >> this driver only intended for ARM SOC systems? > Seconded. Somehow I thought we've pulled in vgem to support software > rendering like llvmpipe, and I remember that that's been the original > justification. TIL that that's indeed not the case and google is > splattering their cros tree with dma_buf->mmap implementations this is > obviously not the case and the intention really seems to be to use > dma_buf->mmap and vgem as the generic interface to expose buffer objects > of real drivers to software rendering. > > Given that neither vgem nor dma_buf->mmap has any sane concept of handling > coherency I'm really unhappy about this and tempted to just submit the > revert for vgem before 4.1 ships. I'll chat with relevant people a bit > more. Worse I chatted with Stephane today and he brushed this off as > not-my-problem and if this hurts intel intel should fix this. That's not > how a proper usptream interface is getting designd, and coherency handling > is an even more serious problem on arm an virtual hw like vmwgfx. So given how this has turned out, my opinion is that before a usable generic mmap of accelerated buffer objects goes upstream, there should be a proper interface to request regions present and to dirty regions. It seems to me that so far all use-cases are for one- or two-dimensional access so it should be sufficient to start with that and add other access modes later on. Now this is no guarantee that people won't request and dirty the whole dma-buf on each access, but at least that would make people think, and if things become slow it's pretty clear where the problem is. I'm all for delaying vgem until we have such an interface in place. Thanks, Thomas > On intel > (well at least big core thanks to the huge coherent cache fabric) this is > mostly a non-issue, except that the patch in the cros tree obviously gets > things wrong. > > Decently pissed tbh. > > Cheers, Daniel
[PATCH v3] drm/exynos: calculate vrefresh instead of use a fixed value
Hi Tobias, 2015-05-21 Tobias Jakobi : > Gustavo Padovan wrote: > > From: Gustavo Padovan > > > > When mode's vrefresh is zero we should ask DRM core to calculate vrefresh > > for us so we can get the correct value instead of relying on fixed value > > defined in a macro. But if vrefresh is still zero we should fail the > > update. > This works better for me: > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > index dc834b8..26e8ae4 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c > @@ -346,11 +346,16 @@ static bool fimd_mode_fixup(struct exynos_drm_crtc > *crtc, > static void fimd_commit(struct exynos_drm_crtc *crtc) > { > struct fimd_context *ctx = crtc->ctx; > - struct drm_display_mode *mode = &crtc->base.mode; > + struct drm_display_mode *mode; > struct fimd_driver_data *driver_data = ctx->driver_data; > void *timing_base = ctx->regs + driver_data->timing_base; > u32 val, clkdiv; > > + if (crtc->base.state) > + mode = &crtc->base.state->adjusted_mode; > + else > + mode = &crtc->base.mode; > + > if (ctx->suspended) > return; > > Otherwise I get an oops (nullptr deref) on boot, so 'state' is probably > not initialized yet at this point. Would you like to send a proper git patch of this? You can move the drm_mode_vrefresh() part to your patch. Gustavo
[Intel-gfx] [PATCH] drm/plane-helper: Adapt cursor hack to transitional helpers
On 05/20/2015 10:36 AM, Daniel Vetter wrote: > In > > commit f02ad907cd9e7fe3a6405d2d005840912f1ed258 > Author: Daniel Vetter > Date: Thu Jan 22 16:36:23 2015 +0100 > > drm/atomic-helpers: Recover full cursor plane behaviour > > we've added a hack to atomic helpers to never to vblank waits for > cursor updates through the legacy apis since that's what X expects. > Unfortunately we've (again) forgotten to adjust the transitional > helpers. Do this now. > > This fixes regressions for drivers only partially converted over to > atomic (like i915). > > Reported-by: Pekka Paalanen > Cc: Pekka Paalanen > Cc: stable at vger.kernel.org > Signed-off-by: Daniel Vetter > --- > drivers/gpu/drm/drm_plane_helper.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/gpu/drm/drm_plane_helper.c > b/drivers/gpu/drm/drm_plane_helper.c > index 40c1db9ad7c3..2f0ed11024eb 100644 > --- a/drivers/gpu/drm/drm_plane_helper.c > +++ b/drivers/gpu/drm/drm_plane_helper.c > @@ -465,6 +465,9 @@ int drm_plane_helper_commit(struct drm_plane *plane, > if (!crtc[i]) > continue; > > + if (crtc[i]->cursor == plane) > + continue; > + > /* There's no other way to figure out whether the crtc is > running. */ > ret = drm_crtc_vblank_get(crtc[i]); > if (ret == 0) { > This one is Reviewed-and-tested-by: Mario Kleiner I was looking into Weston performance and the cursor problem, so had necessary tracing in place to test this. I can confirm that cursor related blocking in Westons drm-backend execution are gone with this patch applied, whereas they are still present when using hardware overlays on Intel, as expected. So hardware cursors should be fine again, once the patch also ends in stable kernels. thanks, -mario
[PATCH] drm/vgem: implement virtual GEM
On Thu, May 21, 2015 at 9:49 AM, Thomas Hellstrom wrote: > On 05/21/2015 11:13 AM, Daniel Vetter wrote: >> On Thu, Apr 02, 2015 at 10:30:53AM +0200, Thomas Hellstrom wrote: >>> On 11/25/2014 02:08 AM, Zachary Reizner wrote: After looking into removing platform_device, I found that using dma_buf_attach with a NULL device always returns an error, thereby preventing me from using VGEM for import and mmap. The solution seems to be to skip using dma_buf_attach, and instead use dma_buf_mmap when user-space tries to mmap a gem object that was imported into VGEM. The drawback to this approach is that most drivers stub their dma_buf_ops->mmap implementation. Presumably mmap could be implemented for the drivers that this would make sense for. Are there any comments, questions, or concerns for this proposed solution? >>> I see now that this driver has entered -next, and I'm sorry this comment >>> didn't arrive before. I simply missed this discussion :( >>> >>> My biggest concern, as stated many many times before, is that dma-buf >>> mmap is a horrible interface for incoherent drivers, and for drivers >>> that use odd format (tiled) dma-bufs, basically since it doesn't supply >>> a dirtied region. Therefore (correct me if I'm wrong) there has been an >>> agreement that for purposes outside of ARM SOC, we should simply not >>> implement dma-buf mmap for other uses than for internal driver use. >>> >>> So assume a real driver implements dma-buf mmap, but it is crawling due >>> to coherency- or untiling / tiling operations. How do you tell a generic >>> user of the vgem driver *NOT* to mmap for performance reasons? Or is >>> this driver only intended for ARM SOC systems? >> Seconded. Somehow I thought we've pulled in vgem to support software >> rendering like llvmpipe, and I remember that that's been the original >> justification. TIL that that's indeed not the case and google is >> splattering their cros tree with dma_buf->mmap implementations this is >> obviously not the case and the intention really seems to be to use >> dma_buf->mmap and vgem as the generic interface to expose buffer objects >> of real drivers to software rendering. >> >> Given that neither vgem nor dma_buf->mmap has any sane concept of handling >> coherency I'm really unhappy about this and tempted to just submit the >> revert for vgem before 4.1 ships. I'll chat with relevant people a bit >> more. Worse I chatted with Stephane today and he brushed this off as >> not-my-problem and if this hurts intel intel should fix this. That's not >> how a proper usptream interface is getting designd, and coherency handling >> is an even more serious problem on arm an virtual hw like vmwgfx. > > So given how this has turned out, my opinion is that before a usable > generic mmap of accelerated buffer objects > goes upstream, there should be a proper interface to request regions > present and to dirty regions. It seems to me that so far > all use-cases are for one- or two-dimensional access so it should be > sufficient to start with that and add other access > modes later on. Now this is no guarantee that people won't request and > dirty the whole dma-buf on each access, but at least > that would make people think, and if things become slow it's pretty > clear where the problem is. > > I'm all for delaying vgem until we have such an interface in place. so, for llvmpipe use-case, I think dri2 is sufficient. So why don't we just drop DRIVER_PRIME flag for now.. BR, -R > Thanks, > Thomas > > > > >> On intel >> (well at least big core thanks to the huge coherent cache fabric) this is >> mostly a non-issue, except that the patch in the cros tree obviously gets >> things wrong. >> >> Decently pissed tbh. >> >> Cheers, Daniel > > ___ > dri-devel mailing list > dri-devel at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH] drm/vgem: implement virtual GEM
On 05/21/2015 04:19 PM, Rob Clark wrote: > On Thu, May 21, 2015 at 9:49 AM, Thomas Hellstrom > wrote: >> On 05/21/2015 11:13 AM, Daniel Vetter wrote: >>> On Thu, Apr 02, 2015 at 10:30:53AM +0200, Thomas Hellstrom wrote: On 11/25/2014 02:08 AM, Zachary Reizner wrote: > After looking into removing platform_device, I found that using > dma_buf_attach with a NULL device always returns an error, thereby > preventing me from using VGEM for import and mmap. The solution seems > to be to skip using dma_buf_attach, and instead use dma_buf_mmap when > user-space tries to mmap a gem object that was imported into VGEM. The > drawback to this approach is that most drivers stub their > dma_buf_ops->mmap implementation. Presumably mmap could be implemented > for the drivers that this would make sense for. Are there any > comments, questions, or concerns for this proposed solution? I see now that this driver has entered -next, and I'm sorry this comment didn't arrive before. I simply missed this discussion :( My biggest concern, as stated many many times before, is that dma-buf mmap is a horrible interface for incoherent drivers, and for drivers that use odd format (tiled) dma-bufs, basically since it doesn't supply a dirtied region. Therefore (correct me if I'm wrong) there has been an agreement that for purposes outside of ARM SOC, we should simply not implement dma-buf mmap for other uses than for internal driver use. So assume a real driver implements dma-buf mmap, but it is crawling due to coherency- or untiling / tiling operations. How do you tell a generic user of the vgem driver *NOT* to mmap for performance reasons? Or is this driver only intended for ARM SOC systems? >>> Seconded. Somehow I thought we've pulled in vgem to support software >>> rendering like llvmpipe, and I remember that that's been the original >>> justification. TIL that that's indeed not the case and google is >>> splattering their cros tree with dma_buf->mmap implementations this is >>> obviously not the case and the intention really seems to be to use >>> dma_buf->mmap and vgem as the generic interface to expose buffer objects >>> of real drivers to software rendering. >>> >>> Given that neither vgem nor dma_buf->mmap has any sane concept of handling >>> coherency I'm really unhappy about this and tempted to just submit the >>> revert for vgem before 4.1 ships. I'll chat with relevant people a bit >>> more. Worse I chatted with Stephane today and he brushed this off as >>> not-my-problem and if this hurts intel intel should fix this. That's not >>> how a proper usptream interface is getting designd, and coherency handling >>> is an even more serious problem on arm an virtual hw like vmwgfx. >> So given how this has turned out, my opinion is that before a usable >> generic mmap of accelerated buffer objects >> goes upstream, there should be a proper interface to request regions >> present and to dirty regions. It seems to me that so far >> all use-cases are for one- or two-dimensional access so it should be >> sufficient to start with that and add other access >> modes later on. Now this is no guarantee that people won't request and >> dirty the whole dma-buf on each access, but at least >> that would make people think, and if things become slow it's pretty >> clear where the problem is. >> >> I'm all for delaying vgem until we have such an interface in place. > so, for llvmpipe use-case, I think dri2 is sufficient. So why don't > we just drop DRIVER_PRIME flag for now.. > > BR, > -R Fine with me! /Thomas > >> Thanks, >> Thomas >> >> >> >> >>> On intel >>> (well at least big core thanks to the huge coherent cache fabric) this is >>> mostly a non-issue, except that the patch in the cros tree obviously gets >>> things wrong. >>> >>> Decently pissed tbh. >>> >>> Cheers, Daniel >> ___ >> dri-devel mailing list >> dri-devel at lists.freedesktop.org >> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_mailman_listinfo_dri-2Ddevel&d=AwIBaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=vpukPkBtpoNQp2IUKuFviOmPNYWVKmen3Jeeu55zmEA&m=sLK_B5IzlsF7zUqLCrxPQUtxzZt77RtzKxrZaJGYews&s=tfXDNoFQ1d044YyOewiTg_Qa0gsSvjOZGT603lZtZVo&e= >>
[PATCH] Revert "drm/vgem: implement virtual GEM"
This reverts commit 502e95c6678505474f1056480310cd9382bacbac. Originally vgem was just to have a drm driver for software-only renders like llvmpipe so that they integrate more nicely with the existing compositor protocols like DRI2/3. Later on Ben extended it to serve as a dma-buf import/export test vehicle for debugging. Both of these use-cases imo make sense and are on the level of just yet another (virtual) drm driver. But only just I realized that Google's CrOS plans with vgem are much more pervasive - the plan seems to be to use it as the generic software mmap path on top of any kind of hw driver buffer objects from the underlying SoC gfx hw. That means vgem is now common infrastructre which should work for all drivers and properly interact with them, and from that point-of-view it definitely falls short on three accounts: - It directly forwards the current dma-buf ->mmap model, and the consensus for that has always been that it's a toy one at best useful for debugging or super-unlikely fallbacks. Originally it was added mostly as a concession to get people on top of the dma-buf train since Ion has this too. For proper mmap support we really need some software begin/end signals, probably best in the form of a set of ioctls on the dma-buf fd that forward to the already existing ->begin/end_cpu_access hooks. Not exposing this and not requiring userspace to use them puts a serious burden on any kind of driver that needs to occasionally handle a bit of coherency troubles. Which includes anything on ARM and even more so more fancy stuff like virtual hardware. Furthermore the vgem mmap interface doesn't expose any begin/end ioctls either, which means we can't even use the existing dma-buf hooks properly and fix this up in vgem. - vgem uses the dumb buffer api to expose the the mmap support. Generally I don't care about what kind of horror-shows of abi abuse drivers do (and there's lots of dumb buffer abused out there). But vgem as used now isn't just a driver, but core infrastructure. And the dumb mmap interface really is just for uploading the occasional splash screen, and definitely not for more elaborate buffer object usage. Furthermore the dumb buffer api is explictily for kms drivers to be used as framebuffers. Which vgem just isn't. - The userspace demonstration vehicle seems missing. Yes there's Ajax's old llvmpipe-on-vgem stuff, and there's Ben's old patches to use vgem to put dma-buf on i915 through it's paces. But vgem as-is has long eclipsed these use-cases, but the corresponding CrOS code hasn't been floated around. Which means it's pretty much impossible to gauge whether the proposed ABI is a good fit for the stated goals. Worse still I tried to raise this with Stéphane on irc and wanted to discuss my concerns, but he just shrugged them off that intel hw issues aren't his concern (and a few other denials). While intel hw is one of the few used by CrOS which actually has a fully coherent gpu (well at least the ones with LLC). Given all that I think vgem just isn't ready yet. I'm definitely not opposed to the overall idea, but I do think it needs to be fleshed out a bit more. And since the release of 4.1 is fairly close the best immediate action seems to be to temporarily revert the vgem driver for now. Cc: Thomas Hellstrom Cc: Dave Airlie Cc: Stéphane Marchesin Cc: Rob Clark Cc: Adam Jackson Cc: Zach Reizner Signed-off-by: Daniel Vetter --- drivers/gpu/drm/Kconfig | 9 - drivers/gpu/drm/Makefile| 1 - drivers/gpu/drm/vgem/Makefile | 4 - drivers/gpu/drm/vgem/vgem_dma_buf.c | 94 -- drivers/gpu/drm/vgem/vgem_drv.c | 364 drivers/gpu/drm/vgem/vgem_drv.h | 57 -- 6 files changed, 529 deletions(-) delete mode 100644 drivers/gpu/drm/vgem/Makefile delete mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c delete mode 100644 drivers/gpu/drm/vgem/vgem_drv.c delete mode 100644 drivers/gpu/drm/vgem/vgem_drv.h diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 47f2ce81b412..151a050129e7 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -165,15 +165,6 @@ config DRM_SAVAGE Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister chipset. If M is selected the module will be called savage. -config DRM_VGEM - tristate "Virtual GEM provider" - depends on DRM - help - Choose this option to get a virtual graphics memory manager, - as used by Mesa's software renderer for enhanced performance. - If M is selected the module will be called vgem. - - source "drivers/gpu/drm/exynos/Kconfig" source "drivers/gpu/drm/rockchip/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4de8d9b006ec..44caabf13041 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -46,7 +46,6 @@ obj-$(CONFIG_DRM_SIS
[PATCH] Revert "drm/vgem: implement virtual GEM"
Acked-by: Thomas Hellstrom On 05/21/2015 04:34 PM, Daniel Vetter wrote: > This reverts commit 502e95c6678505474f1056480310cd9382bacbac. > > Originally vgem was just to have a drm driver for software-only > renders like llvmpipe so that they integrate more nicely with the > existing compositor protocols like DRI2/3. > > Later on Ben extended it to serve as a dma-buf import/export test > vehicle for debugging. Both of these use-cases imo make sense and are > on the level of just yet another (virtual) drm driver. > > But only just I realized that Google's CrOS plans with vgem are much > more pervasive - the plan seems to be to use it as the generic > software mmap path on top of any kind of hw driver buffer objects from > the underlying SoC gfx hw. That means vgem is now common infrastructre > which should work for all drivers and properly interact with them, and > from that point-of-view it definitely falls short on three accounts: > > - It directly forwards the current dma-buf ->mmap model, and the > consensus for that has always been that it's a toy one at best > useful for debugging or super-unlikely fallbacks. Originally it was > added mostly as a concession to get people on top of the dma-buf > train since Ion has this too. > > For proper mmap support we really need some software begin/end > signals, probably best in the form of a set of ioctls on the dma-buf > fd that forward to the already existing ->begin/end_cpu_access > hooks. > > Not exposing this and not requiring userspace to use them puts a > serious burden on any kind of driver that needs to occasionally > handle a bit of coherency troubles. Which includes anything on ARM > and even more so more fancy stuff like virtual hardware. > > Furthermore the vgem mmap interface doesn't expose any begin/end > ioctls either, which means we can't even use the existing dma-buf > hooks properly and fix this up in vgem. > > - vgem uses the dumb buffer api to expose the the mmap support. > Generally I don't care about what kind of horror-shows of abi abuse > drivers do (and there's lots of dumb buffer abused out there). But > vgem as used now isn't just a driver, but core infrastructure. And > the dumb mmap interface really is just for uploading the occasional > splash screen, and definitely not for more elaborate buffer object > usage. > > Furthermore the dumb buffer api is explictily for kms drivers to be > used as framebuffers. Which vgem just isn't. > > - The userspace demonstration vehicle seems missing. Yes there's > Ajax's old llvmpipe-on-vgem stuff, and there's Ben's old patches to > use vgem to put dma-buf on i915 through it's paces. But vgem as-is > has long eclipsed these use-cases, but the corresponding CrOS code > hasn't been floated around. Which means it's pretty much impossible > to gauge whether the proposed ABI is a good fit for the stated > goals. > > Worse still I tried to raise this with Stéphane on irc and wanted to > discuss my concerns, but he just shrugged them off that intel hw > issues aren't his concern (and a few other denials). While intel hw is > one of the few used by CrOS which actually has a fully coherent gpu > (well at least the ones with LLC). > > Given all that I think vgem just isn't ready yet. I'm definitely not > opposed to the overall idea, but I do think it needs to be fleshed out > a bit more. And since the release of 4.1 is fairly close the best > immediate action seems to be to temporarily revert the vgem driver for > now. > > Cc: Thomas Hellstrom > Cc: Dave Airlie > Cc: Stéphane Marchesin > Cc: Rob Clark > Cc: Adam Jackson > Cc: Zach Reizner > Signed-off-by: Daniel Vetter > --- > drivers/gpu/drm/Kconfig | 9 - > drivers/gpu/drm/Makefile| 1 - > drivers/gpu/drm/vgem/Makefile | 4 - > drivers/gpu/drm/vgem/vgem_dma_buf.c | 94 -- > drivers/gpu/drm/vgem/vgem_drv.c | 364 > > drivers/gpu/drm/vgem/vgem_drv.h | 57 -- > 6 files changed, 529 deletions(-) > delete mode 100644 drivers/gpu/drm/vgem/Makefile > delete mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c > delete mode 100644 drivers/gpu/drm/vgem/vgem_drv.c > delete mode 100644 drivers/gpu/drm/vgem/vgem_drv.h > > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig > index 47f2ce81b412..151a050129e7 100644 > --- a/drivers/gpu/drm/Kconfig > +++ b/drivers/gpu/drm/Kconfig > @@ -165,15 +165,6 @@ config DRM_SAVAGE > Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister > chipset. If M is selected the module will be called savage. > > -config DRM_VGEM > - tristate "Virtual GEM provider" > - depends on DRM > - help > - Choose this option to get a virtual graphics memory manager, > - as used by Mesa's software renderer for enhanced performance. > - If M is selected the module will be called vgem. > - > - > source "drivers/gpu/drm/exyno
[PATCH] drm/vgem: drop DRIVER_PRIME
For actual sharing of buffers with other drivers (ie. actual hardware) we'll need to pimp things out a bit better to deal w/ caching, multiple memory domains, etc. See thread: http://lists.freedesktop.org/archives/dri-devel/2015-May/083160.html But for the llvmpipe use-case this isn't a problem. Nor do we really need prime/dri3 (dri2 is sufficient). So until the other issues are sorted lets remove DRIVER_PRIME. NOTE this ends up leaving some basically dead code for prime import/ export (mostly because I was rushing to send this before a meeting). Signed-off-by: Rob Clark --- This is an alternative to removing vgem completely for 4.1, so that llvmpipe work can get started in parallel with sorting out the other issues for sw + hw access.. drivers/gpu/drm/vgem/vgem_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index cb3b435..b0316f9 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -302,7 +302,7 @@ static const struct file_operations vgem_driver_fops = { }; static struct drm_driver vgem_driver = { - .driver_features= DRIVER_GEM | DRIVER_PRIME, + .driver_features= DRIVER_GEM, .gem_free_object= vgem_gem_free_object, .gem_vm_ops = &vgem_gem_vm_ops, .ioctls = vgem_ioctls, -- 2.4.1
[PATCH libdrm] tegra: Add VIC clear test
Hi Arto, On 21 May 2015 at 14:18, Arto Merilainen wrote: > This patch adds a simple test for testing Video-Image-Compositor > engine on Tegra124 SoC. The test case opens a channel and performs > a surface clear. > > Signed-off-by: Arto Merilainen > --- > tests/tegra/Makefile.am | 3 +- > tests/tegra/host1x.h | 52 ++ > tests/tegra/submit_vic.c | 315 +++ > tests/tegra/vic.h| 426 > +++ > 4 files changed, 795 insertions(+), 1 deletion(-) > create mode 100644 tests/tegra/host1x.h > create mode 100644 tests/tegra/submit_vic.c > create mode 100644 tests/tegra/vic.h > Please add the two new headers into the noinst_HEADERS list like below. Otherwise they won''t end up in the tarball, thus the test will fail to build. diff --git a/tests/tegra/Makefile.am b/tests/tegra/Makefile.am index 8e625c8..a771b32 100644 --- a/tests/tegra/Makefile.am +++ b/tests/tegra/Makefile.am @@ -11,3 +11,7 @@ LDADD = \ noinst_PROGRAMS = \ openclose \ submit_vic + +noinst_HEADERS = \ + host1x.h \ + vic.h Thanks Emil
[PATCH v5 00/12] drm/exynos: atomic modesetting support
From: Gustavo Padovan Hi, Here goes the full support for atomic modesetting on exynos. I've split the patches in the various phases of atomic support. v2: fixes comments by Joonyoung - remove unused var in patch 09 - use ->disable instead of outdated ->dpms in hdmi code - remove WARN_ON from crtc enable/disable v3: fixes comment by Joonyoung - move the removal of drm_helper_disable_unused_functions() to separated patch v4: add patches that remove unnecessary calls to disable_plane() v5: fixes NULL CRTC crash on planes updates (reported by Inki and Tobias) Gustavo Gustavo Padovan (12): drm/exynos: atomic phase 1: use drm_plane_helper_update() drm/exynos: atomic phase 1: use drm_plane_helper_disable() drm/exynos: atomic phase 1: add .mode_set_nofb() callback drm/exynos: atomic phase 2: wire up state reset(), duplicate() and destroy() drm/exynos: atomic phase 2: keep track of framebuffer pointer drm/exynos: atomic phase 3: atomic updates of planes drm/exynos: atomic phase 3: use atomic .set_config helper drm/exynos: atomic phase 3: convert page flips drm/exynos: remove exported functions from exynos_drm_plane drm/exynos: don't disable unused functions at init drm/exynos: atomic dpms support drm/exynos: remove unnecessary calls to disable_plane() drivers/gpu/drm/bridge/ps8622.c | 6 +- drivers/gpu/drm/bridge/ptn3460.c| 6 +- drivers/gpu/drm/exynos/exynos_dp_core.c | 6 +- drivers/gpu/drm/exynos/exynos_drm_crtc.c| 215 drivers/gpu/drm/exynos/exynos_drm_dpi.c | 6 +- drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 + drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 +- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 6 +- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 35 + drivers/gpu/drm/exynos/exynos_drm_fb.c | 12 +- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 - drivers/gpu/drm/exynos/exynos_drm_plane.c | 119 --- drivers/gpu/drm/exynos/exynos_drm_plane.h | 11 -- drivers/gpu/drm/exynos/exynos_drm_vidi.c| 6 +- drivers/gpu/drm/exynos/exynos_hdmi.c| 10 +- 15 files changed, 183 insertions(+), 264 deletions(-) -- 2.1.0
[PATCH v5 01/12] drm/exynos: atomic phase 1: use drm_plane_helper_update()
From: Gustavo Padovan Rip out the check from exynos_update_plane() and create exynos_check_plane() for the check phase enabling use to use the atomic helpers to call our check and update phases when updating planes. Update all users of exynos_update_plane() accordingly to call exynos_check_plane() before. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 29 +++--- drivers/gpu/drm/exynos/exynos_drm_plane.c | 40 +++ drivers/gpu/drm/exynos/exynos_drm_plane.h | 2 +- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index eb49195..1c0d936 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -116,6 +116,7 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *fb = crtc->primary->fb; unsigned int crtc_w; unsigned int crtc_h; + int ret; /* when framebuffer changing is requested, crtc's dpms should be on */ if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { @@ -123,11 +124,16 @@ static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, return -EPERM; } + ret = exynos_check_plane(crtc->primary, fb); + if (ret) + return ret; + crtc_w = fb->width - x; crtc_h = fb->height - y; + exynos_update_plane(crtc->primary, crtc, fb, 0, 0, + crtc_w, crtc_h, x, y, crtc_w, crtc_h); - return exynos_update_plane(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, x, y, crtc_w, crtc_h); + return 0; } static void exynos_drm_crtc_disable(struct drm_crtc *crtc) @@ -164,7 +170,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_framebuffer *old_fb = crtc->primary->fb; unsigned int crtc_w, crtc_h; int ret; @@ -183,6 +188,10 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, goto out; } + ret = exynos_check_plane(crtc->primary, fb); + if (ret) + goto out; + ret = drm_vblank_get(dev, exynos_crtc->pipe); if (ret) { DRM_DEBUG("failed to acquire vblank counter\n"); @@ -201,17 +210,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, crtc->primary->fb = fb; crtc_w = fb->width - crtc->x; crtc_h = fb->height - crtc->y; - ret = exynos_update_plane(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, crtc->x, crtc->y, - crtc_w, crtc_h); - if (ret) { - crtc->primary->fb = old_fb; - spin_lock_irq(&dev->event_lock); - exynos_crtc->event = NULL; - drm_vblank_put(dev, exynos_crtc->pipe); - spin_unlock_irq(&dev->event_lock); - return ret; - } + exynos_update_plane(crtc->primary, crtc, fb, 0, 0, + crtc_w, crtc_h, crtc->x, crtc->y, + crtc_w, crtc_h); return 0; diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 13ea334..5a938b1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -144,21 +144,15 @@ void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, plane->crtc = crtc; } -int +void exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); - int ret; - - ret = exynos_check_plane(plane, fb); - if (ret < 0) - return ret; exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x >> 16, src_y >> 16, @@ -166,8 +160,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (exynos_crtc->ops->win_commit) exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); - - return 0; } static int exynos_disable_plane(struct drm_plane *plane) @@ -183,11 +175,37 @@ static int exynos_disable_plane(struct drm_plane *plane) } static struct drm_plane_funcs exynos_plane_funcs = { - .update_plane = exynos_update_plane, + .update_plane = drm_plane_helper_update, .disable_plane = exynos
[PATCH] drm/exynos: use drm_atomic_state directly
From: Gustavo Padovan Instead of use duplicated information stored on struct exynos_drm_plane use the atomic state directly to have a more clear understanding and clean code. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 49 ++-- drivers/gpu/drm/exynos/exynos_drm_drv.h| 51 - drivers/gpu/drm/exynos/exynos_drm_fimd.c | 47 ++-- drivers/gpu/drm/exynos/exynos_drm_plane.c | 86 ++--- drivers/gpu/drm/exynos/exynos_mixer.c | 116 ++--- 5 files changed, 131 insertions(+), 218 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c b/drivers/gpu/drm/exynos/exynos7_drm_decon.c index ed4461f..612ee29 100644 --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -281,16 +281,16 @@ static void decon_disable_vblank(struct exynos_drm_crtc *crtc) } } -static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) +static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, +struct drm_framebuffer *fb) { - struct exynos_drm_plane *plane = &ctx->planes[win]; unsigned long val; int padding; val = readl(ctx->regs + WINCON(win)); val &= ~WINCONx_BPPMODE_MASK; - switch (plane->pixel_format) { + switch (fb->pixel_format) { case DRM_FORMAT_RGB565: val |= WINCONx_BPPMODE_16BPP_565; val |= WINCONx_BURSTLEN_16WORD; @@ -339,7 +339,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) break; } - DRM_DEBUG_KMS("bpp = %d\n", plane->bpp); + DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel); /* * In case of exynos, setting dma-burst to 16Word causes permanent @@ -349,8 +349,8 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) * movement causes unstable DMA which results into iommu crash/tear. */ - padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; - if (plane->fb_width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { + padding = (fb->pitches[0] / (fb->bits_per_pixel >> 3)) - fb->width; + if (fb->width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { val &= ~WINCONx_BURSTLEN_MASK; val |= WINCONx_BURSTLEN_8WORD; } @@ -396,12 +396,15 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, struct exynos_drm_plane *plane) { struct decon_context *ctx = crtc->ctx; + struct drm_plane_state *state = plane->base.state; struct drm_display_mode *mode = &crtc->base.mode; int padding; unsigned long val, alpha; unsigned int last_x; unsigned int last_y; unsigned int win = plane->zpos; + unsigned int bpp = state->fb->bits_per_pixel >> 3; + unsigned int pitch = state->fb->pitches[0]; /* If suspended, enable this on resume */ if (ctx->suspended) { @@ -426,38 +429,38 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, val = (unsigned long)plane->dma_addr[0]; writel(val, ctx->regs + VIDW_BUF_START(win)); - padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; + padding = (pitch / bpp) - state->fb->width; /* buffer size */ - writel(plane->fb_width + padding, ctx->regs + VIDW_WHOLE_X(win)); - writel(plane->fb_height, ctx->regs + VIDW_WHOLE_Y(win)); + writel(state->fb->width + padding, ctx->regs + VIDW_WHOLE_X(win)); + writel(state->fb->height, ctx->regs + VIDW_WHOLE_Y(win)); /* offset from the start of the buffer to read */ - writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win)); - writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win)); + writel(state->src_x, ctx->regs + VIDW_OFFSET_X(win)); + writel(state->src_y, ctx->regs + VIDW_OFFSET_Y(win)); DRM_DEBUG_KMS("start addr = 0x%lx\n", (unsigned long)val); - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", - plane->crtc_width, plane->crtc_height); + DRM_DEBUG_KMS("crtc_w = %d, crtc_h = %d\n", + state->crtc_w, state->crtc_h); /* * OSD position. * In case the window layout goes of LCD layout, DECON fails. */ - if ((plane->crtc_x + plane->crtc_width) > mode->hdisplay) - plane->crtc_x = mode->hdisplay - plane->crtc_width; - if ((plane->crtc_y + plane->crtc_height) > mode->vdisplay) - plane->crtc_y = mode->vdisplay - plane->crtc_height; + if ((state->crtc_x + state->crtc_w) > mode->hdisplay) + state->crtc_x = mode->hdisplay - state->crtc_w; + if ((state->crtc_y + state->crtc_h) > mode->vdisplay) + state->crtc_y = mode->vdisplay
[PATCH v5 02/12] drm/exynos: atomic phase 1: use drm_plane_helper_disable()
From: Gustavo Padovan The atomic helper to disable planes also uses the optional .atomic_disable() helper. The unique operation it does is calling .win_disable() exynos_drm_fb_get_buf_cnt() needs a fb check too to avoid a null pointer. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_fb.c| 2 +- drivers/gpu/drm/exynos/exynos_drm_plane.c | 29 - 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 929cb03..8a38eb7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -136,7 +136,7 @@ unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb) exynos_fb = to_exynos_fb(fb); - return exynos_fb->buf_cnt; + return exynos_fb ? exynos_fb->buf_cnt : 0; } struct drm_framebuffer * diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 5a938b1..b16be27 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -162,21 +162,9 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); } -static int exynos_disable_plane(struct drm_plane *plane) -{ - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc); - - if (exynos_crtc && exynos_crtc->ops->win_disable) - exynos_crtc->ops->win_disable(exynos_crtc, - exynos_plane->zpos); - - return 0; -} - static struct drm_plane_funcs exynos_plane_funcs = { .update_plane = drm_plane_helper_update, - .disable_plane = exynos_disable_plane, + .disable_plane = drm_plane_helper_disable, .destroy= drm_plane_cleanup, }; @@ -201,9 +189,24 @@ static void exynos_plane_atomic_update(struct drm_plane *plane, state->src_w >> 16, state->src_h >> 16); } +static void exynos_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(old_state->crtc); + + if (!old_state->crtc) + return; + + if (exynos_crtc->ops->win_disable) + exynos_crtc->ops->win_disable(exynos_crtc, + exynos_plane->zpos); +} + static const struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_check = exynos_plane_atomic_check, .atomic_update = exynos_plane_atomic_update, + .atomic_disable = exynos_plane_atomic_disable, }; static void exynos_plane_attach_zpos_property(struct drm_plane *plane, -- 2.1.0
[PATCH v5 03/12] drm/exynos: atomic phase 1: add .mode_set_nofb() callback
From: Gustavo Padovan The new atomic infrastructure needs the .mode_set_nofb() callback to update CRTC timings before setting any plane. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 60 +--- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 1c0d936..35f101f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -81,59 +81,16 @@ exynos_drm_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -static int -exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y, - struct drm_framebuffer *old_fb) -{ - struct drm_framebuffer *fb = crtc->primary->fb; - unsigned int crtc_w; - unsigned int crtc_h; - int ret; - - /* -* copy the mode data adjusted by mode_fixup() into crtc->mode -* so that hardware can be seet to proper mode. -*/ - memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode)); - - ret = exynos_check_plane(crtc->primary, fb); - if (ret < 0) - return ret; - - crtc_w = fb->width - x; - crtc_h = fb->height - y; - exynos_plane_mode_set(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, x, y, crtc_w, crtc_h); - - return 0; -} - -static int exynos_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) +static void +exynos_drm_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_framebuffer *fb = crtc->primary->fb; - unsigned int crtc_w; - unsigned int crtc_h; - int ret; - /* when framebuffer changing is requested, crtc's dpms should be on */ - if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { - DRM_ERROR("failed framebuffer changing request.\n"); - return -EPERM; - } - - ret = exynos_check_plane(crtc->primary, fb); - if (ret) - return ret; - - crtc_w = fb->width - x; - crtc_h = fb->height - y; - exynos_update_plane(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, x, y, crtc_w, crtc_h); + if (WARN_ON(!crtc->state)) + return; - return 0; + if (exynos_crtc->ops->commit) + exynos_crtc->ops->commit(exynos_crtc); } static void exynos_drm_crtc_disable(struct drm_crtc *crtc) @@ -158,8 +115,9 @@ static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { .prepare= exynos_drm_crtc_prepare, .commit = exynos_drm_crtc_commit, .mode_fixup = exynos_drm_crtc_mode_fixup, - .mode_set = exynos_drm_crtc_mode_set, - .mode_set_base = exynos_drm_crtc_mode_set_base, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_nofb = exynos_drm_crtc_mode_set_nofb, + .mode_set_base = drm_helper_crtc_mode_set_base, .disable= exynos_drm_crtc_disable, }; -- 2.1.0
[PATCH v5 04/12] drm/exynos: atomic phase 2: wire up state reset(), duplicate() and destroy()
From: Gustavo Padovan Set CRTC, planes and connectors to use the default implementations from the atomic helper library. The helpers will work to keep track of state for each DRM object. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/bridge/ps8622.c | 4 drivers/gpu/drm/bridge/ptn3460.c | 4 drivers/gpu/drm/exynos/exynos_dp_core.c | 4 drivers/gpu/drm/exynos/exynos_drm_crtc.c | 6 ++ drivers/gpu/drm/exynos/exynos_drm_dpi.c | 4 drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 ++ drivers/gpu/drm/exynos/exynos_drm_dsi.c | 4 drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 drivers/gpu/drm/exynos/exynos_drm_vidi.c | 4 drivers/gpu/drm/exynos/exynos_hdmi.c | 4 10 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/bridge/ps8622.c b/drivers/gpu/drm/bridge/ps8622.c index e895aa7..b604326 100644 --- a/drivers/gpu/drm/bridge/ps8622.c +++ b/drivers/gpu/drm/bridge/ps8622.c @@ -31,6 +31,7 @@ #include "drmP.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_atomic_helper.h" /* Brightness scale on the Parade chip */ #define PS8622_MAX_BRIGHTNESS 0xff @@ -502,6 +503,9 @@ static const struct drm_connector_funcs ps8622_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = ps8622_detect, .destroy = ps8622_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static int ps8622_attach(struct drm_bridge *bridge) diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c index 9d2f053..8ed3617 100644 --- a/drivers/gpu/drm/bridge/ptn3460.c +++ b/drivers/gpu/drm/bridge/ptn3460.c @@ -27,6 +27,7 @@ #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_atomic_helper.h" #include "drm_edid.h" #include "drmP.h" @@ -263,6 +264,9 @@ static struct drm_connector_funcs ptn3460_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = ptn3460_detect, .destroy = ptn3460_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static int ptn3460_bridge_attach(struct drm_bridge *bridge) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 1dbfba5..59f2ca5 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -958,6 +959,9 @@ static struct drm_connector_funcs exynos_dp_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .detect = exynos_dp_detect, .destroy = exynos_dp_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; static int exynos_dp_get_modes(struct drm_connector *connector) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 35f101f..44e73d0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -14,6 +14,8 @@ #include #include +#include +#include #include "exynos_drm_crtc.h" #include "exynos_drm_drv.h" @@ -194,8 +196,12 @@ static struct drm_crtc_funcs exynos_crtc_funcs = { .set_config = drm_crtc_helper_set_config, .page_flip = exynos_drm_crtc_page_flip, .destroy= exynos_drm_crtc_destroy, + .reset = drm_atomic_helper_crtc_reset, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, }; + struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_plane *plane, int pipe, diff --git a/drivers/gpu/drm/exynos/exynos_drm_dpi.c b/drivers/gpu/drm/exynos/exynos_drm_dpi.c index 37678cf..ced5c23 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dpi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dpi.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -63,6 +64,9 @@ static struct drm_connector_funcs exynos_dpi_connector_funcs = { .detect = exynos_dpi_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = exynos_dpi_connector_destroy, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connec
[PATCH v5 05/12] drm/exynos: atomic phase 2: keep track of framebuffer pointer
From: Gustavo Padovan Use drm_atomic_set_fb_for_plane() in the legacy page_flip path to keep track of the framebuffer pointer and reference. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 44e73d0..b080e83 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -174,6 +174,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, crtc_w, crtc_h, crtc->x, crtc->y, crtc_w, crtc_h); + if (crtc->primary->state) + drm_atomic_set_fb_for_plane(crtc->primary->state, fb); + return 0; out: -- 2.1.0
[PATCH v5 06/12] drm/exynos: atomic phase 3: atomic updates of planes
From: Gustavo Padovan Now that phase 1 and 2 are complete we can switch the update/disable_plane callbacks to their atomic version. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_fb.c| 3 +++ drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 8a38eb7..dcda496 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "exynos_drm_drv.h" @@ -305,6 +306,8 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev) static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { .fb_create = exynos_user_fb_create, .output_poll_changed = exynos_drm_output_poll_changed, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, }; void exynos_drm_mode_config_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 7811a29..ab50bb7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -164,8 +164,8 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, } static struct drm_plane_funcs exynos_plane_funcs = { - .update_plane = drm_plane_helper_update, - .disable_plane = drm_plane_helper_disable, + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, .destroy= drm_plane_cleanup, .reset = drm_atomic_helper_plane_reset, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, -- 2.1.0
[PATCH v5 07/12] drm/exynos: atomic phase 3: use atomic .set_config helper
From: Gustavo Padovan Now that phase 1 and 2 are complete switch .set_config helper to use the atomic one. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index b080e83..b0888d4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -196,7 +196,7 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) } static struct drm_crtc_funcs exynos_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .page_flip = exynos_drm_crtc_page_flip, .destroy= exynos_drm_crtc_destroy, .reset = drm_atomic_helper_crtc_reset, -- 2.1.0
[PATCH v5 08/12] drm/exynos: atomic phase 3: convert page flips
From: Gustavo Padovan PageFlips now use the atomic helper to work through the atomic modesetting API. Async page flips are not supported yet. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 63 +--- drivers/gpu/drm/exynos/exynos_drm_fb.c | 9 - 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index b0888d4..0db7b91 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -123,67 +123,6 @@ static struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { .disable= exynos_drm_crtc_disable, }; -static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, -struct drm_framebuffer *fb, -struct drm_pending_vblank_event *event, -uint32_t page_flip_flags) -{ - struct drm_device *dev = crtc->dev; - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - unsigned int crtc_w, crtc_h; - int ret; - - /* when the page flip is requested, crtc's dpms should be on */ - if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) { - DRM_ERROR("failed page flip request.\n"); - return -EINVAL; - } - - if (!event) - return -EINVAL; - - spin_lock_irq(&dev->event_lock); - if (exynos_crtc->event) { - ret = -EBUSY; - goto out; - } - - ret = exynos_check_plane(crtc->primary, fb); - if (ret) - goto out; - - ret = drm_vblank_get(dev, exynos_crtc->pipe); - if (ret) { - DRM_DEBUG("failed to acquire vblank counter\n"); - goto out; - } - - exynos_crtc->event = event; - spin_unlock_irq(&dev->event_lock); - - /* -* the pipe from user always is 0 so we can set pipe number -* of current owner to event. -*/ - event->pipe = exynos_crtc->pipe; - - crtc->primary->fb = fb; - crtc_w = fb->width - crtc->x; - crtc_h = fb->height - crtc->y; - exynos_update_plane(crtc->primary, crtc, fb, 0, 0, - crtc_w, crtc_h, crtc->x, crtc->y, - crtc_w, crtc_h); - - if (crtc->primary->state) - drm_atomic_set_fb_for_plane(crtc->primary->state, fb); - - return 0; - -out: - spin_unlock_irq(&dev->event_lock); - return ret; -} - static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); @@ -197,7 +136,7 @@ static void exynos_drm_crtc_destroy(struct drm_crtc *crtc) static struct drm_crtc_funcs exynos_crtc_funcs = { .set_config = drm_atomic_helper_set_config, - .page_flip = exynos_drm_crtc_page_flip, + .page_flip = drm_atomic_helper_page_flip, .destroy= exynos_drm_crtc_destroy, .reset = drm_atomic_helper_crtc_reset, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index dcda496..d5141af 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -303,11 +303,18 @@ static void exynos_drm_output_poll_changed(struct drm_device *dev) exynos_drm_fbdev_init(dev); } +static int exynos_atomic_commit(struct drm_device *dev, + struct drm_atomic_state *state, + bool async) +{ + return drm_atomic_helper_commit(dev, state, false); +} + static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = { .fb_create = exynos_user_fb_create, .output_poll_changed = exynos_drm_output_poll_changed, .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, + .atomic_commit = exynos_atomic_commit, }; void exynos_drm_mode_config_init(struct drm_device *dev) -- 2.1.0
[PATCH v5 09/12] drm/exynos: remove exported functions from exynos_drm_plane
From: Gustavo Padovan Now that no one is using the functions exported by exynos_drm_plane due to the atomic conversion we can make remove some of the them or make them static. v2: remove unused exynos_drm_crtc Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_plane.c | 90 +-- drivers/gpu/drm/exynos/exynos_drm_plane.h | 11 2 files changed, 37 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index ab50bb7..b385fec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -62,35 +62,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last) return size; } -int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb) -{ - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); - int nr; - int i; - - nr = exynos_drm_fb_get_buf_cnt(fb); - for (i = 0; i < nr; i++) { - struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); - - if (!buffer) { - DRM_DEBUG_KMS("buffer is null\n"); - return -EFAULT; - } - - exynos_plane->dma_addr[i] = buffer->dma_addr; - - DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", - i, (unsigned long)exynos_plane->dma_addr[i]); - } - - return 0; -} - -void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) +static void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) { struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); unsigned int actual_w; @@ -145,24 +122,6 @@ void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc, plane->crtc = crtc; } -void -exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, -struct drm_framebuffer *fb, int crtc_x, int crtc_y, -unsigned int crtc_w, unsigned int crtc_h, -uint32_t src_x, uint32_t src_y, -uint32_t src_w, uint32_t src_h) -{ - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); - - exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, - crtc_w, crtc_h, src_x >> 16, src_y >> 16, - src_w >> 16, src_h >> 16); - - if (exynos_crtc->ops->win_commit) - exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); -} - static struct drm_plane_funcs exynos_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, @@ -175,22 +134,47 @@ static struct drm_plane_funcs exynos_plane_funcs = { static int exynos_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) { - return exynos_check_plane(plane, state->fb); + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); + int nr; + int i; + + nr = exynos_drm_fb_get_buf_cnt(state->fb); + for (i = 0; i < nr; i++) { + struct exynos_drm_gem_buf *buffer = + exynos_drm_fb_buffer(state->fb, i); + + if (!buffer) { + DRM_DEBUG_KMS("buffer is null\n"); + return -EFAULT; + } + + exynos_plane->dma_addr[i] = buffer->dma_addr; + + DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", + i, (unsigned long)exynos_plane->dma_addr[i]); + } + + return 0; } static void exynos_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { struct drm_plane_state *state = plane->state; + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(state->crtc); + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); if (!state->crtc) return; - exynos_update_plane(plane, state->crtc, state->fb, - state->crtc_x, state->crtc_y, - state->crtc_w, state->crtc
[PATCH v5 10/12] drm/exynos: don't disable unused functions at init
From: Gustavo Padovan Everything starts disabled so we don't really need to disable anything. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index e71e331..e0b085b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -275,9 +275,6 @@ int exynos_drm_fbdev_init(struct drm_device *dev) } - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(dev); - ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP); if (ret < 0) { DRM_ERROR("failed to set up hw configuration.\n"); -- 2.1.0
[PATCH v5 11/12] drm/exynos: atomic dpms support
From: Gustavo Padovan Run dpms operations through the atomic intefaces. This basically removes the .dpms() callback from econders and crtcs and use .disable() and .enable() to turn the crtc on and off. v2: Address comments by Joonyoung: - make hdmi code call ->disable() instead of ->dpms() - do not use WARN_ON on crtc enable/disable v3: - Fix build failure after the hdmi change in v2 - Change dpms helper of ptn3460 bridge Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/bridge/ps8622.c | 2 +- drivers/gpu/drm/bridge/ptn3460.c| 2 +- drivers/gpu/drm/exynos/exynos_dp_core.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_crtc.c| 99 - drivers/gpu/drm/exynos/exynos_drm_dpi.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 +- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 27 ++-- drivers/gpu/drm/exynos/exynos_drm_vidi.c| 2 +- drivers/gpu/drm/exynos/exynos_hdmi.c| 6 +- 10 files changed, 71 insertions(+), 77 deletions(-) diff --git a/drivers/gpu/drm/bridge/ps8622.c b/drivers/gpu/drm/bridge/ps8622.c index b604326..d686235 100644 --- a/drivers/gpu/drm/bridge/ps8622.c +++ b/drivers/gpu/drm/bridge/ps8622.c @@ -499,7 +499,7 @@ static void ps8622_connector_destroy(struct drm_connector *connector) } static const struct drm_connector_funcs ps8622_connector_funcs = { - .dpms = drm_helper_connector_dpms, + .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = ps8622_detect, .destroy = ps8622_connector_destroy, diff --git a/drivers/gpu/drm/bridge/ptn3460.c b/drivers/gpu/drm/bridge/ptn3460.c index 8ed3617..260bc9f 100644 --- a/drivers/gpu/drm/bridge/ptn3460.c +++ b/drivers/gpu/drm/bridge/ptn3460.c @@ -260,7 +260,7 @@ static void ptn3460_connector_destroy(struct drm_connector *connector) } static struct drm_connector_funcs ptn3460_connector_funcs = { - .dpms = drm_helper_connector_dpms, + .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = ptn3460_detect, .destroy = ptn3460_connector_destroy, diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 59f2ca5..d468637 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -955,7 +955,7 @@ static void exynos_dp_connector_destroy(struct drm_connector *connector) } static struct drm_connector_funcs exynos_dp_connector_funcs = { - .dpms = drm_helper_connector_dpms, + .dpms = drm_atomic_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = exynos_dp_detect, .destroy = exynos_dp_connector_destroy, diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 0db7b91..519c569 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -22,51 +22,57 @@ #include "exynos_drm_encoder.h" #include "exynos_drm_plane.h" -static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) +static void exynos_drm_crtc_enable(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + struct exynos_drm_plane *exynos_plane = to_exynos_plane(crtc->primary); - DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode); - - if (exynos_crtc->dpms == mode) { - DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n"); + if (exynos_crtc->enabled) return; - } - - if (mode > DRM_MODE_DPMS_ON) { - /* wait for the completion of page flip. */ - if (!wait_event_timeout(exynos_crtc->pending_flip_queue, - (exynos_crtc->event == NULL), HZ/20)) - exynos_crtc->event = NULL; - drm_crtc_vblank_off(crtc); - } if (exynos_crtc->ops->dpms) - exynos_crtc->ops->dpms(exynos_crtc, mode); + exynos_crtc->ops->dpms(exynos_crtc, DRM_MODE_DPMS_ON); - exynos_crtc->dpms = mode; + exynos_crtc->enabled = true; - if (mode == DRM_MODE_DPMS_ON) - drm_crtc_vblank_on(crtc); -} + drm_crtc_vblank_on(crtc); -static void exynos_drm_crtc_prepare(struct drm_crtc *crtc) -{ - /* drm framework doesn't check NULL. */ + if (exynos_crtc->ops->win_commit) + exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); + + if (exynos_crtc->ops->commit) + exynos_crtc->ops->commit(exynos_crtc); } -static void exynos_drm_crtc_commit(struct drm_crtc *crtc) +static void exynos_drm_crtc_disable(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct exynos_drm_plane *exynos
[PATCH v5 12/12] drm/exynos: remove unnecessary calls to disable_plane()
From: Gustavo Padovan The planes are already disabled by the drm_atomic_helper_commit() code so we don't need to disable the in these two places. Signed-off-by: Gustavo Padovan --- drivers/gpu/drm/exynos/exynos_drm_crtc.c| 11 --- drivers/gpu/drm/exynos/exynos_drm_encoder.c | 8 2 files changed, 19 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 519c569..9bf25ff 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -47,8 +47,6 @@ static void exynos_drm_crtc_enable(struct drm_crtc *crtc) static void exynos_drm_crtc_disable(struct drm_crtc *crtc) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - struct drm_plane *plane; - int ret; if (!exynos_crtc->enabled) return; @@ -64,15 +62,6 @@ static void exynos_drm_crtc_disable(struct drm_crtc *crtc) exynos_crtc->ops->dpms(exynos_crtc, DRM_MODE_DPMS_OFF); exynos_crtc->enabled = false; - - drm_for_each_legacy_plane(plane, &crtc->dev->mode_config.plane_list) { - if (plane->crtc != crtc) - continue; - - ret = plane->funcs->disable_plane(plane); - if (ret) - DRM_ERROR("Failed to disable plane %d\n", ret); - } } static bool diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 0648ba4..7b89fd5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -81,17 +81,9 @@ static void exynos_drm_encoder_disable(struct drm_encoder *encoder) { struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); struct exynos_drm_display *display = exynos_encoder->display; - struct drm_plane *plane; - struct drm_device *dev = encoder->dev; if (display->ops->dpms) display->ops->dpms(display, DRM_MODE_DPMS_OFF); - - /* all planes connected to this encoder should be also disabled. */ - drm_for_each_legacy_plane(plane, &dev->mode_config.plane_list) { - if (plane->crtc && (plane->crtc == encoder->crtc)) - plane->funcs->disable_plane(plane); - } } static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = { -- 2.1.0
[PATCH] drm/vgem: drop DRIVER_PRIME
Hi, Rob! On 05/21/2015 04:53 PM, Rob Clark wrote: > For actual sharing of buffers with other drivers (ie. actual hardware) > we'll need to pimp things out a bit better to deal w/ caching, multiple > memory domains, etc. See thread: > > > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_archives_dri-2Ddevel_2015-2DMay_083160.html&d=AwIBAg&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=vpukPkBtpoNQp2IUKuFviOmPNYWVKmen3Jeeu55zmEA&m=hZDsGjgypZF71rQfORpnkvT34UoNymdOdW0M3RyIIpQ&s=6QpYr_rF5y3fBjm48gY5zTJp6Fu87bv2HJYGGJ7VX7s&e= > > > But for the llvmpipe use-case this isn't a problem. Nor do we really > need prime/dri3 (dri2 is sufficient). So until the other issues are > sorted lets remove DRIVER_PRIME. > > NOTE this ends up leaving some basically dead code for prime import/ > export (mostly because I was rushing to send this before a meeting). What worries me a little is what Daniel brought up in his commit message, that let's say in the end people add a reasonable interface to dma_buf mmap, vgem also needs a corresponding interface... Makes me think that the best solution for now is perhaps to revert it. /Thomas > > Signed-off-by: Rob Clark > --- > This is an alternative to removing vgem completely for 4.1, so that > llvmpipe work can get started in parallel with sorting out the other > issues for sw + hw access.. > > drivers/gpu/drm/vgem/vgem_drv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c > index cb3b435..b0316f9 100644 > --- a/drivers/gpu/drm/vgem/vgem_drv.c > +++ b/drivers/gpu/drm/vgem/vgem_drv.c > @@ -302,7 +302,7 @@ static const struct file_operations vgem_driver_fops = { > }; > > static struct drm_driver vgem_driver = { > - .driver_features= DRIVER_GEM | DRIVER_PRIME, > + .driver_features= DRIVER_GEM, > .gem_free_object= vgem_gem_free_object, > .gem_vm_ops = &vgem_gem_vm_ops, > .ioctls = vgem_ioctls,
[Bug 90378] GPU lockups in Left 4 Dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=90378 --- Comment #2 from Daniel Scharrer --- Created attachment 115951 --> https://bugs.freedesktop.org/attachment.cgi?id=115951&action=edit patch to revert LLVM r233366 (fixes lockups) This seems to be a regression in llvm: Mesa git + LLVM svn is bad Mesa 10.5.5 + LLVM svn is bad Mesa git + LLVM 3.6.0 is good (no lockups, no glitches) With Mesa git, the lockups in the L4D2 apitrace linked above bisect to LLVM r233366: commit 9217916725713c00f17cb64123e8dffdae843eb7 Author: Andrew Trick Date: Fri Mar 27 06:10:13 2015 + Complete the MachineScheduler fix made way back in r210390. "Fix the MachineScheduler's logic for updating ready times for in-order. Now the scheduler updates a node's ready time as soon as it is scheduled, before releasing dependent nodes." This fix was only made in one variant of the ScheduleDAGMI driver. Francois de Ferriere reported the issue in the other bit of code where it was also needed. I never got around to coming up with a test case, but it's an obvious fix that shouldn't be delayed any longer. I'll try to refactor this code a little better. I did verify performance on a wide variety of targets and saw no negative impact with this fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk at 233366 91177308-0d34-0410-b5e6-96231b3b80d8 I had to revert b8797a7 and a99a16a in Mesa for it to build against that LLVM revision. Besides the arch-specific test files, r233366 only moves one line of code around. Reverting that on current LLVM (see attached patch) also fixes the lockups. As with bug #90510, R600_DEBUG=switch_on_eop gets rid of the glitches, and also prevents the crashes as well. Not sure if that means it could be a bug in Mesa or if that just hides the LLVM bug. While bisecting for the lockup, I noticed the glitches were also introduced in LLVM after 3.6.0, but not by the same revision - f74b5c6 (r231401) has no lockups but does have glitches. I'll bisect that for bug #88561 as the glitches in the latest Talos apitrace there also seem to come from that commit range. (The GPU faults - bug #87278 - seem to have yet another cause, being present even with LLVM 3.6.0.) NB: I also noticed that with compositing enabled in KWin, the system is not able to recover from the GPU lockups (and eventually does not even respond to SSH or SysRq). With compositing disabled the GPU is almost always reset successfully and the game / glretrace can continue as if nothing happened. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/55d34ebc/attachment.html>
[Bug 90378] [radeonsi][bisected] GPU lockups in Left 4 Dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=90378 Daniel Scharrer changed: What|Removed |Added Summary|GPU lockups in Left 4 Dead |[radeonsi][bisected] GPU |2 |lockups in Left 4 Dead 2 -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/9c632f14/attachment.html>
[PATCH v5 09/12] drm/exynos: remove exported functions from exynos_drm_plane
Hi, like I said before, this clashes with my commit 'drm/exynos: plane: honor buffer offset for dma_addr' (5d878bdb51bd7915ba3def8b531238c67624aa58), which is currently sitting in airlied's drm-fixes. With best wishes, Tobias On 2015-05-21 17:02, Gustavo Padovan wrote: > From: Gustavo Padovan > > Now that no one is using the functions exported by exynos_drm_plane due > to the atomic conversion we can make remove some of the them or make > them > static. > > v2: remove unused exynos_drm_crtc > > Signed-off-by: Gustavo Padovan > --- > drivers/gpu/drm/exynos/exynos_drm_plane.c | 90 > +-- > drivers/gpu/drm/exynos/exynos_drm_plane.h | 11 > 2 files changed, 37 insertions(+), 64 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c > b/drivers/gpu/drm/exynos/exynos_drm_plane.c > index ab50bb7..b385fec 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c > @@ -62,35 +62,12 @@ static int exynos_plane_get_size(int start, > unsigned length, unsigned last) > return size; > } > > -int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer > *fb) > -{ > - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); > - int nr; > - int i; > - > - nr = exynos_drm_fb_get_buf_cnt(fb); > - for (i = 0; i < nr; i++) { > - struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i); > - > - if (!buffer) { > - DRM_DEBUG_KMS("buffer is null\n"); > - return -EFAULT; > - } > - > - exynos_plane->dma_addr[i] = buffer->dma_addr; > - > - DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", > - i, (unsigned long)exynos_plane->dma_addr[i]); > - } > - > - return 0; > -} > - > -void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc > *crtc, > - struct drm_framebuffer *fb, int crtc_x, int crtc_y, > - unsigned int crtc_w, unsigned int crtc_h, > - uint32_t src_x, uint32_t src_y, > - uint32_t src_w, uint32_t src_h) > +static void exynos_plane_mode_set(struct drm_plane *plane, struct > drm_crtc *crtc, > + struct drm_framebuffer *fb, > + int crtc_x, int crtc_y, > + unsigned int crtc_w, unsigned int crtc_h, > + uint32_t src_x, uint32_t src_y, > + uint32_t src_w, uint32_t src_h) > { > struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); > unsigned int actual_w; > @@ -145,24 +122,6 @@ void exynos_plane_mode_set(struct drm_plane > *plane, struct drm_crtc *crtc, > plane->crtc = crtc; > } > > -void > -exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, > - struct drm_framebuffer *fb, int crtc_x, int crtc_y, > - unsigned int crtc_w, unsigned int crtc_h, > - uint32_t src_x, uint32_t src_y, > - uint32_t src_w, uint32_t src_h) > -{ > - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); > - struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); > - > - exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, > - crtc_w, crtc_h, src_x >> 16, src_y >> 16, > - src_w >> 16, src_h >> 16); > - > - if (exynos_crtc->ops->win_commit) > - exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos); > -} > - > static struct drm_plane_funcs exynos_plane_funcs = { > .update_plane = drm_atomic_helper_update_plane, > .disable_plane = drm_atomic_helper_disable_plane, > @@ -175,22 +134,47 @@ static struct drm_plane_funcs exynos_plane_funcs > = { > static int exynos_plane_atomic_check(struct drm_plane *plane, >struct drm_plane_state *state) > { > - return exynos_check_plane(plane, state->fb); > + struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); > + int nr; > + int i; > + > + nr = exynos_drm_fb_get_buf_cnt(state->fb); > + for (i = 0; i < nr; i++) { > + struct exynos_drm_gem_buf *buffer = > + exynos_drm_fb_buffer(state->fb, i); > + > + if (!buffer) { > + DRM_DEBUG_KMS("buffer is null\n"); > + return -EFAULT; > + } > + > + exynos_plane->dma_addr[i] = buffer->dma_addr; > + > + DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n", > + i, (unsigned long)exynos_plane->dma_addr[i]); > + } > + > + return 0; > } > > static void exynos_plane_atomic_update(struct drm_plane *plane, > struct drm_plane_state *old_state) > { > struct
[PATCH v3] drm/exynos: calculate vrefresh instead of use a fixed value
Hey, On 2015-05-21 16:06, Gustavo Padovan wrote: > Hi Tobias, > > 2015-05-21 Tobias Jakobi : > >> Gustavo Padovan wrote: >> > From: Gustavo Padovan >> > >> > When mode's vrefresh is zero we should ask DRM core to calculate vrefresh >> > for us so we can get the correct value instead of relying on fixed value >> > defined in a macro. But if vrefresh is still zero we should fail the >> > update. >> This works better for me: >> diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c >> b/drivers/gpu/drm/exynos/exynos_drm_fimd.c >> index dc834b8..26e8ae4 100644 >> --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c >> +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c >> @@ -346,11 +346,16 @@ static bool fimd_mode_fixup(struct >> exynos_drm_crtc >> *crtc, >> static void fimd_commit(struct exynos_drm_crtc *crtc) >> { >> struct fimd_context *ctx = crtc->ctx; >> - struct drm_display_mode *mode = &crtc->base.mode; >> + struct drm_display_mode *mode; >> struct fimd_driver_data *driver_data = ctx->driver_data; >> void *timing_base = ctx->regs + driver_data->timing_base; >> u32 val, clkdiv; >> >> + if (crtc->base.state) >> + mode = &crtc->base.state->adjusted_mode; >> + else >> + mode = &crtc->base.mode; >> + >> if (ctx->suspended) >> return; >> >> Otherwise I get an oops (nullptr deref) on boot, so 'state' is >> probably >> not initialized yet at this point. > > Would you like to send a proper git patch of this? You can move the > drm_mode_vrefresh() part to your patch. I'll try to send out something later this day. With best wishes, Tobias > > Gustavo
[PATCH 3/4] drm/tegra: Add VIC support
Thank you Mikko for your comments! Please see my answers inline. - Arto On 05/21/2015 05:40 PM, Mikko Perttunen wrote: > Hi, very good patch! > > Here are a few small comments. Aside those, you should also add a > section to > Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt in a > separate patch. Will do. > On 05/21/2015 04:20 PM, Arto Merilainen wrote: >> This patch adds support for Video Image Compositor engine which >> can be used for 2d operations. >> >> The engine has a microcontroller (Falcon) that acts as a frontend >> for the rest of the unit. In order to properly utilize the engine, >> the frontend must be booted before pushing any commands. >> >> Signed-off-by: Andrew Chew >> Signed-off-by: Arto Merilainen >> --- >> drivers/gpu/drm/tegra/Makefile | 3 +- >> drivers/gpu/drm/tegra/drm.c| 9 +- >> drivers/gpu/drm/tegra/drm.h| 1 + >> drivers/gpu/drm/tegra/vic.c| 593 >> + >> drivers/gpu/drm/tegra/vic.h| 116 >> include/linux/host1x.h | 1 + >> 6 files changed, 721 insertions(+), 2 deletions(-) >> create mode 100644 drivers/gpu/drm/tegra/vic.c >> create mode 100644 drivers/gpu/drm/tegra/vic.h >> >> diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile >> index 2c66a8db9da4..3bc3566e00b6 100644 >> --- a/drivers/gpu/drm/tegra/Makefile >> +++ b/drivers/gpu/drm/tegra/Makefile >> @@ -13,6 +13,7 @@ tegra-drm-y := \ >> sor.o \ >> dpaux.o \ >> gr2d.o \ >> -gr3d.o >> +gr3d.o \ >> +vic.o >> >> obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o >> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c >> index bfad15a913a0..d947f5f4d801 100644 >> --- a/drivers/gpu/drm/tegra/drm.c >> +++ b/drivers/gpu/drm/tegra/drm.c >> @@ -1,6 +1,6 @@ >> /* >>* Copyright (C) 2012 Avionic Design GmbH >> - * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. >> + * Copyright (C) 2012-2015 NVIDIA CORPORATION. All rights reserved. >>* >>* This program is free software; you can redistribute it and/or modify >>* it under the terms of the GNU General Public License version 2 as >> @@ -1048,6 +1048,7 @@ static const struct of_device_id host1x_drm_subdevs[] >> = { >> { .compatible = "nvidia,tegra124-dc", }, >> { .compatible = "nvidia,tegra124-sor", }, >> { .compatible = "nvidia,tegra124-hdmi", }, >> +{ .compatible = "nvidia,tegra124-vic", }, >> { /* sentinel */ } >> }; >> >> @@ -1097,8 +1098,14 @@ static int __init host1x_drm_init(void) >> if (err < 0) >> goto unregister_gr2d; >> >> +err = platform_driver_register(&tegra_vic_driver); >> +if (err < 0) >> +goto unregister_gr3d; >> + >> return 0; >> >> +unregister_gr3d: >> +platform_driver_unregister(&tegra_gr3d_driver); >> unregister_gr2d: >> platform_driver_unregister(&tegra_gr2d_driver); >> unregister_dpaux: >> diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h >> index 0e7756e720c5..a9c02a80d6bf 100644 >> --- a/drivers/gpu/drm/tegra/drm.h >> +++ b/drivers/gpu/drm/tegra/drm.h >> @@ -275,5 +275,6 @@ extern struct platform_driver tegra_hdmi_driver; >> extern struct platform_driver tegra_dpaux_driver; >> extern struct platform_driver tegra_gr2d_driver; >> extern struct platform_driver tegra_gr3d_driver; >> +extern struct platform_driver tegra_vic_driver; >> >> #endif /* HOST1X_DRM_H */ >> diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c >> new file mode 100644 >> index ..b7c5a96697ed >> --- /dev/null >> +++ b/drivers/gpu/drm/tegra/vic.c >> @@ -0,0 +1,593 @@ >> +/* >> + * Copyright (c) 2015, NVIDIA Corporation. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "drm.h" >> +#include "gem.h" >> +#include "vic.h" >> + >> +#define VIC_IDLE_TIMEOUT_DEFAULT1 /* 10 milliseconds */ >> +#define VIC_IDLE_CHECK_PERIOD 10 /* 10 usec */ >> + >> +struct vic; > > This doesn't seem to be needed here. > >> + >> +struct vic_config { >> +/* firmware name */ >> +char *ucode_name; >> + >> +/* class id */ >> +u32 class_id; >> + >> +/* powergate id */ >> +int powergate_id; >> +}; >> + >> +struct vic { >> +struct { >> +u32 bin_data_offset; >> +u32 data_offset; >> +u32 data_size; >> +u32 code_offset; >> +u32 size; >> +} os, fce; >> + >> +struct tegra_bo *ucode_bo; >> +bool ucode_valid; >> +void *ucode_vaddr; >> + >> +bool booted; >> + >> +void __iomem *regs; >> +struct tegra_drm_client client;
[Bug 90378] [radeonsi][bisected] GPU lockups in Left 4 Dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=90378 --- Comment #3 from Daniel Scharrer --- Created attachment 115952 --> https://bugs.freedesktop.org/attachment.cgi?id=115952&action=edit R600_DEBUG=ps,vs,gs output with r233365 (no lockups) -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/cd3310da/attachment.html>
[Bug 90378] [radeonsi][bisected] GPU lockups in Left 4 Dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=90378 Daniel Scharrer changed: What|Removed |Added Attachment #115952|text/plain |application/x-xz mime type|| -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/864b9b7b/attachment.html>
[PATCH libdrm] tegra: Add VIC clear test
Thank you Emil for your feedback, On 05/21/2015 05:58 PM, Emil Velikov wrote: > Hi Arto, > > On 21 May 2015 at 14:18, Arto Merilainen wrote: >> This patch adds a simple test for testing Video-Image-Compositor >> engine on Tegra124 SoC. The test case opens a channel and performs >> a surface clear. >> >> Signed-off-by: Arto Merilainen >> --- >> tests/tegra/Makefile.am | 3 +- >> tests/tegra/host1x.h | 52 ++ >> tests/tegra/submit_vic.c | 315 +++ >> tests/tegra/vic.h| 426 >> +++ >> 4 files changed, 795 insertions(+), 1 deletion(-) >> create mode 100644 tests/tegra/host1x.h >> create mode 100644 tests/tegra/submit_vic.c >> create mode 100644 tests/tegra/vic.h >> > > Please add the two new headers into the noinst_HEADERS list like > below. Otherwise they won''t end up in the tarball, thus the test will > fail to build. I will fix this in the next version. - Arto
[Bug 90378] [radeonsi][bisected] GPU lockups in Left 4 Dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=90378 --- Comment #4 from Daniel Scharrer --- Created attachment 115956 --> https://bugs.freedesktop.org/attachment.cgi?id=115956&action=edit R600_DEBUG=ps,vs,gs output with r233366 (lockups) -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/4fc73666/attachment.html>
[Bug 89228] Regression with left for dead 2
https://bugs.freedesktop.org/show_bug.cgi?id=89228 --- Comment #4 from Daniel Scharrer --- Are you still experiencing lockups? If so, can you a) run the game with R600_DEBUG=switch_on_eop and b) compile LLVM with the patch from bug #90378 comment 2 and run without R600_DEBUG This should at least confirm if we are seeing the same issue. -- You are receiving this mail because: You are the assignee for the bug. -- next part -- An HTML attachment was scrubbed... URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/8d23fd0f/attachment.html>
[PATCH] drm/vgem: drop DRIVER_PRIME
On Thu, May 21, 2015 at 05:03:58PM +0200, Thomas Hellstrom wrote: > Hi, Rob! > > On 05/21/2015 04:53 PM, Rob Clark wrote: > > For actual sharing of buffers with other drivers (ie. actual hardware) > > we'll need to pimp things out a bit better to deal w/ caching, multiple > > memory domains, etc. See thread: > > > > > > https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_archives_dri-2Ddevel_2015-2DMay_083160.html&d=AwIBAg&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=vpukPkBtpoNQp2IUKuFviOmPNYWVKmen3Jeeu55zmEA&m=hZDsGjgypZF71rQfORpnkvT34UoNymdOdW0M3RyIIpQ&s=6QpYr_rF5y3fBjm48gY5zTJp6Fu87bv2HJYGGJ7VX7s&e= > > > > > > But for the llvmpipe use-case this isn't a problem. Nor do we really > > need prime/dri3 (dri2 is sufficient). So until the other issues are > > sorted lets remove DRIVER_PRIME. > > > > NOTE this ends up leaving some basically dead code for prime import/ > > export (mostly because I was rushing to send this before a meeting). > > What worries me a little is what Daniel brought up in his commit > message, that let's say in the end people add a reasonable interface to > dma_buf mmap, vgem also needs a corresponding interface... Makes me > think that the best solution for now > is perhaps to revert it. Yeah if we just drop the prime parts vgem is pretty much only for llvmpipe and other software renderers. And if we add prime it'd be purely self-import only which rejects any foreign access and reject any foreign objects. At least I haven't understood yet why we need to import the dma-bufs first when we could just directly mmap the passed-in fd ... Anyway I think removing the dead code makes sense - we can easily resurrect it with git again. Also the current prime code for vgem doesn't handle self-imports correctly, so isnt' even really useable for llvmpipe-on-vgem as-is. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch
[PATCH] drm/vgem: drop DRIVER_PRIME
On Thu, May 21, 2015 at 11:03 AM, Thomas Hellstrom wrote: > Hi, Rob! > > On 05/21/2015 04:53 PM, Rob Clark wrote: >> For actual sharing of buffers with other drivers (ie. actual hardware) >> we'll need to pimp things out a bit better to deal w/ caching, multiple >> memory domains, etc. See thread: >> >> >> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_archives_dri-2Ddevel_2015-2DMay_083160.html&d=AwIBAg&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=vpukPkBtpoNQp2IUKuFviOmPNYWVKmen3Jeeu55zmEA&m=hZDsGjgypZF71rQfORpnkvT34UoNymdOdW0M3RyIIpQ&s=6QpYr_rF5y3fBjm48gY5zTJp6Fu87bv2HJYGGJ7VX7s&e= >> >> But for the llvmpipe use-case this isn't a problem. Nor do we really >> need prime/dri3 (dri2 is sufficient). So until the other issues are >> sorted lets remove DRIVER_PRIME. >> >> NOTE this ends up leaving some basically dead code for prime import/ >> export (mostly because I was rushing to send this before a meeting). > > What worries me a little is what Daniel brought up in his commit > message, that let's say in the end people add a reasonable interface to > dma_buf mmap, vgem also needs a corresponding interface... Makes me > think that the best solution for now > is perhaps to revert it. Well, I think that is solvable.. ie. when vgem regains PRIME support, disallow mmap'ing of imported buffers (and disallow export?), and do all cpu-prep/fini stuff via dmabuf handle, for example. Without prime, vgem is at least for now useful for allocating a dumb buffer and sharing it between X and client (for llvmpipe rendering). BR, -R > /Thomas > > >> >> Signed-off-by: Rob Clark >> --- >> This is an alternative to removing vgem completely for 4.1, so that >> llvmpipe work can get started in parallel with sorting out the other >> issues for sw + hw access.. >> >> drivers/gpu/drm/vgem/vgem_drv.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/drivers/gpu/drm/vgem/vgem_drv.c >> b/drivers/gpu/drm/vgem/vgem_drv.c >> index cb3b435..b0316f9 100644 >> --- a/drivers/gpu/drm/vgem/vgem_drv.c >> +++ b/drivers/gpu/drm/vgem/vgem_drv.c >> @@ -302,7 +302,7 @@ static const struct file_operations vgem_driver_fops = { >> }; >> >> static struct drm_driver vgem_driver = { >> - .driver_features= DRIVER_GEM | DRIVER_PRIME, >> + .driver_features= DRIVER_GEM, >> .gem_free_object= vgem_gem_free_object, >> .gem_vm_ops = &vgem_gem_vm_ops, >> .ioctls = vgem_ioctls, >
[RESEND PATCH 2/2] modetest: only select plane with matching format
Hi Tobias On 12 May 2015 at 21:17, Tobias Jakobi wrote: > Don't assume that a plane supports any kind of pixelformat > but do a check first. > > v2: Simplify the format check. > Signed-off-by: Tobias Jakobi Nice catch ! I will push the tomorrow, unless we hear any objections against it. Patch 1/2 looks sane imho, although I'm not sure if some of the teams has some (automated?) testing which depends on the lack of transparency. Curious if pinging people (check git log for a list) at #dri-devel or via email might show such users ? Cheers, Emil
[PATCH v2] drm: Only create a cmdline mode if no probed modes match
On Mon, Apr 20, 2015 at 03:41:48PM +0200, Radek Dostál wrote: > On 04/20/2015 03:28 PM, Chris Wilson wrote: > > The intention of using video=: is primarily to select > > the user's preferred resolution at startup. Currently we always create a > > new mode irrespective of whether the monitor has a native mode at the > > desired resolution. This has the issue that we may then select the fake > > mode rather the native mode during fb_helper->inital_config() and so > > if the fake mode is invalid we then end up with a loss of signal. Oops. > > This invalid fake mode would also be exported to userspace, who > > potentially may make the same mistake. > > > > To avoid this issue, we filter out the added command line mode if we > > detect the desired resolution (and clock if specified) amongst the > > probed modes. This fixes the immediate problem of adding a duplicate > > mode, but perhaps more generically we should avoid adding a GTF mode if > > the monitor has an EDID that is not GTF-compatible, or similarly for > > CVT. > > > > A second issue sneaked into this patch is to add the cmdline mode mode > > ahead of the absolute fallback 1024x768 mode. That is if the user has > > specified a mode that we create as a fallback, we do not need to add a > > second unused fallback mode. > > > > Fixes regression from > > > > commit eaf99c749d43ae74ac7ffece5512f3c73f01dfd2 > > Author: Chris Wilson > > Date: Wed Aug 6 10:08:32 2014 +0200 > > > > drm: Perform cmdline mode parsing during connector initialisation > > > > that breaks HDMI output on BeagleBone Black with LG TV (model 19LS4R-ZA). > > > > v2: Explicitly delete our earlier cmdline mode > > > > Reported-by: Radek Dostál > > Signed-off-by: Chris Wilson > > Cc: Radek Dostál > > Cc: Jesse Barnes > > Cc: Ville Syrjälä > > Cc: Daniel Vetter > > Cc: dri-devel at lists.freedesktop.org > > Cc: Julia Lemire > > Cc: Dave Airlie > > Cc: stable at vger.kernel.org > > works now :) > > Tested-by: Radek Dostál Daniel, Dave do either or you want to pick this up for your fixes tree? -Chris -- Chris Wilson, Intel Open Source Technology Centre
[PATCH] drm/vgem: drop DRIVER_PRIME (v2)
For actual sharing of buffers with other drivers (ie. actual hardware) we'll need to pimp things out a bit better to deal w/ caching, multiple memory domains, etc. See thread: http://lists.freedesktop.org/archives/dri-devel/2015-May/083160.html But for the llvmpipe use-case this isn't a problem. Nor do we really need prime/dri3 (dri2 is sufficient). So until the other issues are sorted lets remove DRIVER_PRIME. v2: also drop the dead code Signed-off-by: Rob Clark --- drivers/gpu/drm/vgem/Makefile | 2 +- drivers/gpu/drm/vgem/vgem_dma_buf.c | 94 - drivers/gpu/drm/vgem/vgem_drv.c | 11 + drivers/gpu/drm/vgem/vgem_drv.h | 11 - 4 files changed, 2 insertions(+), 116 deletions(-) delete mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c diff --git a/drivers/gpu/drm/vgem/Makefile b/drivers/gpu/drm/vgem/Makefile index 1055cb7..3f4c7b8 100644 --- a/drivers/gpu/drm/vgem/Makefile +++ b/drivers/gpu/drm/vgem/Makefile @@ -1,4 +1,4 @@ ccflags-y := -Iinclude/drm -vgem-y := vgem_drv.o vgem_dma_buf.o +vgem-y := vgem_drv.o obj-$(CONFIG_DRM_VGEM) += vgem.o diff --git a/drivers/gpu/drm/vgem/vgem_dma_buf.c b/drivers/gpu/drm/vgem/vgem_dma_buf.c deleted file mode 100644 index 0254438..000 --- a/drivers/gpu/drm/vgem/vgem_dma_buf.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2014 The Chromium OS Authors - * - * 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. - * - * Authors: - *Ben Widawsky - * - */ - -#include -#include "vgem_drv.h" - -struct sg_table *vgem_gem_prime_get_sg_table(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - BUG_ON(obj->pages == NULL); - - return drm_prime_pages_to_sg(obj->pages, obj->base.size / PAGE_SIZE); -} - -int vgem_gem_prime_pin(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - return vgem_gem_get_pages(obj); -} - -void vgem_gem_prime_unpin(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - vgem_gem_put_pages(obj); -} - -void *vgem_gem_prime_vmap(struct drm_gem_object *gobj) -{ - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); - BUG_ON(obj->pages == NULL); - - return vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL); -} - -void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) -{ - vunmap(vaddr); -} - -struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev, -struct dma_buf *dma_buf) -{ - struct drm_vgem_gem_object *obj = NULL; - int ret; - - obj = kzalloc(sizeof(*obj), GFP_KERNEL); - if (obj == NULL) { - ret = -ENOMEM; - goto fail; - } - - ret = drm_gem_object_init(dev, &obj->base, dma_buf->size); - if (ret) { - ret = -ENOMEM; - goto fail_free; - } - - get_dma_buf(dma_buf); - - obj->base.dma_buf = dma_buf; - obj->use_dma_buf = true; - - return &obj->base; - -fail_free: - kfree(obj); -fail: - return ERR_PTR(ret); -} diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index cb3b435..7a207ca 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -302,22 +302,13 @@ static const struct file_operations vgem_driver_fops = { }; static struct drm_driver vgem_driver = { - .driver_features= DRIVER_GEM | DRIVER_PRIME, + .driver_features= DRIVER_GEM, .gem_free_object= vgem_gem_free_object, .gem_vm_ops = &vgem_gem_vm_ops, .ioctls = vgem_ioctls, .fops = &vgem_driver_fops, .dumb_create= vgem_g
4.1-rc4 display-port on radeon not working
On 05/21/15 00:04, Alex Deucher wrote: > On Wed, May 20, 2015 at 12:57 PM, Malte Schröder wrote: >> On 05/20/15 17:37, Alex Deucher wrote: >>> On Tue, May 19, 2015 at 6:03 PM, Malte Schröder wrote: >>>> Hi, >>>> with 4.1-rc display-port on my Tahiti XT stopped working. I used the >>>> firmware from http://people.freedesktop.org/~agd5f/radeon_ucode/ as of >>>> today. >>>> Note: the display is an Asus PB278, it used to have problems with >>>> display port negotiation, but those disappeared like a year ago. >>>> >>> >>> Does booting with radeon.auxch=0 on the kernel command line in grub >>> help? Can you bisect? >>> >>> Alex >>> >> >> Yes, radeon.auxch=0 helps. As for bisecting, I can try, but I won't have >> time for that until next week. > > No need to bisect. if auxch=0 helps, I know what commit broke it. > Does the attached patch help? Yes, this patch does fix the problem for me :) > > Alex -- Gruà Malte Schröder - MalteSch at gmx.de -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20150521/6f5eb24f/attachment-0001.sig>
[PATCH] drm: atmel_hlcdc: Add support for get_timings
drm_panel supports querying timing ranges. If the supplied mode does not work with the hlcdc we query the panel and try to find a suitable mode. Signed-off-by: David Dueck --- drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c | 118 +++ 1 file changed, 98 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c index 9c45130..ea36c24 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -78,6 +79,8 @@ drm_encoder_to_atmel_hlcdc_rgb_output(struct drm_encoder *encoder) struct atmel_hlcdc_panel { struct atmel_hlcdc_rgb_output base; struct drm_panel *panel; + struct display_timing *timings; + unsigned int num_timings; }; static inline struct atmel_hlcdc_panel * @@ -104,14 +107,6 @@ static void atmel_hlcdc_panel_encoder_disable(struct drm_encoder *encoder) drm_panel_disable(panel->panel); } -static bool -atmel_hlcdc_panel_encoder_mode_fixup(struct drm_encoder *encoder, -const struct drm_display_mode *mode, -struct drm_display_mode *adjusted) -{ - return true; -} - static void atmel_hlcdc_rgb_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, @@ -142,8 +137,86 @@ atmel_hlcdc_rgb_encoder_mode_set(struct drm_encoder *encoder, cfg); } +/** + * atmel_hlcdc_choose_parameter - choose timing parameter + * @dc_min: minimum parameter value allowed by dc + * @dc_max: maximum parameter value allowed by dc + * @te: parameter range allowed by panel + * @result: chosen parameter + * + * DESCRIPTION: + * If there is overlap in the allowed ranges, we will pick a parameter + * minimizing the distance to te.typ. If not, we return te.min or te.max. + **/ +static u32 atmel_hlcdc_choose_parameter(u32 dc_min, u32 dc_max, + struct timing_entry te) +{ + if (te.typ <= dc_max && te.typ >= dc_min) + return te.typ; + else if (te.typ > dc_max) + return max(dc_max, te.min); + else + return min(dc_min, te.max); +} + +static void atmel_hlcdc_calculate_mode(struct display_timing *timings, + struct drm_display_mode *adjusted_mode) +{ + u32 hsync_len, hfront_porch, hback_porch; + u32 vsync_len, vfront_porch, vback_porch; + + hsync_len = atmel_hlcdc_choose_parameter(1, 0x40, timings->hsync_len); + vsync_len = atmel_hlcdc_choose_parameter(1, 0x40, timings->vsync_len); + + hfront_porch = atmel_hlcdc_choose_parameter(1, 0x200, + timings->hfront_porch); + hback_porch = atmel_hlcdc_choose_parameter(1, 0x200, + timings->hback_porch); + vfront_porch = atmel_hlcdc_choose_parameter(1, 0x40, + timings->vfront_porch); + vback_porch = atmel_hlcdc_choose_parameter(0, 0x40, + timings->vback_porch); + + adjusted_mode->hsync_start = adjusted_mode->hdisplay + hfront_porch; + adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_len; + adjusted_mode->htotal = adjusted_mode->hsync_end + hback_porch; + + adjusted_mode->vsync_start = adjusted_mode->vdisplay + vfront_porch; + adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_len; + adjusted_mode->vtotal = adjusted_mode->vsync_end + vback_porch; +} + +static int +atmel_hlcdc_panel_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct atmel_hlcdc_rgb_output *rgb = + drm_encoder_to_atmel_hlcdc_rgb_output(encoder); + struct atmel_hlcdc_panel *panel = atmel_hlcdc_rgb_output_to_panel(rgb); + struct drm_display_mode *mode = &crtc_state->mode; + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + int i; + + if (atmel_hlcdc_dc_mode_valid(rgb->dc, mode) == MODE_OK) + return 0; + + for (i = 0; i < panel->num_timings; i++) { + if (panel->timings->hactive.typ != mode->hdisplay || + panel->timings->vactive.typ != mode->vdisplay) + continue; + + atmel_hlcdc_calculate_mode(panel->timings, adjusted_mode); + if (atmel_hlcdc_dc_mode_valid(rgb->dc, adjusted_mode) == + MODE_OK) + return 0; + } + + return -EINVAL; +} + static struct drm_encoder_helper_funcs atmel_hlcdc_panel_e
[PATCH v5 09/12] drm/exynos: remove exported functions from exynos_drm_plane
2015-05-21 Tobias Jakobi : > Hi, > > like I said before, this clashes with my commit 'drm/exynos: plane: honor > buffer offset for dma_addr' (5d878bdb51bd7915ba3def8b531238c67624aa58), > which is currently sitting in airlied's drm-fixes. Inki has to merge his -fixes tree into exynos-drm-next to solve this. It is the only way I can rebase on top of your commit and solve the conflict. Anyway, I just figured that exynos-drm-next was updated from yesterday to today so this v5 doesn't apply on today's tree. I'll send a v6 once Inki merges "drm/exynos: plane: honor buffer offset for dma_addr" into exynos-drm-next. Inki, can you please do that? so we can proceed with atomic and hopefully have it ready for 4.2 merge window. Gustavo
[PATCH v5 1/3] drm/layerscape: Add Freescale DCU DRM driver
Hi Dave, Can you help me review this patch please? Thanks. Jianwei > -Original Message- > From: Wang Jianwei-B52261 > Sent: Thursday, May 07, 2015 2:29 PM > To: Wang Jianwei-B52261; airlied at linux.ie; daniel.vetter at intel.com; > stefan at agner.ch; Wood Scott-B07421; dri-devel at lists.freedesktop.org > Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org; > Jin Zhengxiong-R64188; Wang Huan-B18965; Xiubo Li > Subject: RE: [PATCH v5 1/3] drm/layerscape: Add Freescale DCU DRM driver > > Hi Dave, > > Can you help me to review this patch? Thanks. > > Jianwei > > > -Original Message- > > From: Jianwei Wang [mailto:jianwei.wang at freescale.com] > > Sent: Friday, April 17, 2015 2:36 PM > > To: airlied at linux.ie; daniel.vetter at intel.com; stefan at agner.ch; > > Wood > > Scott-B07421; dri-devel at lists.freedesktop.org > > Cc: linux-kernel at vger.kernel.org; linux-arm-kernel at > > lists.infradead.org; > > Jin Zhengxiong-R64188; Wang Jianwei-B52261; Wang Huan-B18965; Xiubo Li; > > Wang Jianwei-B52261 > > Subject: [PATCH v5 1/3] drm/layerscape: Add Freescale DCU DRM driver > > > > From: Jianwei Wang > > > > This patch add support for Two Dimensional Animation and Compositing > > Engine (2D-ACE) on the Freescale SoCs. > > > > 2D-ACE is a Freescale display controller. 2D-ACE describes the > > functionality of the module extremely well its name is a value that > cannot > > be used as a token in programming languages. > > Instead the valid token "DCU" is used to tag the register names and > > function names. > > > > The Display Controller Unit (DCU) module is a system master that fetches > > graphics stored in internal or external memory and displays them on a > TFT > > LCD panel. A wide range of panel sizes is supported and the timing of > the > > interface signals is highly configurable. > > Graphics are read directly from memory and then blended in real-time, > > which allows for dynamic content creation with minimal CPU intervention. > > > > The features: > > (1) Full RGB888 output to TFT LCD panel. > > (2) For the current LCD panel, WQVGA "480x272" is supported. > > (3) Blending of each pixel using up to 4 source layers dependent on size > > of panel. > > (4) Each graphic layer can be placed with one pixel resolution in either > > axis. > > (5) Each graphic layer support RGB565 and RGB888 direct colors without > > alpha channel and BGRA BGRA ARGB1555 direct colors with an alpha > > channel and YUV422 format. > > (6) Each graphic layer support alpha blending with 8-bit resolution. > > > > This is a simplified version, only one primary plane, one framebuffer > > created for fbdev, one crtc, one connector for TFT LCD panel, an encoder. > > > > Signed-off-by: Alison Wang > > Signed-off-by: Xiubo Li > > Signed-off-by: Jianwei Wang > > --- > > > > Changed in V5 > > > > - Update commit message > > - Add layer registers initialization > > - Remove unused functions > > - Rename driver folder > > - Move pixel clock control functions to fsl_dcu_drm_drv.c > > - remove redundant enable the clock implicitly using regmap > > - Add maintainer message > > > > Changed in V4: > > > > -This version doesn't have functionality changed Just a minor > adjustment. > > > > Changed in V3: > > > > - Test driver on Vybrid board and add compatible string > > - Remove unused functions > > - set default crtc for encoder > > - replace legacy functions with atomic help functions > > - Set the unique name of the DRM device > > - Implement irq handle function for vblank interrupt > > > > Changed in v2: > > - Add atomic support > > - Modify bindings file > > - Rename node for compatibility > > - Move platform related code out for compatibility > > > > .../devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt| 50 +++ > > MAINTAINERS| 8 + > > drivers/gpu/drm/Kconfig| 2 + > > drivers/gpu/drm/Makefile | 1 + > > drivers/gpu/drm/fsl-dcu/Kconfig| 17 + > > drivers/gpu/drm/fsl-dcu/Makefile | 7 + > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c| 194 +++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h| 30 ++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 172 ++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h | 22 ++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 373 > > + > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 223 > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c| 26 ++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c | 42 +++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h | 17 + > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c| 192 +++ > > drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h| 23 ++ > > 17 files changed, 1399 insertions(+) > > create mode 100644 Documentation/devicetree/bind
[PATCH] ARM: dts: exynos4412-trats2: set display clock correctly
On 05/20/15 09:12, Krzysztof Kozlowski wrote: > 2015-02-07 19:49 GMT+09:00 Inki Dae : >> This patch sets display clock correctly. >> >> If Display clock isn't set correctly then you would find below messages >> and Display controller doesn't work correctly since a patch[1] >> >>exynos-drm: No connectors reported connected with modes >>[drm] Cannot find any crtc or sizes - going 1024x768 >> >> [1] commit abc0b1447d49 ("drm: Perform basic sanity checks on probed modes") > > Reviewed-by: Krzysztof Kozlowski > Tested-by: Krzysztof Kozlowski > > Tested on Trats2 board. > > Dear Kukjin, > > Could you pull it to current fixes branch (this RC cycle)? The patch > fixes display on Trats2 board. Without it (since abc0b1447d49) it > won't be properly set up and device boots with blank screen and > mentioned error message in logs. > > I think this actually is a candidate for stable backporting (4.0+) > because it fixes important functionality of device: > > Fixes: abc0b1447d49 ("drm: Perform basic sanity checks on probed modes") > Cc: > Thanks, applied, and will be sent out in a day for v4.1-rc. - Kukjin
[PATCH 3/4] drm/tegra: Add VIC support
On 05/21/2015 06:10 PM, Arto Merilainen wrote: > ... >>> + >>> +vic->rst = devm_reset_control_get(dev, "vic03"); >> >> I might prefer just "vic" as the clock/reset name. The name is often >> used as a sort of "role" for the clock/reset for the device, not >> necessarily the raw name of the "correct" clock/reset. >> > > I considered that - but I then noticed that > drivers/clk/tegra/clk-tegra124.c was already using vic03 variant. I can > write a patch for changing that too. Well, the two can be different; the clock-name in device tree kind of means "string that i use to refer to a clock that powers the VIC unit". It's not really a big deal though, both ways are used in DT bindings. Mikko
[PATCH] drm/exynos: use drm_atomic_state directly
Just ignore this one. The patch file was by mistake in the same folder as the atomic ones. It is part of a patchset that will come out later. Gustavo 2015-05-21 Gustavo Padovan : > From: Gustavo Padovan > > Instead of use duplicated information stored on struct exynos_drm_plane > use the atomic state directly to have a more clear understanding and clean > code. > > Signed-off-by: Gustavo Padovan > --- > drivers/gpu/drm/exynos/exynos7_drm_decon.c | 49 ++-- > drivers/gpu/drm/exynos/exynos_drm_drv.h| 51 - > drivers/gpu/drm/exynos/exynos_drm_fimd.c | 47 ++-- > drivers/gpu/drm/exynos/exynos_drm_plane.c | 86 ++--- > drivers/gpu/drm/exynos/exynos_mixer.c | 116 > ++--- > 5 files changed, 131 insertions(+), 218 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos7_drm_decon.c > b/drivers/gpu/drm/exynos/exynos7_drm_decon.c > index ed4461f..612ee29 100644 > --- a/drivers/gpu/drm/exynos/exynos7_drm_decon.c > +++ b/drivers/gpu/drm/exynos/exynos7_drm_decon.c > @@ -281,16 +281,16 @@ static void decon_disable_vblank(struct exynos_drm_crtc > *crtc) > } > } > > -static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win) > +static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, > + struct drm_framebuffer *fb) > { > - struct exynos_drm_plane *plane = &ctx->planes[win]; > unsigned long val; > int padding; > > val = readl(ctx->regs + WINCON(win)); > val &= ~WINCONx_BPPMODE_MASK; > > - switch (plane->pixel_format) { > + switch (fb->pixel_format) { > case DRM_FORMAT_RGB565: > val |= WINCONx_BPPMODE_16BPP_565; > val |= WINCONx_BURSTLEN_16WORD; > @@ -339,7 +339,7 @@ static void decon_win_set_pixfmt(struct decon_context > *ctx, unsigned int win) > break; > } > > - DRM_DEBUG_KMS("bpp = %d\n", plane->bpp); > + DRM_DEBUG_KMS("bpp = %d\n", fb->bits_per_pixel); > > /* >* In case of exynos, setting dma-burst to 16Word causes permanent > @@ -349,8 +349,8 @@ static void decon_win_set_pixfmt(struct decon_context > *ctx, unsigned int win) >* movement causes unstable DMA which results into iommu crash/tear. >*/ > > - padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; > - if (plane->fb_width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { > + padding = (fb->pitches[0] / (fb->bits_per_pixel >> 3)) - fb->width; > + if (fb->width + padding < MIN_FB_WIDTH_FOR_16WORD_BURST) { > val &= ~WINCONx_BURSTLEN_MASK; > val |= WINCONx_BURSTLEN_8WORD; > } > @@ -396,12 +396,15 @@ static void decon_update_plane(struct exynos_drm_crtc > *crtc, > struct exynos_drm_plane *plane) > { > struct decon_context *ctx = crtc->ctx; > + struct drm_plane_state *state = plane->base.state; > struct drm_display_mode *mode = &crtc->base.mode; > int padding; > unsigned long val, alpha; > unsigned int last_x; > unsigned int last_y; > unsigned int win = plane->zpos; > + unsigned int bpp = state->fb->bits_per_pixel >> 3; > + unsigned int pitch = state->fb->pitches[0]; > > /* If suspended, enable this on resume */ > if (ctx->suspended) { > @@ -426,38 +429,38 @@ static void decon_update_plane(struct exynos_drm_crtc > *crtc, > val = (unsigned long)plane->dma_addr[0]; > writel(val, ctx->regs + VIDW_BUF_START(win)); > > - padding = (plane->pitch / (plane->bpp >> 3)) - plane->fb_width; > + padding = (pitch / bpp) - state->fb->width; > > /* buffer size */ > - writel(plane->fb_width + padding, ctx->regs + VIDW_WHOLE_X(win)); > - writel(plane->fb_height, ctx->regs + VIDW_WHOLE_Y(win)); > + writel(state->fb->width + padding, ctx->regs + VIDW_WHOLE_X(win)); > + writel(state->fb->height, ctx->regs + VIDW_WHOLE_Y(win)); > > /* offset from the start of the buffer to read */ > - writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win)); > - writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win)); > + writel(state->src_x, ctx->regs + VIDW_OFFSET_X(win)); > + writel(state->src_y, ctx->regs + VIDW_OFFSET_Y(win)); > > DRM_DEBUG_KMS("start addr = 0x%lx\n", > (unsigned long)val); > - DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", > - plane->crtc_width, plane->crtc_height); > + DRM_DEBUG_KMS("crtc_w = %d, crtc_h = %d\n", > + state->crtc_w, state->crtc_h); > > /* >* OSD position. >* In case the window layout goes of LCD layout, DECON fails. >*/ > - if ((plane->crtc_x + plane->crtc_width) > mode->hdisplay) > - plane->crtc_x = mode->hdisplay - plane->crtc_width; > - if ((plane->crtc_y + plane->crtc_height) > mode->vdisplay) > -
[PATCH 3/4] drm/tegra: Add VIC support
Hi, very good patch! Here are a few small comments. Aside those, you should also add a section to Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt in a separate patch. Thanks, Mikko. On 05/21/2015 04:20 PM, Arto Merilainen wrote: > This patch adds support for Video Image Compositor engine which > can be used for 2d operations. > > The engine has a microcontroller (Falcon) that acts as a frontend > for the rest of the unit. In order to properly utilize the engine, > the frontend must be booted before pushing any commands. > > Signed-off-by: Andrew Chew > Signed-off-by: Arto Merilainen > --- > drivers/gpu/drm/tegra/Makefile | 3 +- > drivers/gpu/drm/tegra/drm.c| 9 +- > drivers/gpu/drm/tegra/drm.h| 1 + > drivers/gpu/drm/tegra/vic.c| 593 > + > drivers/gpu/drm/tegra/vic.h| 116 > include/linux/host1x.h | 1 + > 6 files changed, 721 insertions(+), 2 deletions(-) > create mode 100644 drivers/gpu/drm/tegra/vic.c > create mode 100644 drivers/gpu/drm/tegra/vic.h > > diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile > index 2c66a8db9da4..3bc3566e00b6 100644 > --- a/drivers/gpu/drm/tegra/Makefile > +++ b/drivers/gpu/drm/tegra/Makefile > @@ -13,6 +13,7 @@ tegra-drm-y := \ > sor.o \ > dpaux.o \ > gr2d.o \ > - gr3d.o > + gr3d.o \ > + vic.o > > obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o > diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c > index bfad15a913a0..d947f5f4d801 100644 > --- a/drivers/gpu/drm/tegra/drm.c > +++ b/drivers/gpu/drm/tegra/drm.c > @@ -1,6 +1,6 @@ > /* > * Copyright (C) 2012 Avionic Design GmbH > - * Copyright (C) 2012-2013 NVIDIA CORPORATION. All rights reserved. > + * Copyright (C) 2012-2015 NVIDIA CORPORATION. All rights reserved. > * > * This program is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License version 2 as > @@ -1048,6 +1048,7 @@ static const struct of_device_id host1x_drm_subdevs[] = > { > { .compatible = "nvidia,tegra124-dc", }, > { .compatible = "nvidia,tegra124-sor", }, > { .compatible = "nvidia,tegra124-hdmi", }, > + { .compatible = "nvidia,tegra124-vic", }, > { /* sentinel */ } > }; > > @@ -1097,8 +1098,14 @@ static int __init host1x_drm_init(void) > if (err < 0) > goto unregister_gr2d; > > + err = platform_driver_register(&tegra_vic_driver); > + if (err < 0) > + goto unregister_gr3d; > + > return 0; > > +unregister_gr3d: > + platform_driver_unregister(&tegra_gr3d_driver); > unregister_gr2d: > platform_driver_unregister(&tegra_gr2d_driver); > unregister_dpaux: > diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h > index 0e7756e720c5..a9c02a80d6bf 100644 > --- a/drivers/gpu/drm/tegra/drm.h > +++ b/drivers/gpu/drm/tegra/drm.h > @@ -275,5 +275,6 @@ extern struct platform_driver tegra_hdmi_driver; > extern struct platform_driver tegra_dpaux_driver; > extern struct platform_driver tegra_gr2d_driver; > extern struct platform_driver tegra_gr3d_driver; > +extern struct platform_driver tegra_vic_driver; > > #endif /* HOST1X_DRM_H */ > diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c > new file mode 100644 > index ..b7c5a96697ed > --- /dev/null > +++ b/drivers/gpu/drm/tegra/vic.c > @@ -0,0 +1,593 @@ > +/* > + * Copyright (c) 2015, NVIDIA Corporation. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "drm.h" > +#include "gem.h" > +#include "vic.h" > + > +#define VIC_IDLE_TIMEOUT_DEFAULT 1 /* 10 milliseconds */ > +#define VIC_IDLE_CHECK_PERIOD10 /* 10 usec */ > + > +struct vic; This doesn't seem to be needed here. > + > +struct vic_config { > + /* firmware name */ > + char *ucode_name; > + > + /* class id */ > + u32 class_id; > + > + /* powergate id */ > + int powergate_id; > +}; > + > +struct vic { > + struct { > + u32 bin_data_offset; > + u32 data_offset; > + u32 data_size; > + u32 code_offset; > + u32 size; > + } os, fce; > + > + struct tegra_bo *ucode_bo; > + bool ucode_valid; > + void *ucode_vaddr; > + > + bool booted; > + > + void __iomem *regs; > + struct tegra_drm_client client; > + struct host1x_channel *channel; > + struct iommu_domain *domain; > + struct device *dev; > + struct clk *clk; > + struct reset_control *rst; > + > + /* Platform configuration */ > + struct vic_config *config; > + >
[PATCH] drm/vgem: drop DRIVER_PRIME (v2)
On Thu, May 21, 2015 at 11:58:30AM -0400, Rob Clark wrote: > For actual sharing of buffers with other drivers (ie. actual hardware) > we'll need to pimp things out a bit better to deal w/ caching, multiple > memory domains, etc. See thread: > > http://lists.freedesktop.org/archives/dri-devel/2015-May/083160.html > > But for the llvmpipe use-case this isn't a problem. Nor do we really > need prime/dri3 (dri2 is sufficient). So until the other issues are > sorted lets remove DRIVER_PRIME. > > v2: also drop the dead code > > Signed-off-by: Rob Clark Yeah I'm ok with this too, but it pretty much means vgem is a thing for llvmpipe only. And then abusing dumb buffers is imo ok too, since I don't care too much what kind of horrors drivers pull of internally. Acked-by: Daniel Vetter > --- > drivers/gpu/drm/vgem/Makefile | 2 +- > drivers/gpu/drm/vgem/vgem_dma_buf.c | 94 > - > drivers/gpu/drm/vgem/vgem_drv.c | 11 + > drivers/gpu/drm/vgem/vgem_drv.h | 11 - > 4 files changed, 2 insertions(+), 116 deletions(-) > delete mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c > > diff --git a/drivers/gpu/drm/vgem/Makefile b/drivers/gpu/drm/vgem/Makefile > index 1055cb7..3f4c7b8 100644 > --- a/drivers/gpu/drm/vgem/Makefile > +++ b/drivers/gpu/drm/vgem/Makefile > @@ -1,4 +1,4 @@ > ccflags-y := -Iinclude/drm > -vgem-y := vgem_drv.o vgem_dma_buf.o > +vgem-y := vgem_drv.o > > obj-$(CONFIG_DRM_VGEM) += vgem.o > diff --git a/drivers/gpu/drm/vgem/vgem_dma_buf.c > b/drivers/gpu/drm/vgem/vgem_dma_buf.c > deleted file mode 100644 > index 0254438..000 > --- a/drivers/gpu/drm/vgem/vgem_dma_buf.c > +++ /dev/null > @@ -1,94 +0,0 @@ > -/* > - * Copyright © 2012 Intel Corporation > - * Copyright © 2014 The Chromium OS Authors > - * > - * 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. > - * > - * Authors: > - *Ben Widawsky > - * > - */ > - > -#include > -#include "vgem_drv.h" > - > -struct sg_table *vgem_gem_prime_get_sg_table(struct drm_gem_object *gobj) > -{ > - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); > - BUG_ON(obj->pages == NULL); > - > - return drm_prime_pages_to_sg(obj->pages, obj->base.size / PAGE_SIZE); > -} > - > -int vgem_gem_prime_pin(struct drm_gem_object *gobj) > -{ > - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); > - return vgem_gem_get_pages(obj); > -} > - > -void vgem_gem_prime_unpin(struct drm_gem_object *gobj) > -{ > - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); > - vgem_gem_put_pages(obj); > -} > - > -void *vgem_gem_prime_vmap(struct drm_gem_object *gobj) > -{ > - struct drm_vgem_gem_object *obj = to_vgem_bo(gobj); > - BUG_ON(obj->pages == NULL); > - > - return vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL); > -} > - > -void vgem_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) > -{ > - vunmap(vaddr); > -} > - > -struct drm_gem_object *vgem_gem_prime_import(struct drm_device *dev, > - struct dma_buf *dma_buf) > -{ > - struct drm_vgem_gem_object *obj = NULL; > - int ret; > - > - obj = kzalloc(sizeof(*obj), GFP_KERNEL); > - if (obj == NULL) { > - ret = -ENOMEM; > - goto fail; > - } > - > - ret = drm_gem_object_init(dev, &obj->base, dma_buf->size); > - if (ret) { > - ret = -ENOMEM; > - goto fail_free; > - } > - > - get_dma_buf(dma_buf); > - > - obj->base.dma_buf = dma_buf; > - obj->use_dma_buf = true; > - > - return &obj->base; > - > -fail_free: > - kfree(obj); > -fail: > - return ERR_PTR(ret); > -} > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c > index cb3b435..7a207ca 100644 > --- a/drivers/gpu/drm/vgem/vgem_drv.c > +++ b/drivers/gpu/drm/vgem/vgem_drv.c > @@ -302,22 +30
[PATCH] drm/vgem: drop DRIVER_PRIME (v2)
On Thu, May 21, 2015 at 06:07:30PM +0200, Daniel Vetter wrote: > On Thu, May 21, 2015 at 11:58:30AM -0400, Rob Clark wrote: > > For actual sharing of buffers with other drivers (ie. actual hardware) > > we'll need to pimp things out a bit better to deal w/ caching, multiple > > memory domains, etc. See thread: > > > > http://lists.freedesktop.org/archives/dri-devel/2015-May/083160.html > > > > But for the llvmpipe use-case this isn't a problem. Nor do we really > > need prime/dri3 (dri2 is sufficient). So until the other issues are > > sorted lets remove DRIVER_PRIME. > > > > v2: also drop the dead code > > > > Signed-off-by: Rob Clark > > Yeah I'm ok with this too, but it pretty much means vgem is a thing for > llvmpipe only. And then abusing dumb buffers is imo ok too, since I don't > care too much what kind of horrors drivers pull of internally. Ugh. But llvmpipe + dumb buffer is much inferior to SHM. -Chris -- Chris Wilson, Intel Open Source Technology Centre
[PATCH v5 09/12] drm/exynos: remove exported functions from exynos_drm_plane
2015-05-21 Gustavo Padovan : > 2015-05-21 Tobias Jakobi : > > > Hi, > > > > like I said before, this clashes with my commit 'drm/exynos: plane: honor > > buffer offset for dma_addr' (5d878bdb51bd7915ba3def8b531238c67624aa58), > > which is currently sitting in airlied's drm-fixes. > > Inki has to merge his -fixes tree into exynos-drm-next to solve this. > It is the only way I can rebase on top of your commit and solve the > conflict. > Anyway, I just figured that exynos-drm-next was updated from yesterday > to today so this v5 doesn't apply on today's tree. I'll send a v6 once > Inki merges "drm/exynos: plane: honor buffer offset for dma_addr" into > exynos-drm-next. > > Inki, can you please do that? so we can proceed with atomic and > hopefully have it ready for 4.2 merge window. Actually the patch is on exynos-drm-next but with a different commit id. I wonder why. Why did you applied it directly to your branch instead of merging the -fixes tree? Now we have the same commit with the differents hashes in the tree. Gustavo
[PATCH] drm/vgem: drop DRIVER_PRIME (v2)
On Thu, May 21, 2015 at 12:10 PM, Chris Wilson wrote: > On Thu, May 21, 2015 at 06:07:30PM +0200, Daniel Vetter wrote: >> On Thu, May 21, 2015 at 11:58:30AM -0400, Rob Clark wrote: >> > For actual sharing of buffers with other drivers (ie. actual hardware) >> > we'll need to pimp things out a bit better to deal w/ caching, multiple >> > memory domains, etc. See thread: >> > >> > http://lists.freedesktop.org/archives/dri-devel/2015-May/083160.html >> > >> > But for the llvmpipe use-case this isn't a problem. Nor do we really >> > need prime/dri3 (dri2 is sufficient). So until the other issues are >> > sorted lets remove DRIVER_PRIME. >> > >> > v2: also drop the dead code >> > >> > Signed-off-by: Rob Clark >> >> Yeah I'm ok with this too, but it pretty much means vgem is a thing for >> llvmpipe only. And then abusing dumb buffers is imo ok too, since I don't >> care too much what kind of horrors drivers pull of internally. > > Ugh. But llvmpipe + dumb buffer is much inferior to SHM. it is using shmem for it's dumb buffers.. although I noticed it was mapping writecombine which is probably not what is wanted.. BR, -R > -Chris > > -- > Chris Wilson, Intel Open Source Technology Centre
[PATCH] drm/vgem: drop DRIVER_PRIME (v2)
On 05/21/2015 06:07 PM, Daniel Vetter wrote: > On Thu, May 21, 2015 at 11:58:30AM -0400, Rob Clark wrote: >> For actual sharing of buffers with other drivers (ie. actual hardware) >> we'll need to pimp things out a bit better to deal w/ caching, multiple >> memory domains, etc. See thread: >> >> >> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_archives_dri-2Ddevel_2015-2DMay_083160.html&d=AwIDAw&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=vpukPkBtpoNQp2IUKuFviOmPNYWVKmen3Jeeu55zmEA&m=5PY5xMHJsYyknpy_IWAegxqACOaf4x60CKosyG0oxCw&s=ciVeRE10840cewxQSgbJ_4YfCH6tU8A1o58k0tHgkD8&e= >> >> >> But for the llvmpipe use-case this isn't a problem. Nor do we really >> need prime/dri3 (dri2 is sufficient). So until the other issues are >> sorted lets remove DRIVER_PRIME. >> >> v2: also drop the dead code >> >> Signed-off-by: Rob Clark > Yeah I'm ok with this too, but it pretty much means vgem is a thing for > llvmpipe only. And then abusing dumb buffers is imo ok too, since I don't > care too much what kind of horrors drivers pull of internally. > > Acked-by: Daniel Vetter > > Well in the end, I'm happy whatever way as long as the root problem is solved. Acked-by: Thomas Hellstrom
[PATCH v5 09/12] drm/exynos: remove exported functions from exynos_drm_plane
Gustavo Padovan wrote: > 2015-05-21 Gustavo Padovan : > >> 2015-05-21 Tobias Jakobi : >> >>> Hi, >>> >>> like I said before, this clashes with my commit 'drm/exynos: plane: honor >>> buffer offset for dma_addr' (5d878bdb51bd7915ba3def8b531238c67624aa58), >>> which is currently sitting in airlied's drm-fixes. >> >> Inki has to merge his -fixes tree into exynos-drm-next to solve this. >> It is the only way I can rebase on top of your commit and solve the >> conflict. >> Anyway, I just figured that exynos-drm-next was updated from yesterday >> to today so this v5 doesn't apply on today's tree. I'll send a v6 once >> Inki merges "drm/exynos: plane: honor buffer offset for dma_addr" into >> exynos-drm-next. >> >> Inki, can you please do that? so we can proceed with atomic and >> hopefully have it ready for 4.2 merge window. > > Actually the patch is on exynos-drm-next but with a different commit id. > I wonder why. Why did you applied it directly to your branch instead of > merging the -fixes tree? Now we have the same commit with the differents > hashes in the tree. I never do merges for my tree, I always rebase (either on stable/linux or torvalds/master). For submitting patches I cherry-pick stuff to the corresponding upstream branch (exynos-drm-next in this case) and then submit via git-send-email. With best wishes, Tobias > > Gustavo >