forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/media/platform/qcom/venus/hfi_venus.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
34 * Copyright (C) 2017 Linaro Ltd.
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 and
7
- * only version 2 as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
145 */
156
167 #include <linux/delay.h>
....@@ -19,7 +10,6 @@
1910 #include <linux/interrupt.h>
2011 #include <linux/iopoll.h>
2112 #include <linux/kernel.h>
22
-#include <linux/qcom_scm.h>
2313 #include <linux/slab.h>
2414
2515 #include "core.h"
....@@ -27,6 +17,7 @@
2717 #include "hfi_msgs.h"
2818 #include "hfi_venus.h"
2919 #include "hfi_venus_io.h"
20
+#include "firmware.h"
3021
3122 #define HFI_MASK_QHDR_TX_TYPE 0xff000000
3223 #define HFI_MASK_QHDR_RX_TYPE 0x00ff0000
....@@ -54,11 +45,6 @@
5445 #define IFACEQ_VAR_SMALL_PKT_SIZE 100
5546 #define IFACEQ_VAR_LARGE_PKT_SIZE 512
5647 #define IFACEQ_VAR_HUGE_PKT_SIZE (1024 * 12)
57
-
58
-enum tzbsp_video_state {
59
- TZBSP_VIDEO_STATE_SUSPEND = 0,
60
- TZBSP_VIDEO_STATE_RESUME
61
-};
6248
6349 struct hfi_queue_table_header {
6450 u32 version;
....@@ -144,7 +130,7 @@
144130 };
145131
146132 static bool venus_pkt_debug;
147
-static int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL;
133
+int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL;
148134 static bool venus_sys_idle_indicator;
149135 static bool venus_fw_low_power_mode = true;
150136 static int venus_hw_rsp_timeout = 1000;
....@@ -359,16 +345,6 @@
359345 dma_free_attrs(dev, mem->size, mem->kva, mem->da, mem->attrs);
360346 }
361347
362
-static void venus_writel(struct venus_hfi_device *hdev, u32 reg, u32 value)
363
-{
364
- writel(value, hdev->core->base + reg);
365
-}
366
-
367
-static u32 venus_readl(struct venus_hfi_device *hdev, u32 reg)
368
-{
369
- return readl(hdev->core->base + reg);
370
-}
371
-
372348 static void venus_set_registers(struct venus_hfi_device *hdev)
373349 {
374350 const struct venus_resources *res = hdev->core->res;
....@@ -377,12 +353,14 @@
377353 unsigned int i;
378354
379355 for (i = 0; i < count; i++)
380
- venus_writel(hdev, tbl[i].reg, tbl[i].value);
356
+ writel(tbl[i].value, hdev->core->base + tbl[i].reg);
381357 }
382358
383359 static void venus_soft_int(struct venus_hfi_device *hdev)
384360 {
385
- venus_writel(hdev, CPU_IC_SOFTINT, BIT(CPU_IC_SOFTINT_H2A_SHIFT));
361
+ void __iomem *cpu_ic_base = hdev->core->cpu_ic_base;
362
+
363
+ writel(BIT(CPU_IC_SOFTINT_H2A_SHIFT), cpu_ic_base + CPU_IC_SOFTINT);
386364 }
387365
388366 static int venus_iface_cmdq_write_nolock(struct venus_hfi_device *hdev,
....@@ -453,16 +431,25 @@
453431 {
454432 struct device *dev = hdev->core->dev;
455433 static const unsigned int max_tries = 100;
456
- u32 ctrl_status = 0;
434
+ u32 ctrl_status = 0, mask_val;
457435 unsigned int count = 0;
436
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
437
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
458438 int ret = 0;
459439
460
- venus_writel(hdev, VIDC_CTRL_INIT, BIT(VIDC_CTRL_INIT_CTRL_SHIFT));
461
- venus_writel(hdev, WRAPPER_INTR_MASK, WRAPPER_INTR_MASK_A2HVCODEC_MASK);
462
- venus_writel(hdev, CPU_CS_SCIACMDARG3, 1);
440
+ if (IS_V6(hdev->core)) {
441
+ mask_val = readl(wrapper_base + WRAPPER_INTR_MASK);
442
+ mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 |
443
+ WRAPPER_INTR_MASK_A2HCPU_MASK);
444
+ } else {
445
+ mask_val = WRAPPER_INTR_MASK_A2HVCODEC_MASK;
446
+ }
447
+ writel(mask_val, wrapper_base + WRAPPER_INTR_MASK);
448
+ writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3);
463449
450
+ writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT);
464451 while (!ctrl_status && count < max_tries) {
465
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
452
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
466453 if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) {
467454 dev_err(dev, "invalid setting for UC_REGION\n");
468455 ret = -EINVAL;
....@@ -476,22 +463,27 @@
476463 if (count >= max_tries)
477464 ret = -ETIMEDOUT;
478465
466
+ if (IS_V6(hdev->core))
467
+ writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6);
468
+
479469 return ret;
480470 }
481471
482472 static u32 venus_hwversion(struct venus_hfi_device *hdev)
483473 {
484474 struct device *dev = hdev->core->dev;
485
- u32 ver = venus_readl(hdev, WRAPPER_HW_VERSION);
475
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
476
+ u32 ver;
486477 u32 major, minor, step;
487478
479
+ ver = readl(wrapper_base + WRAPPER_HW_VERSION);
488480 major = ver & WRAPPER_HW_VERSION_MAJOR_VERSION_MASK;
489481 major = major >> WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT;
490482 minor = ver & WRAPPER_HW_VERSION_MINOR_VERSION_MASK;
491483 minor = minor >> WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT;
492484 step = ver & WRAPPER_HW_VERSION_STEP_VERSION_MASK;
493485
494
- dev_dbg(dev, "venus hw version %x.%x.%x\n", major, minor, step);
486
+ dev_dbg(dev, VDBGL "venus hw version %x.%x.%x\n", major, minor, step);
495487
496488 return major;
497489 }
....@@ -499,6 +491,7 @@
499491 static int venus_run(struct venus_hfi_device *hdev)
500492 {
501493 struct device *dev = hdev->core->dev;
494
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
502495 int ret;
503496
504497 /*
....@@ -507,12 +500,12 @@
507500 */
508501 venus_set_registers(hdev);
509502
510
- venus_writel(hdev, UC_REGION_ADDR, hdev->ifaceq_table.da);
511
- venus_writel(hdev, UC_REGION_SIZE, SHARED_QSIZE);
512
- venus_writel(hdev, CPU_CS_SCIACMDARG2, hdev->ifaceq_table.da);
513
- venus_writel(hdev, CPU_CS_SCIACMDARG1, 0x01);
503
+ writel(hdev->ifaceq_table.da, cpu_cs_base + UC_REGION_ADDR);
504
+ writel(SHARED_QSIZE, cpu_cs_base + UC_REGION_SIZE);
505
+ writel(hdev->ifaceq_table.da, cpu_cs_base + CPU_CS_SCIACMDARG2);
506
+ writel(0x01, cpu_cs_base + CPU_CS_SCIACMDARG1);
514507 if (hdev->sfr.da)
515
- venus_writel(hdev, SFR_ADDR, hdev->sfr.da);
508
+ writel(hdev->sfr.da, cpu_cs_base + SFR_ADDR);
516509
517510 ret = venus_boot_core(hdev);
518511 if (ret) {
....@@ -527,17 +520,18 @@
527520
528521 static int venus_halt_axi(struct venus_hfi_device *hdev)
529522 {
530
- void __iomem *base = hdev->core->base;
523
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
524
+ void __iomem *vbif_base = hdev->core->vbif_base;
531525 struct device *dev = hdev->core->dev;
532526 u32 val;
533527 int ret;
534528
535529 if (IS_V4(hdev->core)) {
536
- val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
530
+ val = readl(wrapper_base + WRAPPER_CPU_AXI_HALT);
537531 val |= WRAPPER_CPU_AXI_HALT_HALT;
538
- venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
532
+ writel(val, wrapper_base + WRAPPER_CPU_AXI_HALT);
539533
540
- ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS,
534
+ ret = readl_poll_timeout(wrapper_base + WRAPPER_CPU_AXI_HALT_STATUS,
541535 val,
542536 val & WRAPPER_CPU_AXI_HALT_STATUS_IDLE,
543537 POLL_INTERVAL_US,
....@@ -551,12 +545,12 @@
551545 }
552546
553547 /* Halt AXI and AXI IMEM VBIF Access */
554
- val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0);
548
+ val = readl(vbif_base + VBIF_AXI_HALT_CTRL0);
555549 val |= VBIF_AXI_HALT_CTRL0_HALT_REQ;
556
- venus_writel(hdev, VBIF_AXI_HALT_CTRL0, val);
550
+ writel(val, vbif_base + VBIF_AXI_HALT_CTRL0);
557551
558552 /* Request for AXI bus port halt */
559
- ret = readl_poll_timeout(base + VBIF_AXI_HALT_CTRL1, val,
553
+ ret = readl_poll_timeout(vbif_base + VBIF_AXI_HALT_CTRL1, val,
560554 val & VBIF_AXI_HALT_CTRL1_HALT_ACK,
561555 POLL_INTERVAL_US,
562556 VBIF_AXI_HALT_ACK_TIMEOUT_US);
....@@ -575,7 +569,7 @@
575569 if (!hdev->power_enabled)
576570 return 0;
577571
578
- ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
572
+ ret = venus_set_hw_state_suspend(hdev->core);
579573 if (ret)
580574 return ret;
581575
....@@ -595,7 +589,7 @@
595589 if (hdev->power_enabled)
596590 return 0;
597591
598
- ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_RESUME, 0);
592
+ ret = venus_set_hw_state_resume(hdev->core);
599593 if (ret)
600594 goto err;
601595
....@@ -608,7 +602,7 @@
608602 return 0;
609603
610604 err_suspend:
611
- qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
605
+ venus_set_hw_state_suspend(hdev->core);
612606 err:
613607 hdev->power_enabled = false;
614608 return ret;
....@@ -920,7 +914,7 @@
920914 if (pkt->hdr.pkt_type != HFI_MSG_SYS_COV) {
921915 struct hfi_msg_sys_debug_pkt *pkt = packet;
922916
923
- dev_dbg(dev, "%s", pkt->msg_data);
917
+ dev_dbg(dev, VDBGFW "%s", pkt->msg_data);
924918 }
925919 }
926920 }
....@@ -1000,13 +994,6 @@
1000994
1001995 venus_set_state(hdev, VENUS_STATE_DEINIT);
1002996
1003
- /*
1004
- * Once SYS_ERROR received from HW, it is safe to halt the AXI.
1005
- * With SYS_ERROR, Venus FW may have crashed and HW might be
1006
- * active and causing unnecessary transactions. Hence it is
1007
- * safe to stop all AXI transactions from venus subsystem.
1008
- */
1009
- venus_halt_axi(hdev);
1010997 venus_sfr_print(hdev);
1011998 }
1012999
....@@ -1023,10 +1010,6 @@
10231010 res = hdev->core->res;
10241011 pkt = hdev->pkt_buf;
10251012
1026
- if (hdev->irq_status & WRAPPER_INTR_STATUS_A2HWD_MASK) {
1027
- venus_sfr_print(hdev);
1028
- hfi_process_watchdog_timeout(core);
1029
- }
10301013
10311014 while (!venus_iface_msgq_read(hdev, pkt)) {
10321015 msg_ret = hfi_process_msg_packet(core, pkt);
....@@ -1060,19 +1043,21 @@
10601043 {
10611044 struct venus_hfi_device *hdev = to_hfi_priv(core);
10621045 u32 status;
1046
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
1047
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
10631048
10641049 if (!hdev)
10651050 return IRQ_NONE;
10661051
1067
- status = venus_readl(hdev, WRAPPER_INTR_STATUS);
1052
+ status = readl(wrapper_base + WRAPPER_INTR_STATUS);
10681053
10691054 if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
10701055 status & WRAPPER_INTR_STATUS_A2HWD_MASK ||
10711056 status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
10721057 hdev->irq_status = status;
10731058
1074
- venus_writel(hdev, CPU_CS_A2HSOFTINTCLR, 1);
1075
- venus_writel(hdev, WRAPPER_INTR_CLEAR, status);
1059
+ writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR);
1060
+ writel(status, wrapper_base + WRAPPER_INTR_CLEAR);
10761061
10771062 return IRQ_WAKE_THREAD;
10781063 }
....@@ -1146,6 +1131,10 @@
11461131 struct venus_hfi_device *hdev = to_hfi_priv(inst->core);
11471132 struct hfi_session_init_pkt pkt;
11481133 int ret;
1134
+
1135
+ ret = venus_sys_set_debug(hdev, venus_fw_debug);
1136
+ if (ret)
1137
+ goto err;
11491138
11501139 ret = pkt_session_init(&pkt, inst, session_type, codec);
11511140 if (ret)
....@@ -1355,6 +1344,8 @@
13551344 pkt = (struct hfi_session_set_property_pkt *)packet;
13561345
13571346 ret = pkt_session_set_property(pkt, inst, ptype, pdata);
1347
+ if (ret == -ENOTSUPP)
1348
+ return 0;
13581349 if (ret)
13591350 return ret;
13601351
....@@ -1399,6 +1390,7 @@
13991390 {
14001391 struct venus_hfi_device *hdev = to_hfi_priv(core);
14011392 struct device *dev = core->dev;
1393
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
14021394 u32 ctrl_status;
14031395 int ret;
14041396
....@@ -1433,7 +1425,7 @@
14331425 return -EINVAL;
14341426 }
14351427
1436
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
1428
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
14371429 if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) {
14381430 mutex_unlock(&hdev->lock);
14391431 return -EINVAL;
....@@ -1454,10 +1446,12 @@
14541446
14551447 static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev)
14561448 {
1449
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
1450
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
14571451 u32 ctrl_status, cpu_status;
14581452
1459
- cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
1460
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
1453
+ cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
1454
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
14611455
14621456 if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
14631457 ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
....@@ -1468,10 +1462,12 @@
14681462
14691463 static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev)
14701464 {
1465
+ void __iomem *wrapper_base = hdev->core->wrapper_base;
1466
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
14711467 u32 ctrl_status, cpu_status;
14721468
1473
- cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
1474
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
1469
+ cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS);
1470
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
14751471
14761472 if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
14771473 ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
....@@ -1484,6 +1480,7 @@
14841480 {
14851481 struct venus_hfi_device *hdev = to_hfi_priv(core);
14861482 struct device *dev = core->dev;
1483
+ void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
14871484 u32 ctrl_status;
14881485 bool val;
14891486 int ret;
....@@ -1500,7 +1497,7 @@
15001497 return -EINVAL;
15011498 }
15021499
1503
- ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
1500
+ ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0);
15041501 if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
15051502 goto power_off;
15061503
....@@ -1626,3 +1623,54 @@
16261623 core->ops = NULL;
16271624 return ret;
16281625 }
1626
+
1627
+void venus_hfi_queues_reinit(struct venus_core *core)
1628
+{
1629
+ struct venus_hfi_device *hdev = to_hfi_priv(core);
1630
+ struct hfi_queue_table_header *tbl_hdr;
1631
+ struct iface_queue *queue;
1632
+ struct hfi_sfr *sfr;
1633
+ unsigned int i;
1634
+
1635
+ mutex_lock(&hdev->lock);
1636
+
1637
+ for (i = 0; i < IFACEQ_NUM; i++) {
1638
+ queue = &hdev->queues[i];
1639
+ queue->qhdr =
1640
+ IFACEQ_GET_QHDR_START_ADDR(hdev->ifaceq_table.kva, i);
1641
+
1642
+ venus_set_qhdr_defaults(queue->qhdr);
1643
+
1644
+ queue->qhdr->start_addr = queue->qmem.da;
1645
+
1646
+ if (i == IFACEQ_CMD_IDX)
1647
+ queue->qhdr->type |= HFI_HOST_TO_CTRL_CMD_Q;
1648
+ else if (i == IFACEQ_MSG_IDX)
1649
+ queue->qhdr->type |= HFI_CTRL_TO_HOST_MSG_Q;
1650
+ else if (i == IFACEQ_DBG_IDX)
1651
+ queue->qhdr->type |= HFI_CTRL_TO_HOST_DBG_Q;
1652
+ }
1653
+
1654
+ tbl_hdr = hdev->ifaceq_table.kva;
1655
+ tbl_hdr->version = 0;
1656
+ tbl_hdr->size = IFACEQ_TABLE_SIZE;
1657
+ tbl_hdr->qhdr0_offset = sizeof(struct hfi_queue_table_header);
1658
+ tbl_hdr->qhdr_size = sizeof(struct hfi_queue_header);
1659
+ tbl_hdr->num_q = IFACEQ_NUM;
1660
+ tbl_hdr->num_active_q = IFACEQ_NUM;
1661
+
1662
+ /*
1663
+ * Set receive request to zero on debug queue as there is no
1664
+ * need of interrupt from video hardware for debug messages
1665
+ */
1666
+ queue = &hdev->queues[IFACEQ_DBG_IDX];
1667
+ queue->qhdr->rx_req = 0;
1668
+
1669
+ sfr = hdev->sfr.kva;
1670
+ sfr->buf_size = ALIGNED_SFR_SIZE;
1671
+
1672
+ /* ensure table and queue header structs are settled in memory */
1673
+ wmb();
1674
+
1675
+ mutex_unlock(&hdev->lock);
1676
+}