From 0c71091230a80731bec3d2752b95d757c0a78bf9 Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Fri, 21 May 2021 17:03:40 -0400 Subject: [PATCH 1/2] soc: qcom: hgsl: Skip DBQ memory initialization DBQ should not be reinitialized when hgsl starts and should rely on HOST do reset at allocation. This fix can address the failure case under GVM restart scenario. Change-Id: I5c430198efc0e62b527b16a3400684a5ad9d77d3 Signed-off-by: Thomas (Wonyoung) Yun Signed-off-by: Jie Feng --- drivers/soc/qcom/hgsl/hgsl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/soc/qcom/hgsl/hgsl.c b/drivers/soc/qcom/hgsl/hgsl.c index c08caaf8b42b..e505cdce1797 100644 --- a/drivers/soc/qcom/hgsl/hgsl.c +++ b/drivers/soc/qcom/hgsl/hgsl.c @@ -937,12 +937,6 @@ static int hgsl_dbq_init(struct file *filep, unsigned long arg) } WARN_ON(param.head_dwords < 2); - dbq_set_qindex((uint32_t *)dbq->vbase, - DBQ_WRITE_INDEX_IN_DWORD, 0); - - dbq_set_qindex((uint32_t *)dbq->vbase, - DBQ_READ_INDEX_IN_DWORD, 0); - dbq->data.vaddr = dbq->vbase + (param.queue_off_dwords << 2); dbq->data.dwords = param.queue_dwords; From 6203a077569fb430a6d6c315d0c1a0764b336c4b Mon Sep 17 00:00:00 2001 From: "Thomas (Wonyoung) Yun" Date: Fri, 21 May 2021 17:07:12 -0400 Subject: [PATCH 2/2] soc: qcom: hgsl: Support cooperative reset with DBQ Add synchronization logic between RGS and HGSL where it handles fault policy as well as hard reset. Change-Id: I72ff7bc3263a38b4cc8306342a02f96e9b95d529 Signed-off-by: Thomas (Wonyoung) Yun Signed-off-by: Jie Feng --- drivers/soc/qcom/hgsl/hgsl.c | 379 +++++++++++++++++++++++++---------- drivers/soc/qcom/hgsl/hgsl.h | 2 + 2 files changed, 278 insertions(+), 103 deletions(-) diff --git a/drivers/soc/qcom/hgsl/hgsl.c b/drivers/soc/qcom/hgsl/hgsl.c index e505cdce1797..c6ac5e5afe4c 100644 --- a/drivers/soc/qcom/hgsl/hgsl.c +++ b/drivers/soc/qcom/hgsl/hgsl.c @@ -26,11 +26,11 @@ #include #include #include - +#include #include "hgsl.h" #include "hgsl_tcsr.h" -#define HGSL_DEVICE_NAME "hgsl" +#define HGSL_DEVICE_NAME "hgsl" #define HGSL_DEV_NUM 1 /* Support upto 3 GVMs: 3 DBQs(Low/Medium/High priority) per GVM */ @@ -40,15 +40,15 @@ #define IORESOURCE_GMUCX "hgsl_reg_gmucx" /* Set-up profiling packets as needed by scope */ -#define CMDBATCH_PROFILING 0x00000010 +#define CMDBATCH_PROFILING 0x00000010 /* Ping the user of HFI when this command is done */ -#define CMDBATCH_NOTIFY 0x00000020 +#define CMDBATCH_NOTIFY 0x00000020 -#define CMDBATCH_EOF 0x00000100 +#define CMDBATCH_EOF 0x00000100 -/* timeout of waiting for free space of doorbell queue. */ -#define HGSL_IDLE_TIMEOUT msecs_to_jiffies(1000) +/* Max retry count of waiting for free space of doorbell queue. */ +#define HGSL_QFREE_MAX_RETRY_COUNT (500) #define GLB_DB_SRC_ISSUEIB_IRQ_ID_0 TCSR_SRC_IRQ_ID_0 #define GLB_DB_SRC_ISSUEIB_IRQ_ID_1 TCSR_SRC_IRQ_ID_1 #define GLB_DB_SRC_ISSUEIB_IRQ_ID_2 TCSR_SRC_IRQ_ID_2 @@ -76,78 +76,122 @@ struct db_buffer { #define QHDR_STATUS_INACTIVE 0x00 #define QHDR_STATUS_ACTIVE 0x01 -/* Updated by HGSL */ -#define DBQ_WRITE_INDEX_IN_DWORD 0 +#define HGSL_CONTEXT_NUM (128) +#define HGSL_SEND_MSG_MAX_RETRY_COUNT (150) -/* Updated by GMU */ -#define DBQ_READ_INDEX_IN_DWORD 1 +// Skip all commands from the bad context +#define HGSL_FT_POLICY_FLAG_KILL BIT(2) -#define HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD (1536 >> 2) -#define HGSL_DBQ_CONTEXT_INFO_BASE_OFFSET_IN_DWORD (2048 >> 2) +#define ALIGN_ADDRESS_4DWORD(addr) (((addr)+15) & ((long long) ~15)) +#define ALIGN_DWORD_ADDRESS_4DWORD(dwaddr) (ALIGN_ADDRESS_4DWORD((dwaddr) * \ + sizeof(uint32_t)) / sizeof(uint32_t)) -#define HGSL_CONTEXT_NUM 128 +enum HGSL_DBQ_METADATA_COMMAND_INFO { + HGSL_DBQ_METADATA_CONTEXT_INFO, + HGSL_DBQ_METADATA_QUEUE_INDEX, + HGSL_DBQ_METADATA_COOPERATIVE_RESET, +}; -/* Meta info for context */ -enum HGSL_DBQ_METADATA_INFO { - HGSL_DBQ_METADATA_CTXT_ID_IN_DWORD = 0x0, - HGSL_DBQ_METADATA_TIMESTAMP_IN_DWORD = 0x1, - HGSL_DBQ_METADATA_CTXT_DESTROY_IN_DWORD = 0x2, - HGSL_DBQ_METADATA_TOTAL_ENTITY_NUM, - /* The context metadata size is 2K in DBQ, - * so we can have maximum 4 dwords for each context - */ - HGSL_DBQ_METADATA_TOTAL_ENTITY_MAX = 0x4 +#define HGSL_DBQ_CONTEXT_ANY (0x0) +#define HGSL_DBQ_OFFSET_ZERO (0x0) + +#define HGSL_DBQ_WRITE_INDEX_OFFSET_IN_DWORD (0x0) +#define HGSL_DBQ_READ_INDEX_OFFSET_IN_DWORD (0x1) + +enum HGSL_DBQ_METADATA_COOPERATIVE_RESET_INFO { + HGSL_DBQ_HOST_TO_GVM_HARDRESET_REQ, + HGSL_DBQ_GVM_TO_HOST_HARDRESET_DISPATCH_IN_BUSY, +}; + +enum HGSL_DBQ_METADATA_CONTEXT_OFFSET_INFO { + HGSL_DBQ_CONTEXT_CONTEXT_ID_OFFSET_IN_DWORD, + HGSL_DBQ_CONTEXT_TIMESTAMP_OFFSET_IN_DWORD, + HGSL_DBQ_CONTEXT_DESTROY_OFFSET_IN_DWORD, + HGSL_DBQ_METADATA_CTXT_TOTAL_ENTITY_NUM, }; /* DBQ structure - * | IBs storage | reserved | w.idx/r.idx | ctxt.info| - * --------------------------------------------------------------------------- - * | [0] | [1K] | [1.5K] | [2K] | - * --------------------------------------------------------------------------- + * IBs storage | reserved | w.idx/r.idx | ctxt.info | hard reset | + * 0 1K 1.5K 2K 3.5K | + * | | | | | | */ -static inline void dbq_set_qindex(uint32_t *va_base, - uint32_t offset, - uint32_t value) -{ - uint32_t *dest; - dest = va_base + HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD + offset; - *dest = value; +#define HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD (1536 >> 2) +#define HGSL_DBQ_CONTEXT_INFO_BASE_OFFSET_IN_DWORD (2048 >> 2) +#define HGSL_DBQ_COOPERATIVE_RESET_INFO_BASE_OFFSET_IN_DWORD (3584 >> 2) + + +static inline bool _timestamp_retired(struct hgsl_context *ctxt, + unsigned int timestamp); + +static inline void set_context_timestamp(struct hgsl_context *ctxt, + unsigned int ts); +static void _signal_contexts(struct qcom_hgsl *hgsl); + +static int db_get_busy_state(void *dbq_base); +static void db_set_busy_state(void *dbq_base, int in_busy); + +static uint32_t hgsl_dbq_get_state_info(uint32_t *va_base, uint32_t command, + uint32_t ctxt_id, uint32_t offset) +{ + uint32_t *dest = NULL; + + switch (command) { + case HGSL_DBQ_METADATA_QUEUE_INDEX: + dest = (uint32_t *)(va_base + + HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD + + offset); + break; + case HGSL_DBQ_METADATA_CONTEXT_INFO: + dest = (uint32_t *)(va_base + + HGSL_DBQ_CONTEXT_INFO_BASE_OFFSET_IN_DWORD + + (HGSL_DBQ_METADATA_CTXT_TOTAL_ENTITY_NUM * + ctxt_id) + offset); + break; + case HGSL_DBQ_METADATA_COOPERATIVE_RESET: + dest = (uint32_t *)(va_base + + HGSL_DBQ_COOPERATIVE_RESET_INFO_BASE_OFFSET_IN_DWORD + + offset); + break; + default: + break; + } + + return *dest; } -static inline uint32_t dbq_get_qindex(uint32_t *va_base, - uint32_t offset) +static void hgsl_dbq_set_state_info(uint32_t *va_base, uint32_t command, + uint32_t ctxt_id, uint32_t offset, + uint32_t value) { - uint32_t *dest; - uint32_t val; + uint32_t *dest = NULL; - dest = va_base + HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD + offset; - - val = *dest; - - /* ensure read is done before return */ - rmb(); - return val; + switch (command) { + case HGSL_DBQ_METADATA_QUEUE_INDEX: + dest = (uint32_t *)(va_base + + HGSL_DBQ_HFI_Q_INDEX_BASE_OFFSET_IN_DWORD + + (HGSL_DBQ_METADATA_CTXT_TOTAL_ENTITY_NUM * + ctxt_id) + offset); + *dest = value; + break; + case HGSL_DBQ_METADATA_CONTEXT_INFO: + dest = (uint32_t *)(va_base + + HGSL_DBQ_CONTEXT_INFO_BASE_OFFSET_IN_DWORD + + (HGSL_DBQ_METADATA_CTXT_TOTAL_ENTITY_NUM * + ctxt_id) + offset); + *dest = value; + break; + case HGSL_DBQ_METADATA_COOPERATIVE_RESET: + dest = (uint32_t *)(va_base + + HGSL_DBQ_COOPERATIVE_RESET_INFO_BASE_OFFSET_IN_DWORD + + offset); + *dest = value; + break; + default: + break; + } } -static inline void dbq_update_ctxt_info(uint32_t *va_base, - uint32_t ctxt_id, - uint32_t offset, - uint32_t value) -{ - uint32_t *dest = (uint32_t *)(va_base + - HGSL_DBQ_CONTEXT_INFO_BASE_OFFSET_IN_DWORD + - (HGSL_DBQ_METADATA_TOTAL_ENTITY_NUM * ctxt_id) + - offset); - - if (WARN_ON(ctxt_id >= HGSL_CONTEXT_NUM)) - return; - - *dest = value; -} - -#define RGS_HFI_DEFAULT_TIMEOUT_MS 5000 - #define HFI_MSG_TYPE_CMD 0 #define HFI_MSG_TYPE_RET 1 @@ -215,6 +259,18 @@ struct hgsl_fw_ib_desc { uint32_t sz; } __packed; +struct hfi_msg_header_fields { + uint32_t msg_id : 8; ///< 0~127 power, 128~255 eCP + uint32_t msg_size_dword : 8; ///< unit in dword, maximum 255 + uint32_t msg_type : 4; ///< refer to adreno_hfi_msg_type_t + uint32_t msg_packet_seq_no : 12; +}; + +union hfi_msg_header { + uint32_t u32_all; + struct hfi_msg_header_fields fields; +}; + /* * Context ID * cmd_flags @@ -224,7 +280,7 @@ struct hgsl_fw_ib_desc { * An array of IB descriptors */ struct hgsl_db_cmds { - uint32_t header; + union hfi_msg_header header; uint32_t ctx_id; uint32_t cmd_flags; uint32_t timestamp; @@ -387,18 +443,23 @@ static uint32_t db_queue_freedwords(struct doorbell_queue *dbq) if (dbq == NULL) return 0; - wptr = dbq_get_qindex(dbq->vbase, DBQ_WRITE_INDEX_IN_DWORD); - rptr = dbq_get_qindex(dbq->vbase, DBQ_READ_INDEX_IN_DWORD); + wptr = hgsl_dbq_get_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_QUEUE_INDEX, HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_WRITE_INDEX_OFFSET_IN_DWORD); + + rptr = hgsl_dbq_get_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_QUEUE_INDEX, HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_READ_INDEX_OFFSET_IN_DWORD); queue_size = dbq->data.dwords; queue_used = (wptr + queue_size - rptr) % queue_size; return (queue_size - queue_used - 1); } -static int db_queue_wait_freewords(struct doorbell_queue *dbq, - uint32_t size) +static int db_queue_wait_freewords(struct doorbell_queue *dbq, uint32_t size) { - unsigned long t = jiffies + HGSL_IDLE_TIMEOUT; + unsigned int retry_count = 0; + unsigned int hard_reset_req = false; if (size == 0) return 0; @@ -407,13 +468,57 @@ static int db_queue_wait_freewords(struct doorbell_queue *dbq, return -EINVAL; do { - if (db_queue_freedwords(dbq) >= size) - return 0; - } while (time_before(jiffies, t)); + hard_reset_req = hgsl_dbq_get_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_COOPERATIVE_RESET, + HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_HOST_TO_GVM_HARDRESET_REQ); + + /* ensure read is done before comparison */ + rmb(); + + if (hard_reset_req == true) { + if (db_get_busy_state(dbq->vbase) == true) + db_set_busy_state(dbq->vbase, false); + } else { + if (db_queue_freedwords(dbq) >= size) { + db_set_busy_state(dbq->vbase, true); + return 0; + } + } + + udelay(1000); + } while (retry_count++ < HGSL_QFREE_MAX_RETRY_COUNT); return -ETIMEDOUT; } +static int db_get_busy_state(void *dbq_base) +{ + unsigned int busy_state = false; + + busy_state = hgsl_dbq_get_state_info((uint32_t *)dbq_base, + HGSL_DBQ_METADATA_COOPERATIVE_RESET, + HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_GVM_TO_HOST_HARDRESET_DISPATCH_IN_BUSY); + + /* ensure read is done before comparison */ + rmb(); + + return busy_state; +} + +static void db_set_busy_state(void *dbq_base, int in_busy) +{ + hgsl_dbq_set_state_info((uint32_t *)dbq_base, + HGSL_DBQ_METADATA_COOPERATIVE_RESET, + HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_GVM_TO_HOST_HARDRESET_DISPATCH_IN_BUSY, + in_busy); + + /* confirm write to memory done */ + wmb(); +} + static int db_send_msg(struct hgsl_priv *priv, struct db_msg_id *db_msg_id, struct db_msg_request *msg_req, @@ -427,11 +532,36 @@ static int db_send_msg(struct hgsl_priv *priv, struct qcom_hgsl *hgsl; struct doorbell_queue *dbq; uint32_t wptr; + struct hgsl_db_cmds *cmds; + int retry_count = 0; + uint32_t hard_reset_req = false; hgsl = priv->dev; dbq = &hgsl->dbq[priv->dbq_idx]; - mutex_lock(&hgsl->lock); + mutex_lock(&dbq->lock); + + cmds = (struct hgsl_db_cmds *)msg_req->ptr_data; + do { + hard_reset_req = hgsl_dbq_get_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_COOPERATIVE_RESET, + HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_HOST_TO_GVM_HARDRESET_REQ); + + /* ensure read is done before comparison */ + rmb(); + + if (hard_reset_req) { + udelay(1000); + if (retry_count++ > HGSL_SEND_MSG_MAX_RETRY_COUNT) { + ret = -ETIMEDOUT; + goto quit; + } + } + } while (hard_reset_req); + + db_set_busy_state(dbq->vbase, true); + queue_size_dword = dbq->data.dwords; msg_size_align = ALIGN(msg_req->msg_dwords, 4); @@ -442,7 +572,10 @@ static int db_send_msg(struct hgsl_priv *priv, goto quit; } - wptr = dbq_get_qindex(dbq->vbase, DBQ_WRITE_INDEX_IN_DWORD); + wptr = hgsl_dbq_get_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_QUEUE_INDEX, HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_WRITE_INDEX_OFFSET_IN_DWORD); + move_dwords = msg_req->msg_dwords; if ((msg_req->msg_dwords + wptr) >= queue_size_dword) { move_dwords = queue_size_dword - wptr; @@ -457,13 +590,22 @@ static int db_send_msg(struct hgsl_priv *priv, memcpy(dst, src, (move_dwords << 2)); wptr = (wptr + msg_size_align) % queue_size_dword; - dbq_set_qindex((uint32_t *)dbq->vbase, - DBQ_WRITE_INDEX_IN_DWORD, - wptr); + hgsl_dbq_set_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_QUEUE_INDEX, + HGSL_DBQ_CONTEXT_ANY, + HGSL_DBQ_WRITE_INDEX_OFFSET_IN_DWORD, + wptr); - dbq_update_ctxt_info((uint32_t *)dbq->vbase, + hgsl_dbq_set_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_CONTEXT_INFO, + cmds->ctx_id, + HGSL_DBQ_CONTEXT_CONTEXT_ID_OFFSET_IN_DWORD, + cmds->ctx_id); + + hgsl_dbq_set_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_CONTEXT_INFO, ((struct hgsl_db_cmds *)src)->ctx_id, - HGSL_DBQ_METADATA_TIMESTAMP_IN_DWORD, + HGSL_DBQ_CONTEXT_TIMESTAMP_OFFSET_IN_DWORD, ((struct hgsl_db_cmds *)src)->timestamp); /* confirm write to memory done before ring door bell. */ @@ -477,7 +619,9 @@ static int db_send_msg(struct hgsl_priv *priv, gmu_ring_local_db(hgsl, priv->dbq_idx); quit: - mutex_unlock(&hgsl->lock); + db_set_busy_state(dbq->vbase, false); + + mutex_unlock(&dbq->lock); return ret; } @@ -496,12 +640,14 @@ static int hgsl_db_issue_cmd(struct hgsl_priv *priv, struct db_msg_id db_msg_id; struct doorbell_queue *dbq; struct qcom_hgsl *hgsl = priv->dev; + struct hgsl_context *ctxt; uint32_t seq_num; db_msg_id.msg_id = HTOF_MSG_ISSUE_CMD; seq_num = atomic_inc_return(&hgsl->seq_num); db_msg_id.seq_no = seq_num; + ctxt = hgsl->contexts[ctx_id]; dbq = &hgsl->dbq[priv->dbq_idx]; msg_dwords = MSG_ISSUE_INF_SZ() + MSG_ISSUE_IBS_SZ(num_ibs); @@ -516,9 +662,9 @@ static int hgsl_db_issue_cmd(struct hgsl_priv *priv, if (cmds == NULL) return -ENOMEM; - cmds->header = HFI_ISSUE_IB_HEADER(num_ibs, - msg_dwords, - db_msg_id.seq_no); + cmds->header = (union hfi_msg_header)HFI_ISSUE_IB_HEADER(num_ibs, + msg_dwords, + db_msg_id.seq_no); cmds->ctx_id = ctx_id; cmds->num_ibs = num_ibs; cmds->cmd_flags = gmu_cmd_flags; @@ -531,7 +677,19 @@ static int hgsl_db_issue_cmd(struct hgsl_priv *priv, req.msg_dwords = msg_dwords; req.ptr_data = cmds; - ret = db_send_msg(priv, &db_msg_id, &req, &resp); + if (!ctxt->is_killed) { + ret = db_send_msg(priv, &db_msg_id, &req, &resp); + } else { + /* Retire ts immediately*/ + set_context_timestamp(ctxt, timestamp); + + /* Trigger event to waitfor ts thread */ + _signal_contexts(hgsl); + ret = 0; + } + + if (ret == 0) + ctxt->queued_ts = timestamp; kfree(cmds); return ret; @@ -703,8 +861,22 @@ static inline uint32_t get_context_timestamp(struct hgsl_context *ctxt) return ts; } +static inline void set_context_timestamp(struct hgsl_context *ctxt, + unsigned int ts) +{ + unsigned int *ts_mem; + + ts_mem = (unsigned int *)(ctxt->shadow_vbase + + ctxt->shadow_eop_off); + + *ts_mem = ts; + + /* ensure update is done before return */ + wmb(); +} + static inline bool _timestamp_retired(struct hgsl_context *ctxt, - unsigned int timestamp) + unsigned int timestamp) { return (get_context_timestamp(ctxt) >= timestamp); } @@ -988,7 +1160,7 @@ static int hgsl_context_create(struct file *filep, unsigned long arg) } if (!hgsl->contexts) { - dev_err(hgsl->dev, "DBQ not initialized propertily\n"); + dev_err(hgsl->dev, "DBQ not initialized properly\n"); return -ENODEV; } @@ -1233,15 +1405,16 @@ static int hgsl_dbq_release(struct file *filep, unsigned long arg, rel_info = *(struct hgsl_dbq_release_info *)arg; dbq = &hgsl->dbq[priv->dbq_idx]; - - dbq_update_ctxt_info(dbq->vbase, + hgsl_dbq_set_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_CONTEXT_INFO, rel_info.ctxt_id, - HGSL_DBQ_METADATA_CTXT_ID_IN_DWORD, + HGSL_DBQ_CONTEXT_CONTEXT_ID_OFFSET_IN_DWORD, rel_info.ctxt_id); - dbq_update_ctxt_info(dbq->vbase, + hgsl_dbq_set_state_info((uint32_t *)dbq->vbase, + HGSL_DBQ_METADATA_CONTEXT_INFO, rel_info.ctxt_id, - HGSL_DBQ_METADATA_CTXT_DESTROY_IN_DWORD, + HGSL_DBQ_CONTEXT_DESTROY_OFFSET_IN_DWORD, 1); rel_info.ref_count = (dbq->state == DB_STATE_Q_INIT_DONE) ? 1 : 0; @@ -1364,7 +1537,7 @@ out: } static int hgsl_ioctl_isync_timeline_create(struct file *filep, - unsigned long arg) + unsigned long arg) { struct hgsl_priv *priv = filep->private_data; uint32_t param = 0; @@ -1378,7 +1551,7 @@ static int hgsl_ioctl_isync_timeline_create(struct file *filep, } static int hgsl_ioctl_isync_timeline_destroy(struct file *filep, - unsigned long arg) + unsigned long arg) { struct hgsl_priv *priv = filep->private_data; uint32_t param = 0; @@ -1391,7 +1564,7 @@ static int hgsl_ioctl_isync_timeline_destroy(struct file *filep, } static int hgsl_ioctl_isync_fence_create(struct file *filep, - unsigned long arg) + unsigned long arg) { struct hgsl_priv *priv = filep->private_data; struct hgsl_isync_create_fence param; @@ -1412,7 +1585,7 @@ static int hgsl_ioctl_isync_fence_create(struct file *filep, } static int hgsl_ioctl_isync_fence_signal(struct file *filep, - unsigned long arg) + unsigned long arg) { struct hgsl_priv *priv = filep->private_data; struct hgsl_isync_signal_fence param; @@ -1427,7 +1600,7 @@ static int hgsl_ioctl_isync_fence_signal(struct file *filep, } static int hgsl_ioctl_isync_forward(struct file *filep, - unsigned long arg) + unsigned long arg) { struct hgsl_priv *priv = filep->private_data; struct hgsl_isync_forward param; @@ -1512,7 +1685,7 @@ static const struct file_operations hgsl_fops = { }; static int qcom_hgsl_register(struct platform_device *pdev, - struct qcom_hgsl *hgsl_dev) + struct qcom_hgsl *hgsl_dev) { int ret; @@ -1532,9 +1705,9 @@ static int qcom_hgsl_register(struct platform_device *pdev, } hgsl_dev->class_dev = device_create(hgsl_dev->driver_class, - NULL, - hgsl_dev->device_no, - hgsl_dev, HGSL_DEVICE_NAME); + NULL, + hgsl_dev->device_no, + hgsl_dev, HGSL_DEVICE_NAME); if (IS_ERR(hgsl_dev->class_dev)) { dev_err(&pdev->dev, "class_device_create failed %d\n", ret); @@ -1547,8 +1720,8 @@ static int qcom_hgsl_register(struct platform_device *pdev, hgsl_dev->cdev.owner = THIS_MODULE; ret = cdev_add(&hgsl_dev->cdev, - MKDEV(MAJOR(hgsl_dev->device_no), 0), - 1); + MKDEV(MAJOR(hgsl_dev->device_no), 0), + 1); if (ret < 0) { dev_err(&pdev->dev, "cdev_add failed %d\n", ret); goto exit_destroy_device; diff --git a/drivers/soc/qcom/hgsl/hgsl.h b/drivers/soc/qcom/hgsl/hgsl.h index d99b6587914f..0b46ab462801 100644 --- a/drivers/soc/qcom/hgsl/hgsl.h +++ b/drivers/soc/qcom/hgsl/hgsl.h @@ -35,6 +35,8 @@ struct hgsl_context { uint32_t last_ts; struct hgsl_hsync_timeline *timeline; + uint32_t queued_ts; + bool is_killed; }; struct hgsl_priv {