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