1*e7b8153eSMauro Carvalho Chehab // SPDX-License-Identifier: GPL-2.0
2*e7b8153eSMauro Carvalho Chehab /*
3*e7b8153eSMauro Carvalho Chehab * Copyright (C) STMicroelectronics SA 2015
4*e7b8153eSMauro Carvalho Chehab * Authors: Yannick Fertre <yannick.fertre@st.com>
5*e7b8153eSMauro Carvalho Chehab * Hugues Fruchet <hugues.fruchet@st.com>
6*e7b8153eSMauro Carvalho Chehab */
7*e7b8153eSMauro Carvalho Chehab
8*e7b8153eSMauro Carvalho Chehab #include <linux/clk.h>
9*e7b8153eSMauro Carvalho Chehab #include <linux/interrupt.h>
10*e7b8153eSMauro Carvalho Chehab #include <linux/platform_device.h>
11*e7b8153eSMauro Carvalho Chehab #include <linux/pm_runtime.h>
12*e7b8153eSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
13*e7b8153eSMauro Carvalho Chehab #include <linux/seq_file.h>
14*e7b8153eSMauro Carvalho Chehab #endif
15*e7b8153eSMauro Carvalho Chehab
16*e7b8153eSMauro Carvalho Chehab #include "hva.h"
17*e7b8153eSMauro Carvalho Chehab #include "hva-hw.h"
18*e7b8153eSMauro Carvalho Chehab
19*e7b8153eSMauro Carvalho Chehab /* HVA register offsets */
20*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_RST 0x0100U
21*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_RST_ACK 0x0104U
22*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_MIF_CFG 0x0108U
23*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HEC_MIF_CFG 0x010CU
24*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_CFL 0x0110U
25*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_FIFO_CMD 0x0114U
26*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_FIFO_STS 0x0118U
27*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_SFL 0x011CU
28*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_IT_ACK 0x0120U
29*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_ERR_IT_ACK 0x0124U
30*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_LMI_ERR 0x0128U
31*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_EMI_ERR 0x012CU
32*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HEC_MIF_ERR 0x0130U
33*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HEC_STS 0x0134U
34*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HVC_STS 0x0138U
35*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HJE_STS 0x013CU
36*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_CNT 0x0140U
37*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_HEC_CHKSYN_DIS 0x0144U
38*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_CLK_GATING 0x0148U
39*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_VERSION 0x014CU
40*e7b8153eSMauro Carvalho Chehab #define HVA_HIF_REG_BSM 0x0150U
41*e7b8153eSMauro Carvalho Chehab
42*e7b8153eSMauro Carvalho Chehab /* define value for version id register (HVA_HIF_REG_VERSION) */
43*e7b8153eSMauro Carvalho Chehab #define VERSION_ID_MASK 0x0000FFFF
44*e7b8153eSMauro Carvalho Chehab
45*e7b8153eSMauro Carvalho Chehab /* define values for BSM register (HVA_HIF_REG_BSM) */
46*e7b8153eSMauro Carvalho Chehab #define BSM_CFG_VAL1 0x0003F000
47*e7b8153eSMauro Carvalho Chehab #define BSM_CFG_VAL2 0x003F0000
48*e7b8153eSMauro Carvalho Chehab
49*e7b8153eSMauro Carvalho Chehab /* define values for memory interface register (HVA_HIF_REG_MIF_CFG) */
50*e7b8153eSMauro Carvalho Chehab #define MIF_CFG_VAL1 0x04460446
51*e7b8153eSMauro Carvalho Chehab #define MIF_CFG_VAL2 0x04460806
52*e7b8153eSMauro Carvalho Chehab #define MIF_CFG_VAL3 0x00000000
53*e7b8153eSMauro Carvalho Chehab
54*e7b8153eSMauro Carvalho Chehab /* define value for HEC memory interface register (HVA_HIF_REG_MIF_CFG) */
55*e7b8153eSMauro Carvalho Chehab #define HEC_MIF_CFG_VAL 0x000000C4
56*e7b8153eSMauro Carvalho Chehab
57*e7b8153eSMauro Carvalho Chehab /* Bits definition for clock gating register (HVA_HIF_REG_CLK_GATING) */
58*e7b8153eSMauro Carvalho Chehab #define CLK_GATING_HVC BIT(0)
59*e7b8153eSMauro Carvalho Chehab #define CLK_GATING_HEC BIT(1)
60*e7b8153eSMauro Carvalho Chehab #define CLK_GATING_HJE BIT(2)
61*e7b8153eSMauro Carvalho Chehab
62*e7b8153eSMauro Carvalho Chehab /* fix hva clock rate */
63*e7b8153eSMauro Carvalho Chehab #define CLK_RATE 300000000
64*e7b8153eSMauro Carvalho Chehab
65*e7b8153eSMauro Carvalho Chehab /* fix delay for pmruntime */
66*e7b8153eSMauro Carvalho Chehab #define AUTOSUSPEND_DELAY_MS 3
67*e7b8153eSMauro Carvalho Chehab
68*e7b8153eSMauro Carvalho Chehab /*
69*e7b8153eSMauro Carvalho Chehab * hw encode error values
70*e7b8153eSMauro Carvalho Chehab * NO_ERROR: Success, Task OK
71*e7b8153eSMauro Carvalho Chehab * H264_BITSTREAM_OVERSIZE: VECH264 Bitstream size > bitstream buffer
72*e7b8153eSMauro Carvalho Chehab * H264_FRAME_SKIPPED: VECH264 Frame skipped (refers to CPB Buffer Size)
73*e7b8153eSMauro Carvalho Chehab * H264_SLICE_LIMIT_SIZE: VECH264 MB > slice limit size
74*e7b8153eSMauro Carvalho Chehab * H264_MAX_SLICE_NUMBER: VECH264 max slice number reached
75*e7b8153eSMauro Carvalho Chehab * H264_SLICE_READY: VECH264 Slice ready
76*e7b8153eSMauro Carvalho Chehab * TASK_LIST_FULL: HVA/FPC task list full
77*e7b8153eSMauro Carvalho Chehab (discard latest transform command)
78*e7b8153eSMauro Carvalho Chehab * UNKNOWN_COMMAND: Transform command not known by HVA/FPC
79*e7b8153eSMauro Carvalho Chehab * WRONG_CODEC_OR_RESOLUTION: Wrong Codec or Resolution Selection
80*e7b8153eSMauro Carvalho Chehab * NO_INT_COMPLETION: Time-out on interrupt completion
81*e7b8153eSMauro Carvalho Chehab * LMI_ERR: Local Memory Interface Error
82*e7b8153eSMauro Carvalho Chehab * EMI_ERR: External Memory Interface Error
83*e7b8153eSMauro Carvalho Chehab * HECMI_ERR: HEC Memory Interface Error
84*e7b8153eSMauro Carvalho Chehab */
85*e7b8153eSMauro Carvalho Chehab enum hva_hw_error {
86*e7b8153eSMauro Carvalho Chehab NO_ERROR = 0x0,
87*e7b8153eSMauro Carvalho Chehab H264_BITSTREAM_OVERSIZE = 0x2,
88*e7b8153eSMauro Carvalho Chehab H264_FRAME_SKIPPED = 0x4,
89*e7b8153eSMauro Carvalho Chehab H264_SLICE_LIMIT_SIZE = 0x5,
90*e7b8153eSMauro Carvalho Chehab H264_MAX_SLICE_NUMBER = 0x7,
91*e7b8153eSMauro Carvalho Chehab H264_SLICE_READY = 0x8,
92*e7b8153eSMauro Carvalho Chehab TASK_LIST_FULL = 0xF0,
93*e7b8153eSMauro Carvalho Chehab UNKNOWN_COMMAND = 0xF1,
94*e7b8153eSMauro Carvalho Chehab WRONG_CODEC_OR_RESOLUTION = 0xF4,
95*e7b8153eSMauro Carvalho Chehab NO_INT_COMPLETION = 0x100,
96*e7b8153eSMauro Carvalho Chehab LMI_ERR = 0x101,
97*e7b8153eSMauro Carvalho Chehab EMI_ERR = 0x102,
98*e7b8153eSMauro Carvalho Chehab HECMI_ERR = 0x103,
99*e7b8153eSMauro Carvalho Chehab };
100*e7b8153eSMauro Carvalho Chehab
hva_hw_its_interrupt(int irq,void * data)101*e7b8153eSMauro Carvalho Chehab static irqreturn_t hva_hw_its_interrupt(int irq, void *data)
102*e7b8153eSMauro Carvalho Chehab {
103*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = data;
104*e7b8153eSMauro Carvalho Chehab
105*e7b8153eSMauro Carvalho Chehab /* read status registers */
106*e7b8153eSMauro Carvalho Chehab hva->sts_reg = readl_relaxed(hva->regs + HVA_HIF_FIFO_STS);
107*e7b8153eSMauro Carvalho Chehab hva->sfl_reg = readl_relaxed(hva->regs + HVA_HIF_REG_SFL);
108*e7b8153eSMauro Carvalho Chehab
109*e7b8153eSMauro Carvalho Chehab /* acknowledge interruption */
110*e7b8153eSMauro Carvalho Chehab writel_relaxed(0x1, hva->regs + HVA_HIF_REG_IT_ACK);
111*e7b8153eSMauro Carvalho Chehab
112*e7b8153eSMauro Carvalho Chehab return IRQ_WAKE_THREAD;
113*e7b8153eSMauro Carvalho Chehab }
114*e7b8153eSMauro Carvalho Chehab
hva_hw_its_irq_thread(int irq,void * arg)115*e7b8153eSMauro Carvalho Chehab static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg)
116*e7b8153eSMauro Carvalho Chehab {
117*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = arg;
118*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
119*e7b8153eSMauro Carvalho Chehab u32 status = hva->sts_reg & 0xFF;
120*e7b8153eSMauro Carvalho Chehab u8 ctx_id = 0;
121*e7b8153eSMauro Carvalho Chehab struct hva_ctx *ctx = NULL;
122*e7b8153eSMauro Carvalho Chehab
123*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: status: 0x%02x fifo level: 0x%02x\n",
124*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, __func__, hva->sts_reg & 0xFF, hva->sfl_reg & 0xF);
125*e7b8153eSMauro Carvalho Chehab
126*e7b8153eSMauro Carvalho Chehab /*
127*e7b8153eSMauro Carvalho Chehab * status: task_id[31:16] client_id[15:8] status[7:0]
128*e7b8153eSMauro Carvalho Chehab * the context identifier is retrieved from the client identifier
129*e7b8153eSMauro Carvalho Chehab */
130*e7b8153eSMauro Carvalho Chehab ctx_id = (hva->sts_reg & 0xFF00) >> 8;
131*e7b8153eSMauro Carvalho Chehab if (ctx_id >= HVA_MAX_INSTANCES) {
132*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: bad context identifier: %d\n",
133*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, __func__, ctx_id);
134*e7b8153eSMauro Carvalho Chehab goto out;
135*e7b8153eSMauro Carvalho Chehab }
136*e7b8153eSMauro Carvalho Chehab
137*e7b8153eSMauro Carvalho Chehab ctx = hva->instances[ctx_id];
138*e7b8153eSMauro Carvalho Chehab if (!ctx)
139*e7b8153eSMauro Carvalho Chehab goto out;
140*e7b8153eSMauro Carvalho Chehab
141*e7b8153eSMauro Carvalho Chehab switch (status) {
142*e7b8153eSMauro Carvalho Chehab case NO_ERROR:
143*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: no error\n",
144*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
145*e7b8153eSMauro Carvalho Chehab ctx->hw_err = false;
146*e7b8153eSMauro Carvalho Chehab break;
147*e7b8153eSMauro Carvalho Chehab case H264_SLICE_READY:
148*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: h264 slice ready\n",
149*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
150*e7b8153eSMauro Carvalho Chehab ctx->hw_err = false;
151*e7b8153eSMauro Carvalho Chehab break;
152*e7b8153eSMauro Carvalho Chehab case H264_FRAME_SKIPPED:
153*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: h264 frame skipped\n",
154*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
155*e7b8153eSMauro Carvalho Chehab ctx->hw_err = false;
156*e7b8153eSMauro Carvalho Chehab break;
157*e7b8153eSMauro Carvalho Chehab case H264_BITSTREAM_OVERSIZE:
158*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s:h264 bitstream oversize\n",
159*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
160*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
161*e7b8153eSMauro Carvalho Chehab break;
162*e7b8153eSMauro Carvalho Chehab case H264_SLICE_LIMIT_SIZE:
163*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: h264 slice limit size is reached\n",
164*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
165*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
166*e7b8153eSMauro Carvalho Chehab break;
167*e7b8153eSMauro Carvalho Chehab case H264_MAX_SLICE_NUMBER:
168*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: h264 max slice number is reached\n",
169*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
170*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
171*e7b8153eSMauro Carvalho Chehab break;
172*e7b8153eSMauro Carvalho Chehab case TASK_LIST_FULL:
173*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s:task list full\n",
174*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
175*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
176*e7b8153eSMauro Carvalho Chehab break;
177*e7b8153eSMauro Carvalho Chehab case UNKNOWN_COMMAND:
178*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: command not known\n",
179*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
180*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
181*e7b8153eSMauro Carvalho Chehab break;
182*e7b8153eSMauro Carvalho Chehab case WRONG_CODEC_OR_RESOLUTION:
183*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: wrong codec or resolution\n",
184*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
185*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
186*e7b8153eSMauro Carvalho Chehab break;
187*e7b8153eSMauro Carvalho Chehab default:
188*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: status not recognized\n",
189*e7b8153eSMauro Carvalho Chehab ctx->name, __func__);
190*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
191*e7b8153eSMauro Carvalho Chehab break;
192*e7b8153eSMauro Carvalho Chehab }
193*e7b8153eSMauro Carvalho Chehab out:
194*e7b8153eSMauro Carvalho Chehab complete(&hva->interrupt);
195*e7b8153eSMauro Carvalho Chehab
196*e7b8153eSMauro Carvalho Chehab return IRQ_HANDLED;
197*e7b8153eSMauro Carvalho Chehab }
198*e7b8153eSMauro Carvalho Chehab
hva_hw_err_interrupt(int irq,void * data)199*e7b8153eSMauro Carvalho Chehab static irqreturn_t hva_hw_err_interrupt(int irq, void *data)
200*e7b8153eSMauro Carvalho Chehab {
201*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = data;
202*e7b8153eSMauro Carvalho Chehab
203*e7b8153eSMauro Carvalho Chehab /* read status registers */
204*e7b8153eSMauro Carvalho Chehab hva->sts_reg = readl_relaxed(hva->regs + HVA_HIF_FIFO_STS);
205*e7b8153eSMauro Carvalho Chehab hva->sfl_reg = readl_relaxed(hva->regs + HVA_HIF_REG_SFL);
206*e7b8153eSMauro Carvalho Chehab
207*e7b8153eSMauro Carvalho Chehab /* read error registers */
208*e7b8153eSMauro Carvalho Chehab hva->lmi_err_reg = readl_relaxed(hva->regs + HVA_HIF_REG_LMI_ERR);
209*e7b8153eSMauro Carvalho Chehab hva->emi_err_reg = readl_relaxed(hva->regs + HVA_HIF_REG_EMI_ERR);
210*e7b8153eSMauro Carvalho Chehab hva->hec_mif_err_reg = readl_relaxed(hva->regs +
211*e7b8153eSMauro Carvalho Chehab HVA_HIF_REG_HEC_MIF_ERR);
212*e7b8153eSMauro Carvalho Chehab
213*e7b8153eSMauro Carvalho Chehab /* acknowledge interruption */
214*e7b8153eSMauro Carvalho Chehab writel_relaxed(0x1, hva->regs + HVA_HIF_REG_IT_ACK);
215*e7b8153eSMauro Carvalho Chehab
216*e7b8153eSMauro Carvalho Chehab return IRQ_WAKE_THREAD;
217*e7b8153eSMauro Carvalho Chehab }
218*e7b8153eSMauro Carvalho Chehab
hva_hw_err_irq_thread(int irq,void * arg)219*e7b8153eSMauro Carvalho Chehab static irqreturn_t hva_hw_err_irq_thread(int irq, void *arg)
220*e7b8153eSMauro Carvalho Chehab {
221*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = arg;
222*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
223*e7b8153eSMauro Carvalho Chehab u8 ctx_id = 0;
224*e7b8153eSMauro Carvalho Chehab struct hva_ctx *ctx;
225*e7b8153eSMauro Carvalho Chehab
226*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s status: 0x%02x fifo level: 0x%02x\n",
227*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, hva->sts_reg & 0xFF, hva->sfl_reg & 0xF);
228*e7b8153eSMauro Carvalho Chehab
229*e7b8153eSMauro Carvalho Chehab /*
230*e7b8153eSMauro Carvalho Chehab * status: task_id[31:16] client_id[15:8] status[7:0]
231*e7b8153eSMauro Carvalho Chehab * the context identifier is retrieved from the client identifier
232*e7b8153eSMauro Carvalho Chehab */
233*e7b8153eSMauro Carvalho Chehab ctx_id = (hva->sts_reg & 0xFF00) >> 8;
234*e7b8153eSMauro Carvalho Chehab if (ctx_id >= HVA_MAX_INSTANCES) {
235*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s bad context identifier: %d\n", HVA_PREFIX,
236*e7b8153eSMauro Carvalho Chehab ctx_id);
237*e7b8153eSMauro Carvalho Chehab goto out;
238*e7b8153eSMauro Carvalho Chehab }
239*e7b8153eSMauro Carvalho Chehab
240*e7b8153eSMauro Carvalho Chehab ctx = hva->instances[ctx_id];
241*e7b8153eSMauro Carvalho Chehab if (!ctx)
242*e7b8153eSMauro Carvalho Chehab goto out;
243*e7b8153eSMauro Carvalho Chehab
244*e7b8153eSMauro Carvalho Chehab if (hva->lmi_err_reg) {
245*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s local memory interface error: 0x%08x\n",
246*e7b8153eSMauro Carvalho Chehab ctx->name, hva->lmi_err_reg);
247*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
248*e7b8153eSMauro Carvalho Chehab }
249*e7b8153eSMauro Carvalho Chehab
250*e7b8153eSMauro Carvalho Chehab if (hva->emi_err_reg) {
251*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s external memory interface error: 0x%08x\n",
252*e7b8153eSMauro Carvalho Chehab ctx->name, hva->emi_err_reg);
253*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
254*e7b8153eSMauro Carvalho Chehab }
255*e7b8153eSMauro Carvalho Chehab
256*e7b8153eSMauro Carvalho Chehab if (hva->hec_mif_err_reg) {
257*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s hec memory interface error: 0x%08x\n",
258*e7b8153eSMauro Carvalho Chehab ctx->name, hva->hec_mif_err_reg);
259*e7b8153eSMauro Carvalho Chehab ctx->hw_err = true;
260*e7b8153eSMauro Carvalho Chehab }
261*e7b8153eSMauro Carvalho Chehab out:
262*e7b8153eSMauro Carvalho Chehab complete(&hva->interrupt);
263*e7b8153eSMauro Carvalho Chehab
264*e7b8153eSMauro Carvalho Chehab return IRQ_HANDLED;
265*e7b8153eSMauro Carvalho Chehab }
266*e7b8153eSMauro Carvalho Chehab
hva_hw_get_ip_version(struct hva_dev * hva)267*e7b8153eSMauro Carvalho Chehab static unsigned long int hva_hw_get_ip_version(struct hva_dev *hva)
268*e7b8153eSMauro Carvalho Chehab {
269*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
270*e7b8153eSMauro Carvalho Chehab unsigned long int version;
271*e7b8153eSMauro Carvalho Chehab
272*e7b8153eSMauro Carvalho Chehab if (pm_runtime_resume_and_get(dev) < 0) {
273*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to get pm_runtime\n", HVA_PREFIX);
274*e7b8153eSMauro Carvalho Chehab mutex_unlock(&hva->protect_mutex);
275*e7b8153eSMauro Carvalho Chehab return -EFAULT;
276*e7b8153eSMauro Carvalho Chehab }
277*e7b8153eSMauro Carvalho Chehab
278*e7b8153eSMauro Carvalho Chehab version = readl_relaxed(hva->regs + HVA_HIF_REG_VERSION) &
279*e7b8153eSMauro Carvalho Chehab VERSION_ID_MASK;
280*e7b8153eSMauro Carvalho Chehab
281*e7b8153eSMauro Carvalho Chehab pm_runtime_put_autosuspend(dev);
282*e7b8153eSMauro Carvalho Chehab
283*e7b8153eSMauro Carvalho Chehab switch (version) {
284*e7b8153eSMauro Carvalho Chehab case HVA_VERSION_V400:
285*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s IP hardware version 0x%lx\n",
286*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, version);
287*e7b8153eSMauro Carvalho Chehab break;
288*e7b8153eSMauro Carvalho Chehab default:
289*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s unknown IP hardware version 0x%lx\n",
290*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, version);
291*e7b8153eSMauro Carvalho Chehab version = HVA_VERSION_UNKNOWN;
292*e7b8153eSMauro Carvalho Chehab break;
293*e7b8153eSMauro Carvalho Chehab }
294*e7b8153eSMauro Carvalho Chehab
295*e7b8153eSMauro Carvalho Chehab return version;
296*e7b8153eSMauro Carvalho Chehab }
297*e7b8153eSMauro Carvalho Chehab
hva_hw_probe(struct platform_device * pdev,struct hva_dev * hva)298*e7b8153eSMauro Carvalho Chehab int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva)
299*e7b8153eSMauro Carvalho Chehab {
300*e7b8153eSMauro Carvalho Chehab struct device *dev = &pdev->dev;
301*e7b8153eSMauro Carvalho Chehab struct resource *esram;
302*e7b8153eSMauro Carvalho Chehab int ret;
303*e7b8153eSMauro Carvalho Chehab
304*e7b8153eSMauro Carvalho Chehab WARN_ON(!hva);
305*e7b8153eSMauro Carvalho Chehab
306*e7b8153eSMauro Carvalho Chehab /* get memory for registers */
307*e7b8153eSMauro Carvalho Chehab hva->regs = devm_platform_ioremap_resource(pdev, 0);
308*e7b8153eSMauro Carvalho Chehab if (IS_ERR(hva->regs)) {
309*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to get regs\n", HVA_PREFIX);
310*e7b8153eSMauro Carvalho Chehab return PTR_ERR(hva->regs);
311*e7b8153eSMauro Carvalho Chehab }
312*e7b8153eSMauro Carvalho Chehab
313*e7b8153eSMauro Carvalho Chehab /* get memory for esram */
314*e7b8153eSMauro Carvalho Chehab esram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
315*e7b8153eSMauro Carvalho Chehab if (!esram) {
316*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to get esram\n", HVA_PREFIX);
317*e7b8153eSMauro Carvalho Chehab return -ENODEV;
318*e7b8153eSMauro Carvalho Chehab }
319*e7b8153eSMauro Carvalho Chehab hva->esram_addr = esram->start;
320*e7b8153eSMauro Carvalho Chehab hva->esram_size = resource_size(esram);
321*e7b8153eSMauro Carvalho Chehab
322*e7b8153eSMauro Carvalho Chehab dev_info(dev, "%s esram reserved for address: 0x%x size:%d\n",
323*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, hva->esram_addr, hva->esram_size);
324*e7b8153eSMauro Carvalho Chehab
325*e7b8153eSMauro Carvalho Chehab /* get clock resource */
326*e7b8153eSMauro Carvalho Chehab hva->clk = devm_clk_get(dev, "clk_hva");
327*e7b8153eSMauro Carvalho Chehab if (IS_ERR(hva->clk)) {
328*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to get clock\n", HVA_PREFIX);
329*e7b8153eSMauro Carvalho Chehab return PTR_ERR(hva->clk);
330*e7b8153eSMauro Carvalho Chehab }
331*e7b8153eSMauro Carvalho Chehab
332*e7b8153eSMauro Carvalho Chehab ret = clk_prepare(hva->clk);
333*e7b8153eSMauro Carvalho Chehab if (ret < 0) {
334*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to prepare clock\n", HVA_PREFIX);
335*e7b8153eSMauro Carvalho Chehab hva->clk = ERR_PTR(-EINVAL);
336*e7b8153eSMauro Carvalho Chehab return ret;
337*e7b8153eSMauro Carvalho Chehab }
338*e7b8153eSMauro Carvalho Chehab
339*e7b8153eSMauro Carvalho Chehab /* get status interruption resource */
340*e7b8153eSMauro Carvalho Chehab ret = platform_get_irq(pdev, 0);
341*e7b8153eSMauro Carvalho Chehab if (ret < 0)
342*e7b8153eSMauro Carvalho Chehab goto err_clk;
343*e7b8153eSMauro Carvalho Chehab hva->irq_its = ret;
344*e7b8153eSMauro Carvalho Chehab
345*e7b8153eSMauro Carvalho Chehab ret = devm_request_threaded_irq(dev, hva->irq_its, hva_hw_its_interrupt,
346*e7b8153eSMauro Carvalho Chehab hva_hw_its_irq_thread,
347*e7b8153eSMauro Carvalho Chehab IRQF_ONESHOT,
348*e7b8153eSMauro Carvalho Chehab "hva_its_irq", hva);
349*e7b8153eSMauro Carvalho Chehab if (ret) {
350*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to install status IRQ 0x%x\n",
351*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, hva->irq_its);
352*e7b8153eSMauro Carvalho Chehab goto err_clk;
353*e7b8153eSMauro Carvalho Chehab }
354*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_its);
355*e7b8153eSMauro Carvalho Chehab
356*e7b8153eSMauro Carvalho Chehab /* get error interruption resource */
357*e7b8153eSMauro Carvalho Chehab ret = platform_get_irq(pdev, 1);
358*e7b8153eSMauro Carvalho Chehab if (ret < 0)
359*e7b8153eSMauro Carvalho Chehab goto err_clk;
360*e7b8153eSMauro Carvalho Chehab hva->irq_err = ret;
361*e7b8153eSMauro Carvalho Chehab
362*e7b8153eSMauro Carvalho Chehab ret = devm_request_threaded_irq(dev, hva->irq_err, hva_hw_err_interrupt,
363*e7b8153eSMauro Carvalho Chehab hva_hw_err_irq_thread,
364*e7b8153eSMauro Carvalho Chehab IRQF_ONESHOT,
365*e7b8153eSMauro Carvalho Chehab "hva_err_irq", hva);
366*e7b8153eSMauro Carvalho Chehab if (ret) {
367*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to install error IRQ 0x%x\n",
368*e7b8153eSMauro Carvalho Chehab HVA_PREFIX, hva->irq_err);
369*e7b8153eSMauro Carvalho Chehab goto err_clk;
370*e7b8153eSMauro Carvalho Chehab }
371*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_err);
372*e7b8153eSMauro Carvalho Chehab
373*e7b8153eSMauro Carvalho Chehab /* initialise protection mutex */
374*e7b8153eSMauro Carvalho Chehab mutex_init(&hva->protect_mutex);
375*e7b8153eSMauro Carvalho Chehab
376*e7b8153eSMauro Carvalho Chehab /* initialise completion signal */
377*e7b8153eSMauro Carvalho Chehab init_completion(&hva->interrupt);
378*e7b8153eSMauro Carvalho Chehab
379*e7b8153eSMauro Carvalho Chehab /* initialise runtime power management */
380*e7b8153eSMauro Carvalho Chehab pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY_MS);
381*e7b8153eSMauro Carvalho Chehab pm_runtime_use_autosuspend(dev);
382*e7b8153eSMauro Carvalho Chehab pm_runtime_set_suspended(dev);
383*e7b8153eSMauro Carvalho Chehab pm_runtime_enable(dev);
384*e7b8153eSMauro Carvalho Chehab
385*e7b8153eSMauro Carvalho Chehab ret = pm_runtime_resume_and_get(dev);
386*e7b8153eSMauro Carvalho Chehab if (ret < 0) {
387*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to set PM\n", HVA_PREFIX);
388*e7b8153eSMauro Carvalho Chehab goto err_disable;
389*e7b8153eSMauro Carvalho Chehab }
390*e7b8153eSMauro Carvalho Chehab
391*e7b8153eSMauro Carvalho Chehab /* check IP hardware version */
392*e7b8153eSMauro Carvalho Chehab hva->ip_version = hva_hw_get_ip_version(hva);
393*e7b8153eSMauro Carvalho Chehab
394*e7b8153eSMauro Carvalho Chehab if (hva->ip_version == HVA_VERSION_UNKNOWN) {
395*e7b8153eSMauro Carvalho Chehab ret = -EINVAL;
396*e7b8153eSMauro Carvalho Chehab goto err_pm;
397*e7b8153eSMauro Carvalho Chehab }
398*e7b8153eSMauro Carvalho Chehab
399*e7b8153eSMauro Carvalho Chehab dev_info(dev, "%s found hva device (version 0x%lx)\n", HVA_PREFIX,
400*e7b8153eSMauro Carvalho Chehab hva->ip_version);
401*e7b8153eSMauro Carvalho Chehab
402*e7b8153eSMauro Carvalho Chehab return 0;
403*e7b8153eSMauro Carvalho Chehab
404*e7b8153eSMauro Carvalho Chehab err_pm:
405*e7b8153eSMauro Carvalho Chehab pm_runtime_put(dev);
406*e7b8153eSMauro Carvalho Chehab err_disable:
407*e7b8153eSMauro Carvalho Chehab pm_runtime_disable(dev);
408*e7b8153eSMauro Carvalho Chehab err_clk:
409*e7b8153eSMauro Carvalho Chehab if (hva->clk)
410*e7b8153eSMauro Carvalho Chehab clk_unprepare(hva->clk);
411*e7b8153eSMauro Carvalho Chehab
412*e7b8153eSMauro Carvalho Chehab return ret;
413*e7b8153eSMauro Carvalho Chehab }
414*e7b8153eSMauro Carvalho Chehab
hva_hw_remove(struct hva_dev * hva)415*e7b8153eSMauro Carvalho Chehab void hva_hw_remove(struct hva_dev *hva)
416*e7b8153eSMauro Carvalho Chehab {
417*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
418*e7b8153eSMauro Carvalho Chehab
419*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_its);
420*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_err);
421*e7b8153eSMauro Carvalho Chehab
422*e7b8153eSMauro Carvalho Chehab pm_runtime_put_autosuspend(dev);
423*e7b8153eSMauro Carvalho Chehab pm_runtime_disable(dev);
424*e7b8153eSMauro Carvalho Chehab }
425*e7b8153eSMauro Carvalho Chehab
hva_hw_runtime_suspend(struct device * dev)426*e7b8153eSMauro Carvalho Chehab int hva_hw_runtime_suspend(struct device *dev)
427*e7b8153eSMauro Carvalho Chehab {
428*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = dev_get_drvdata(dev);
429*e7b8153eSMauro Carvalho Chehab
430*e7b8153eSMauro Carvalho Chehab clk_disable_unprepare(hva->clk);
431*e7b8153eSMauro Carvalho Chehab
432*e7b8153eSMauro Carvalho Chehab return 0;
433*e7b8153eSMauro Carvalho Chehab }
434*e7b8153eSMauro Carvalho Chehab
hva_hw_runtime_resume(struct device * dev)435*e7b8153eSMauro Carvalho Chehab int hva_hw_runtime_resume(struct device *dev)
436*e7b8153eSMauro Carvalho Chehab {
437*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = dev_get_drvdata(dev);
438*e7b8153eSMauro Carvalho Chehab
439*e7b8153eSMauro Carvalho Chehab if (clk_prepare_enable(hva->clk)) {
440*e7b8153eSMauro Carvalho Chehab dev_err(hva->dev, "%s failed to prepare hva clk\n",
441*e7b8153eSMauro Carvalho Chehab HVA_PREFIX);
442*e7b8153eSMauro Carvalho Chehab return -EINVAL;
443*e7b8153eSMauro Carvalho Chehab }
444*e7b8153eSMauro Carvalho Chehab
445*e7b8153eSMauro Carvalho Chehab if (clk_set_rate(hva->clk, CLK_RATE)) {
446*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to set clock frequency\n",
447*e7b8153eSMauro Carvalho Chehab HVA_PREFIX);
448*e7b8153eSMauro Carvalho Chehab clk_disable_unprepare(hva->clk);
449*e7b8153eSMauro Carvalho Chehab return -EINVAL;
450*e7b8153eSMauro Carvalho Chehab }
451*e7b8153eSMauro Carvalho Chehab
452*e7b8153eSMauro Carvalho Chehab return 0;
453*e7b8153eSMauro Carvalho Chehab }
454*e7b8153eSMauro Carvalho Chehab
hva_hw_execute_task(struct hva_ctx * ctx,enum hva_hw_cmd_type cmd,struct hva_buffer * task)455*e7b8153eSMauro Carvalho Chehab int hva_hw_execute_task(struct hva_ctx *ctx, enum hva_hw_cmd_type cmd,
456*e7b8153eSMauro Carvalho Chehab struct hva_buffer *task)
457*e7b8153eSMauro Carvalho Chehab {
458*e7b8153eSMauro Carvalho Chehab struct hva_dev *hva = ctx_to_hdev(ctx);
459*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
460*e7b8153eSMauro Carvalho Chehab u8 client_id = ctx->id;
461*e7b8153eSMauro Carvalho Chehab int ret;
462*e7b8153eSMauro Carvalho Chehab u32 reg = 0;
463*e7b8153eSMauro Carvalho Chehab bool got_pm = false;
464*e7b8153eSMauro Carvalho Chehab
465*e7b8153eSMauro Carvalho Chehab mutex_lock(&hva->protect_mutex);
466*e7b8153eSMauro Carvalho Chehab
467*e7b8153eSMauro Carvalho Chehab /* enable irqs */
468*e7b8153eSMauro Carvalho Chehab enable_irq(hva->irq_its);
469*e7b8153eSMauro Carvalho Chehab enable_irq(hva->irq_err);
470*e7b8153eSMauro Carvalho Chehab
471*e7b8153eSMauro Carvalho Chehab if (pm_runtime_resume_and_get(dev) < 0) {
472*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s failed to get pm_runtime\n", ctx->name);
473*e7b8153eSMauro Carvalho Chehab ctx->sys_errors++;
474*e7b8153eSMauro Carvalho Chehab ret = -EFAULT;
475*e7b8153eSMauro Carvalho Chehab goto out;
476*e7b8153eSMauro Carvalho Chehab }
477*e7b8153eSMauro Carvalho Chehab got_pm = true;
478*e7b8153eSMauro Carvalho Chehab
479*e7b8153eSMauro Carvalho Chehab reg = readl_relaxed(hva->regs + HVA_HIF_REG_CLK_GATING);
480*e7b8153eSMauro Carvalho Chehab switch (cmd) {
481*e7b8153eSMauro Carvalho Chehab case H264_ENC:
482*e7b8153eSMauro Carvalho Chehab reg |= CLK_GATING_HVC;
483*e7b8153eSMauro Carvalho Chehab break;
484*e7b8153eSMauro Carvalho Chehab default:
485*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s unknown command 0x%x\n", ctx->name, cmd);
486*e7b8153eSMauro Carvalho Chehab ctx->encode_errors++;
487*e7b8153eSMauro Carvalho Chehab ret = -EFAULT;
488*e7b8153eSMauro Carvalho Chehab goto out;
489*e7b8153eSMauro Carvalho Chehab }
490*e7b8153eSMauro Carvalho Chehab writel_relaxed(reg, hva->regs + HVA_HIF_REG_CLK_GATING);
491*e7b8153eSMauro Carvalho Chehab
492*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: write configuration registers\n", ctx->name,
493*e7b8153eSMauro Carvalho Chehab __func__);
494*e7b8153eSMauro Carvalho Chehab
495*e7b8153eSMauro Carvalho Chehab /* byte swap config */
496*e7b8153eSMauro Carvalho Chehab writel_relaxed(BSM_CFG_VAL1, hva->regs + HVA_HIF_REG_BSM);
497*e7b8153eSMauro Carvalho Chehab
498*e7b8153eSMauro Carvalho Chehab /* define Max Opcode Size and Max Message Size for LMI and EMI */
499*e7b8153eSMauro Carvalho Chehab writel_relaxed(MIF_CFG_VAL3, hva->regs + HVA_HIF_REG_MIF_CFG);
500*e7b8153eSMauro Carvalho Chehab writel_relaxed(HEC_MIF_CFG_VAL, hva->regs + HVA_HIF_REG_HEC_MIF_CFG);
501*e7b8153eSMauro Carvalho Chehab
502*e7b8153eSMauro Carvalho Chehab /*
503*e7b8153eSMauro Carvalho Chehab * command FIFO: task_id[31:16] client_id[15:8] command_type[7:0]
504*e7b8153eSMauro Carvalho Chehab * the context identifier is provided as client identifier to the
505*e7b8153eSMauro Carvalho Chehab * hardware, and is retrieved in the interrupt functions from the
506*e7b8153eSMauro Carvalho Chehab * status register
507*e7b8153eSMauro Carvalho Chehab */
508*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s %s: send task (cmd: %d, task_desc: %pad)\n",
509*e7b8153eSMauro Carvalho Chehab ctx->name, __func__, cmd + (client_id << 8), &task->paddr);
510*e7b8153eSMauro Carvalho Chehab writel_relaxed(cmd + (client_id << 8), hva->regs + HVA_HIF_FIFO_CMD);
511*e7b8153eSMauro Carvalho Chehab writel_relaxed(task->paddr, hva->regs + HVA_HIF_FIFO_CMD);
512*e7b8153eSMauro Carvalho Chehab
513*e7b8153eSMauro Carvalho Chehab if (!wait_for_completion_timeout(&hva->interrupt,
514*e7b8153eSMauro Carvalho Chehab msecs_to_jiffies(2000))) {
515*e7b8153eSMauro Carvalho Chehab dev_err(dev, "%s %s: time out on completion\n", ctx->name,
516*e7b8153eSMauro Carvalho Chehab __func__);
517*e7b8153eSMauro Carvalho Chehab ctx->encode_errors++;
518*e7b8153eSMauro Carvalho Chehab ret = -EFAULT;
519*e7b8153eSMauro Carvalho Chehab goto out;
520*e7b8153eSMauro Carvalho Chehab }
521*e7b8153eSMauro Carvalho Chehab
522*e7b8153eSMauro Carvalho Chehab /* get encoding status */
523*e7b8153eSMauro Carvalho Chehab ret = ctx->hw_err ? -EFAULT : 0;
524*e7b8153eSMauro Carvalho Chehab
525*e7b8153eSMauro Carvalho Chehab ctx->encode_errors += ctx->hw_err ? 1 : 0;
526*e7b8153eSMauro Carvalho Chehab
527*e7b8153eSMauro Carvalho Chehab out:
528*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_its);
529*e7b8153eSMauro Carvalho Chehab disable_irq(hva->irq_err);
530*e7b8153eSMauro Carvalho Chehab
531*e7b8153eSMauro Carvalho Chehab switch (cmd) {
532*e7b8153eSMauro Carvalho Chehab case H264_ENC:
533*e7b8153eSMauro Carvalho Chehab reg &= ~CLK_GATING_HVC;
534*e7b8153eSMauro Carvalho Chehab writel_relaxed(reg, hva->regs + HVA_HIF_REG_CLK_GATING);
535*e7b8153eSMauro Carvalho Chehab break;
536*e7b8153eSMauro Carvalho Chehab default:
537*e7b8153eSMauro Carvalho Chehab dev_dbg(dev, "%s unknown command 0x%x\n", ctx->name, cmd);
538*e7b8153eSMauro Carvalho Chehab }
539*e7b8153eSMauro Carvalho Chehab
540*e7b8153eSMauro Carvalho Chehab if (got_pm)
541*e7b8153eSMauro Carvalho Chehab pm_runtime_put_autosuspend(dev);
542*e7b8153eSMauro Carvalho Chehab mutex_unlock(&hva->protect_mutex);
543*e7b8153eSMauro Carvalho Chehab
544*e7b8153eSMauro Carvalho Chehab return ret;
545*e7b8153eSMauro Carvalho Chehab }
546*e7b8153eSMauro Carvalho Chehab
547*e7b8153eSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_STI_HVA_DEBUGFS
548*e7b8153eSMauro Carvalho Chehab #define DUMP(reg) seq_printf(s, "%-30s: 0x%08X\n",\
549*e7b8153eSMauro Carvalho Chehab #reg, readl_relaxed(hva->regs + reg))
550*e7b8153eSMauro Carvalho Chehab
hva_hw_dump_regs(struct hva_dev * hva,struct seq_file * s)551*e7b8153eSMauro Carvalho Chehab void hva_hw_dump_regs(struct hva_dev *hva, struct seq_file *s)
552*e7b8153eSMauro Carvalho Chehab {
553*e7b8153eSMauro Carvalho Chehab struct device *dev = hva_to_dev(hva);
554*e7b8153eSMauro Carvalho Chehab
555*e7b8153eSMauro Carvalho Chehab mutex_lock(&hva->protect_mutex);
556*e7b8153eSMauro Carvalho Chehab
557*e7b8153eSMauro Carvalho Chehab if (pm_runtime_resume_and_get(dev) < 0) {
558*e7b8153eSMauro Carvalho Chehab seq_puts(s, "Cannot wake up IP\n");
559*e7b8153eSMauro Carvalho Chehab mutex_unlock(&hva->protect_mutex);
560*e7b8153eSMauro Carvalho Chehab return;
561*e7b8153eSMauro Carvalho Chehab }
562*e7b8153eSMauro Carvalho Chehab
563*e7b8153eSMauro Carvalho Chehab seq_printf(s, "Registers:\nReg @ = 0x%p\n", hva->regs);
564*e7b8153eSMauro Carvalho Chehab
565*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_RST);
566*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_RST_ACK);
567*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_MIF_CFG);
568*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HEC_MIF_CFG);
569*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_CFL);
570*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_SFL);
571*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_LMI_ERR);
572*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_EMI_ERR);
573*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HEC_MIF_ERR);
574*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HEC_STS);
575*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HVC_STS);
576*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HJE_STS);
577*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_CNT);
578*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_HEC_CHKSYN_DIS);
579*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_CLK_GATING);
580*e7b8153eSMauro Carvalho Chehab DUMP(HVA_HIF_REG_VERSION);
581*e7b8153eSMauro Carvalho Chehab
582*e7b8153eSMauro Carvalho Chehab pm_runtime_put_autosuspend(dev);
583*e7b8153eSMauro Carvalho Chehab mutex_unlock(&hva->protect_mutex);
584*e7b8153eSMauro Carvalho Chehab }
585*e7b8153eSMauro Carvalho Chehab #endif
586