From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/media/platform/qcom/venus/hfi_venus.c | 192 ++++++++++++++++++++++++++++++------------------
1 files changed, 120 insertions(+), 72 deletions(-)
diff --git a/kernel/drivers/media/platform/qcom/venus/hfi_venus.c b/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
index fbcc67c..9d939f6 100644
--- a/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/kernel/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
* Copyright (C) 2017 Linaro Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/delay.h>
@@ -19,7 +10,6 @@
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
-#include <linux/qcom_scm.h>
#include <linux/slab.h>
#include "core.h"
@@ -27,6 +17,7 @@
#include "hfi_msgs.h"
#include "hfi_venus.h"
#include "hfi_venus_io.h"
+#include "firmware.h"
#define HFI_MASK_QHDR_TX_TYPE 0xff000000
#define HFI_MASK_QHDR_RX_TYPE 0x00ff0000
@@ -54,11 +45,6 @@
#define IFACEQ_VAR_SMALL_PKT_SIZE 100
#define IFACEQ_VAR_LARGE_PKT_SIZE 512
#define IFACEQ_VAR_HUGE_PKT_SIZE (1024 * 12)
-
-enum tzbsp_video_state {
- TZBSP_VIDEO_STATE_SUSPEND = 0,
- TZBSP_VIDEO_STATE_RESUME
-};
struct hfi_queue_table_header {
u32 version;
@@ -144,7 +130,7 @@
};
static bool venus_pkt_debug;
-static int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL;
+int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL;
static bool venus_sys_idle_indicator;
static bool venus_fw_low_power_mode = true;
static int venus_hw_rsp_timeout = 1000;
@@ -359,16 +345,6 @@
dma_free_attrs(dev, mem->size, mem->kva, mem->da, mem->attrs);
}
-static void venus_writel(struct venus_hfi_device *hdev, u32 reg, u32 value)
-{
- writel(value, hdev->core->base + reg);
-}
-
-static u32 venus_readl(struct venus_hfi_device *hdev, u32 reg)
-{
- return readl(hdev->core->base + reg);
-}
-
static void venus_set_registers(struct venus_hfi_device *hdev)
{
const struct venus_resources *res = hdev->core->res;
@@ -377,12 +353,14 @@
unsigned int i;
for (i = 0; i < count; i++)
- venus_writel(hdev, tbl[i].reg, tbl[i].value);
+ writel(tbl[i].value, hdev->core->base + tbl[i].reg);
}
static void venus_soft_int(struct venus_hfi_device *hdev)
{
- venus_writel(hdev, CPU_IC_SOFTINT, BIT(CPU_IC_SOFTINT_H2A_SHIFT));
+ void __iomem *cpu_ic_base = hdev->core->cpu_ic_base;
+
+ writel(BIT(CPU_IC_SOFTINT_H2A_SHIFT), cpu_ic_base + CPU_IC_SOFTINT);
}
static int venus_iface_cmdq_write_nolock(struct venus_hfi_device *hdev,
@@ -453,16 +431,25 @@
{
struct device *dev = hdev->core->dev;
static const unsigned int max_tries = 100;
- u32 ctrl_status = 0;
+ u32 ctrl_status = 0, mask_val;
unsigned int count = 0;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
int ret = 0;
- venus_writel(hdev, VIDC_CTRL_INIT, BIT(VIDC_CTRL_INIT_CTRL_SHIFT));
- venus_writel(hdev, WRAPPER_INTR_MASK, WRAPPER_INTR_MASK_A2HVCODEC_MASK);
- venus_writel(hdev, CPU_CS_SCIACMDARG3, 1);
+ if (IS_V6(hdev->core)) {
+ mask_val = readl(wrapper_base + WRAPPER_INTR_MASK);
+ mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 |
+ WRAPPER_INTR_MASK_A2HCPU_MASK);
+ } else {
+ mask_val = WRAPPER_INTR_MASK_A2HVCODEC_MASK;
+ }
+ writel(mask_val, wrapper_base + WRAPPER_INTR_MASK);
+ writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3);
+ writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT);
while (!ctrl_status && count < max_tries) {
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) {
dev_err(dev, "invalid setting for UC_REGION\n");
ret = -EINVAL;
@@ -476,22 +463,27 @@
if (count >= max_tries)
ret = -ETIMEDOUT;
+ if (IS_V6(hdev->core))
+ writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
+
return ret;
}
static u32 venus_hwversion(struct venus_hfi_device *hdev)
{
struct device *dev = hdev->core->dev;
- u32 ver = venus_readl(hdev, WRAPPER_HW_VERSION);
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
+ u32 ver;
u32 major, minor, step;
+ ver = readl(wrapper_base + WRAPPER_HW_VERSION);
major = ver & WRAPPER_HW_VERSION_MAJOR_VERSION_MASK;
major = major >> WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT;
minor = ver & WRAPPER_HW_VERSION_MINOR_VERSION_MASK;
minor = minor >> WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT;
step = ver & WRAPPER_HW_VERSION_STEP_VERSION_MASK;
- dev_dbg(dev, "venus hw version %x.%x.%x\n", major, minor, step);
+ dev_dbg(dev, VDBGL "venus hw version %x.%x.%x\n", major, minor, step);
return major;
}
@@ -499,6 +491,7 @@
static int venus_run(struct venus_hfi_device *hdev)
{
struct device *dev = hdev->core->dev;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
int ret;
/*
@@ -507,12 +500,12 @@
*/
venus_set_registers(hdev);
- venus_writel(hdev, UC_REGION_ADDR, hdev->ifaceq_table.da);
- venus_writel(hdev, UC_REGION_SIZE, SHARED_QSIZE);
- venus_writel(hdev, CPU_CS_SCIACMDARG2, hdev->ifaceq_table.da);
- venus_writel(hdev, CPU_CS_SCIACMDARG1, 0x01);
+ writel(hdev->ifaceq_table.da, cpu_cs_base + UC_REGION_ADDR);
+ writel(SHARED_QSIZE, cpu_cs_base + UC_REGION_SIZE);
+ writel(hdev->ifaceq_table.da, cpu_cs_base + CPU_CS_SCIACMDARG2);
+ writel(0x01, cpu_cs_base + CPU_CS_SCIACMDARG1);
if (hdev->sfr.da)
- venus_writel(hdev, SFR_ADDR, hdev->sfr.da);
+ writel(hdev->sfr.da, cpu_cs_base + SFR_ADDR);
ret = venus_boot_core(hdev);
if (ret) {
@@ -527,17 +520,18 @@
static int venus_halt_axi(struct venus_hfi_device *hdev)
{
- void __iomem *base = hdev->core->base;
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
+ void __iomem *vbif_base = hdev->core->vbif_base;
struct device *dev = hdev->core->dev;
u32 val;
int ret;
if (IS_V4(hdev->core)) {
- val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
+ val = readl(wrapper_base + WRAPPER_CPU_AXI_HALT);
val |= WRAPPER_CPU_AXI_HALT_HALT;
- venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
+ writel(val, wrapper_base + WRAPPER_CPU_AXI_HALT);
- ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS,
+ ret = readl_poll_timeout(wrapper_base + WRAPPER_CPU_AXI_HALT_STATUS,
val,
val & WRAPPER_CPU_AXI_HALT_STATUS_IDLE,
POLL_INTERVAL_US,
@@ -551,12 +545,12 @@
}
/* Halt AXI and AXI IMEM VBIF Access */
- val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0);
+ val = readl(vbif_base + VBIF_AXI_HALT_CTRL0);
val |= VBIF_AXI_HALT_CTRL0_HALT_REQ;
- venus_writel(hdev, VBIF_AXI_HALT_CTRL0, val);
+ writel(val, vbif_base + VBIF_AXI_HALT_CTRL0);
/* Request for AXI bus port halt */
- ret = readl_poll_timeout(base + VBIF_AXI_HALT_CTRL1, val,
+ ret = readl_poll_timeout(vbif_base + VBIF_AXI_HALT_CTRL1, val,
val & VBIF_AXI_HALT_CTRL1_HALT_ACK,
POLL_INTERVAL_US,
VBIF_AXI_HALT_ACK_TIMEOUT_US);
@@ -575,7 +569,7 @@
if (!hdev->power_enabled)
return 0;
- ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
+ ret = venus_set_hw_state_suspend(hdev->core);
if (ret)
return ret;
@@ -595,7 +589,7 @@
if (hdev->power_enabled)
return 0;
- ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_RESUME, 0);
+ ret = venus_set_hw_state_resume(hdev->core);
if (ret)
goto err;
@@ -608,7 +602,7 @@
return 0;
err_suspend:
- qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
+ venus_set_hw_state_suspend(hdev->core);
err:
hdev->power_enabled = false;
return ret;
@@ -920,7 +914,7 @@
if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) {
struct hfi_msg_sys_debug_pkt *pkt = packet;
- dev_dbg(dev, "%s", pkt->msg_data);
+ dev_dbg(dev, VDBGFW "%s", pkt->msg_data);
}
}
}
@@ -1000,13 +994,6 @@
venus_set_state(hdev, VENUS_STATE_DEINIT);
- /*
- * Once SYS_ERROR received from HW, it is safe to halt the AXI.
- * With SYS_ERROR, Venus FW may have crashed and HW might be
- * active and causing unnecessary transactions. Hence it is
- * safe to stop all AXI transactions from venus subsystem.
- */
- venus_halt_axi(hdev);
venus_sfr_print(hdev);
}
@@ -1023,10 +1010,6 @@
res = hdev->core->res;
pkt = hdev->pkt_buf;
- if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
- venus_sfr_print(hdev);
- hfi_process_watchdog_timeout(core);
- }
while (!venus_iface_msgq_read(hdev, pkt)) {
msg_ret = hfi_process_msg_packet(core, pkt);
@@ -1060,19 +1043,21 @@
{
struct venus_hfi_device *hdev = to_hfi_priv(core);
u32 status;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
if (!hdev)
return IRQ_NONE;
- status = venus_readl(hdev, WRAPPER_INTR_STATUS);
+ status = readl(wrapper_base + WRAPPER_INTR_STATUS);
if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
status & WRAPPER_INTR_STATUS_A2HWD_MASK ||
status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
hdev->irq_status = status;
- venus_writel(hdev, CPU_CS_A2HSOFTINTCLR, 1);
- venus_writel(hdev, WRAPPER_INTR_CLEAR, status);
+ writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR);
+ writel(status, wrapper_base + WRAPPER_INTR_CLEAR);
return IRQ_WAKE_THREAD;
}
@@ -1146,6 +1131,10 @@
struct venus_hfi_device *hdev = to_hfi_priv(inst->core);
struct hfi_session_init_pkt pkt;
int ret;
+
+ ret = venus_sys_set_debug(hdev, venus_fw_debug);
+ if (ret)
+ goto err;
ret = pkt_session_init(&pkt, inst, session_type, codec);
if (ret)
@@ -1355,6 +1344,8 @@
pkt = (struct hfi_session_set_property_pkt *)packet;
ret = pkt_session_set_property(pkt, inst, ptype, pdata);
+ if (ret == -ENOTSUPP)
+ return 0;
if (ret)
return ret;
@@ -1399,6 +1390,7 @@
{
struct venus_hfi_device *hdev = to_hfi_priv(core);
struct device *dev = core->dev;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status;
int ret;
@@ -1433,7 +1425,7 @@
return -EINVAL;
}
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) {
mutex_unlock(&hdev->lock);
return -EINVAL;
@@ -1454,10 +1446,12 @@
static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev)
{
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+ cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
@@ -1468,10 +1462,12 @@
static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev)
{
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status, cpu_status;
- cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+ cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
@@ -1484,6 +1480,7 @@
{
struct venus_hfi_device *hdev = to_hfi_priv(core);
struct device *dev = core->dev;
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
u32 ctrl_status;
bool val;
int ret;
@@ -1500,7 +1497,7 @@
return -EINVAL;
}
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
goto power_off;
@@ -1626,3 +1623,54 @@
core->ops = NULL;
return ret;
}
+
+void venus_hfi_queues_reinit(struct venus_core *core)
+{
+ struct venus_hfi_device *hdev = to_hfi_priv(core);
+ struct hfi_queue_table_header *tbl_hdr;
+ struct iface_queue *queue;
+ struct hfi_sfr *sfr;
+ unsigned int i;
+
+ mutex_lock(&hdev->lock);
+
+ for (i = 0; i < IFACEQ_NUM; i++) {
+ queue = &hdev->queues[i];
+ queue->qhdr =
+ IFACEQ_GET_QHDR_START_ADDR(hdev->ifaceq_table.kva, i);
+
+ venus_set_qhdr_defaults(queue->qhdr);
+
+ queue->qhdr->start_addr = queue->qmem.da;
+
+ if (i == IFACEQ_CMD_IDX)
+ queue->qhdr->type |= HFI_HOST_TO_CTRL_CMD_Q;
+ else if (i == IFACEQ_MSG_IDX)
+ queue->qhdr->type |= HFI_CTRL_TO_HOST_MSG_Q;
+ else if (i == IFACEQ_DBG_IDX)
+ queue->qhdr->type |= HFI_CTRL_TO_HOST_DBG_Q;
+ }
+
+ tbl_hdr = hdev->ifaceq_table.kva;
+ tbl_hdr->version = 0;
+ tbl_hdr->size = IFACEQ_TABLE_SIZE;
+ tbl_hdr->qhdr0_offset = sizeof(struct hfi_queue_table_header);
+ tbl_hdr->qhdr_size = sizeof(struct hfi_queue_header);
+ tbl_hdr->num_q = IFACEQ_NUM;
+ tbl_hdr->num_active_q = IFACEQ_NUM;
+
+ /*
+ * Set receive request to zero on debug queue as there is no
+ * need of interrupt from video hardware for debug messages
+ */
+ queue = &hdev->queues[IFACEQ_DBG_IDX];
+ queue->qhdr->rx_req = 0;
+
+ sfr = hdev->sfr.kva;
+ sfr->buf_size = ALIGNED_SFR_SIZE;
+
+ /* ensure table and queue header structs are settled in memory */
+ wmb();
+
+ mutex_unlock(&hdev->lock);
+}
--
Gitblit v1.6.2