blob: df50ca55a0673b7627ee25c0900c2dee5b74eeb4 [file] [log] [blame]
Srinu Gorlecf8c6752018-01-19 18:36:13 +05301/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <asm/dma-iommu.h>
15#include <linux/iommu.h>
16#include <linux/of.h>
17#include <linux/slab.h>
18#include <linux/sort.h>
19#include "msm_vidc_debug.h"
20#include "msm_vidc_resources.h"
21#include "msm_vidc_res_parse.h"
22#include "venus_boot.h"
23#include "soc/qcom/secure_buffer.h"
24#include <linux/io.h>
25
26enum clock_properties {
27 CLOCK_PROP_HAS_SCALING = 1 << 0,
28};
29
30static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
31{
32 return NULL;
33}
34
35static int msm_vidc_populate_legacy_context_bank(
36 struct msm_vidc_platform_resources *res);
37
38static size_t get_u32_array_num_elements(struct device_node *np,
39 char *name)
40{
41 int len;
42 size_t num_elements = 0;
43
44 if (!of_get_property(np, name, &len)) {
45 dprintk(VIDC_ERR, "Failed to read %s from device tree\n",
46 name);
47 goto fail_read;
48 }
49
50 num_elements = len / sizeof(u32);
51 if (num_elements <= 0) {
52 dprintk(VIDC_ERR, "%s not specified in device tree\n",
53 name);
54 goto fail_read;
55 }
56 return num_elements;
57
58fail_read:
59 return 0;
60}
61
62static inline enum imem_type read_imem_type(struct platform_device *pdev)
63{
64 bool is_compatible(char *compat)
65 {
66 return !!of_find_compatible_node(NULL, NULL, compat);
67 }
68
69 return is_compatible("qcom,msm-ocmem") ? IMEM_OCMEM :
70 is_compatible("qcom,msm-vmem") ? IMEM_VMEM :
71 IMEM_NONE;
72
73}
74
75static inline void msm_vidc_free_allowed_clocks_table(
76 struct msm_vidc_platform_resources *res)
77{
78 res->allowed_clks_tbl = NULL;
79}
80
81static inline void msm_vidc_free_cycles_per_mb_table(
82 struct msm_vidc_platform_resources *res)
83{
84 res->clock_freq_tbl.clk_prof_entries = NULL;
85}
86
87static inline void msm_vidc_free_platform_version_table(
88 struct msm_vidc_platform_resources *res)
89{
90 res->pf_ver_tbl = NULL;
91}
92
93static inline void msm_vidc_free_capability_version_table(
94 struct msm_vidc_platform_resources *res)
95{
96 res->pf_cap_tbl = NULL;
97}
98
99static inline void msm_vidc_free_freq_table(
100 struct msm_vidc_platform_resources *res)
101{
102 res->load_freq_tbl = NULL;
103}
104
105static inline void msm_vidc_free_dcvs_table(
106 struct msm_vidc_platform_resources *res)
107{
108 res->dcvs_tbl = NULL;
109}
110
111static inline void msm_vidc_free_dcvs_limit(
112 struct msm_vidc_platform_resources *res)
113{
114 res->dcvs_limit = NULL;
115}
116
117static inline void msm_vidc_free_imem_ab_table(
118 struct msm_vidc_platform_resources *res)
119{
120 res->imem_ab_tbl = NULL;
121}
122
123static inline void msm_vidc_free_reg_table(
124 struct msm_vidc_platform_resources *res)
125{
126 res->reg_set.reg_tbl = NULL;
127}
128
129static inline void msm_vidc_free_qdss_addr_table(
130 struct msm_vidc_platform_resources *res)
131{
132 res->qdss_addr_set.addr_tbl = NULL;
133}
134
135static inline void msm_vidc_free_bus_vectors(
136 struct msm_vidc_platform_resources *res)
137{
138 kfree(res->bus_set.bus_tbl);
139 res->bus_set.bus_tbl = NULL;
140 res->bus_set.count = 0;
141}
142
143static inline void msm_vidc_free_buffer_usage_table(
144 struct msm_vidc_platform_resources *res)
145{
146 res->buffer_usage_set.buffer_usage_tbl = NULL;
147}
148
149static inline void msm_vidc_free_regulator_table(
150 struct msm_vidc_platform_resources *res)
151{
152 int c = 0;
153
154 for (c = 0; c < res->regulator_set.count; ++c) {
155 struct regulator_info *rinfo =
156 &res->regulator_set.regulator_tbl[c];
157
158 rinfo->name = NULL;
159 }
160
161 res->regulator_set.regulator_tbl = NULL;
162 res->regulator_set.count = 0;
163}
164
165static inline void msm_vidc_free_clock_table(
166 struct msm_vidc_platform_resources *res)
167{
168 res->clock_set.clock_tbl = NULL;
169 res->clock_set.count = 0;
170}
171
172void msm_vidc_free_platform_resources(
173 struct msm_vidc_platform_resources *res)
174{
175 msm_vidc_free_clock_table(res);
176 msm_vidc_free_regulator_table(res);
177 msm_vidc_free_freq_table(res);
178 msm_vidc_free_platform_version_table(res);
179 msm_vidc_free_capability_version_table(res);
180 msm_vidc_free_dcvs_table(res);
181 msm_vidc_free_dcvs_limit(res);
182 msm_vidc_free_cycles_per_mb_table(res);
183 msm_vidc_free_allowed_clocks_table(res);
184 msm_vidc_free_reg_table(res);
185 msm_vidc_free_qdss_addr_table(res);
186 msm_vidc_free_bus_vectors(res);
187 msm_vidc_free_buffer_usage_table(res);
188}
189
190static int msm_vidc_load_reg_table(struct msm_vidc_platform_resources *res)
191{
192 struct reg_set *reg_set;
193 struct platform_device *pdev = res->pdev;
194 int i;
195 int rc = 0;
196
197 if (!of_find_property(pdev->dev.of_node, "qcom,reg-presets", NULL)) {
198 /* qcom,reg-presets is an optional property. It likely won't be
199 * present if we don't have any register settings to program
200 */
201 dprintk(VIDC_DBG, "qcom,reg-presets not found\n");
202 return 0;
203 }
204
205 reg_set = &res->reg_set;
206 reg_set->count = get_u32_array_num_elements(pdev->dev.of_node,
207 "qcom,reg-presets");
208 reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32);
209
210 if (!reg_set->count) {
211 dprintk(VIDC_DBG, "no elements in reg set\n");
212 return rc;
213 }
214
215 reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count *
216 sizeof(*(reg_set->reg_tbl)), GFP_KERNEL);
217 if (!reg_set->reg_tbl) {
218 dprintk(VIDC_ERR, "%s Failed to alloc register table\n",
219 __func__);
220 return -ENOMEM;
221 }
222
223 if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets",
224 (u32 *)reg_set->reg_tbl, reg_set->count * 2)) {
225 dprintk(VIDC_ERR, "Failed to read register table\n");
226 msm_vidc_free_reg_table(res);
227 return -EINVAL;
228 }
229 for (i = 0; i < reg_set->count; i++) {
230 dprintk(VIDC_DBG,
231 "reg = %x, value = %x\n",
232 reg_set->reg_tbl[i].reg,
233 reg_set->reg_tbl[i].value
234 );
235 }
236 return rc;
237}
238static int msm_vidc_load_qdss_table(struct msm_vidc_platform_resources *res)
239{
240 struct addr_set *qdss_addr_set;
241 struct platform_device *pdev = res->pdev;
242 int i;
243 int rc = 0;
244
245 if (!of_find_property(pdev->dev.of_node, "qcom,qdss-presets", NULL)) {
246 /* qcom,qdss-presets is an optional property. It likely won't be
247 * present if we don't have any register settings to program
248 */
249 dprintk(VIDC_DBG, "qcom,qdss-presets not found\n");
250 return rc;
251 }
252
253 qdss_addr_set = &res->qdss_addr_set;
254 qdss_addr_set->count = get_u32_array_num_elements(pdev->dev.of_node,
255 "qcom,qdss-presets");
256 qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32);
257
258 if (!qdss_addr_set->count) {
259 dprintk(VIDC_DBG, "no elements in qdss reg set\n");
260 return rc;
261 }
262
263 qdss_addr_set->addr_tbl = devm_kzalloc(&pdev->dev,
264 qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl),
265 GFP_KERNEL);
266 if (!qdss_addr_set->addr_tbl) {
267 dprintk(VIDC_ERR, "%s Failed to alloc register table\n",
268 __func__);
269 rc = -ENOMEM;
270 goto err_qdss_addr_tbl;
271 }
272
273 rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,qdss-presets",
274 (u32 *)qdss_addr_set->addr_tbl, qdss_addr_set->count * 2);
275 if (rc) {
276 dprintk(VIDC_ERR, "Failed to read qdss address table\n");
277 msm_vidc_free_qdss_addr_table(res);
278 rc = -EINVAL;
279 goto err_qdss_addr_tbl;
280 }
281
282 for (i = 0; i < qdss_addr_set->count; i++) {
283 dprintk(VIDC_DBG, "qdss addr = %x, value = %x\n",
284 qdss_addr_set->addr_tbl[i].start,
285 qdss_addr_set->addr_tbl[i].size);
286 }
287err_qdss_addr_tbl:
288 return rc;
289}
290
291static int msm_vidc_load_imem_ab_table(struct msm_vidc_platform_resources *res)
292{
293 int num_elements = 0;
294 struct platform_device *pdev = res->pdev;
295
296 if (!of_find_property(pdev->dev.of_node, "qcom,imem-ab-tbl", NULL)) {
297 /* optional property */
298 dprintk(VIDC_DBG, "qcom,imem-freq-tbl not found\n");
299 return 0;
300 }
301
302 num_elements = get_u32_array_num_elements(pdev->dev.of_node,
303 "qcom,imem-ab-tbl");
304 num_elements /= (sizeof(*res->imem_ab_tbl) / sizeof(u32));
305 if (!num_elements) {
306 dprintk(VIDC_ERR, "no elements in imem ab table\n");
307 return -EINVAL;
308 }
309
310 res->imem_ab_tbl = devm_kzalloc(&pdev->dev, num_elements *
311 sizeof(*res->imem_ab_tbl), GFP_KERNEL);
312 if (!res->imem_ab_tbl) {
313 dprintk(VIDC_ERR, "Failed to alloc imem_ab_tbl\n");
314 return -ENOMEM;
315 }
316
317 if (of_property_read_u32_array(pdev->dev.of_node,
318 "qcom,imem-ab-tbl", (u32 *)res->imem_ab_tbl,
319 num_elements * sizeof(*res->imem_ab_tbl) / sizeof(u32))) {
320 dprintk(VIDC_ERR, "Failed to read imem_ab_tbl\n");
321 msm_vidc_free_imem_ab_table(res);
322 return -EINVAL;
323 }
324
325 res->imem_ab_tbl_size = num_elements;
326
327 return 0;
328}
329
330/**
331 * msm_vidc_load_u32_table() - load dtsi table entries
332 * @pdev: A pointer to the platform device.
333 * @of_node: A pointer to the device node.
334 * @table_name: A pointer to the dtsi table entry name.
335 * @struct_size: The size of the structure which is nothing but
336 * a single entry in the dtsi table.
337 * @table: A pointer to the table pointer which needs to be
338 * filled by the dtsi table entries.
339 * @num_elements: Number of elements pointer which needs to be filled
340 * with the number of elements in the table.
341 *
342 * This is a generic implementation to load single or multiple array
343 * table from dtsi. The array elements should be of size equal to u32.
344 *
345 * Return: Return '0' for success else appropriate error value.
346 */
347int msm_vidc_load_u32_table(struct platform_device *pdev,
348 struct device_node *of_node, char *table_name, int struct_size,
349 u32 **table, u32 *num_elements)
350{
351 int rc = 0, num_elemts = 0;
352 u32 *ptbl = NULL;
353
354 if (!of_find_property(of_node, table_name, NULL)) {
355 dprintk(VIDC_DBG, "%s not found\n", table_name);
356 return 0;
357 }
358
359 num_elemts = get_u32_array_num_elements(of_node, table_name);
360 if (!num_elemts) {
361 dprintk(VIDC_ERR, "no elements in %s\n", table_name);
362 return 0;
363 }
364 num_elemts /= struct_size / sizeof(u32);
365
366 ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL);
367 if (!ptbl) {
368 dprintk(VIDC_ERR, "Failed to alloc table %s\n", table_name);
369 return -ENOMEM;
370 }
371
372 if (of_property_read_u32_array(of_node, table_name, ptbl,
373 num_elemts * struct_size / sizeof(u32))) {
374 dprintk(VIDC_ERR, "Failed to read %s\n", table_name);
375 return -EINVAL;
376 }
377
378 *table = ptbl;
379 if (num_elements)
380 *num_elements = num_elemts;
381
382 return rc;
383}
384
385static int msm_vidc_load_platform_version_table(
386 struct msm_vidc_platform_resources *res)
387{
388 int rc = 0;
389 struct platform_device *pdev = res->pdev;
390
391 if (!of_find_property(pdev->dev.of_node,
392 "qcom,platform-version", NULL)) {
393 dprintk(VIDC_DBG, "qcom,platform-version not found\n");
394 return 0;
395 }
396
397 rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node,
398 "qcom,platform-version",
399 sizeof(*res->pf_ver_tbl),
400 (u32 **)&res->pf_ver_tbl,
401 NULL);
402 if (rc) {
403 dprintk(VIDC_ERR,
404 "%s: failed to read platform version table\n",
405 __func__);
406 return rc;
407 }
408
409 return 0;
410}
411
412static int msm_vidc_load_capability_version_table(
413 struct msm_vidc_platform_resources *res)
414{
415 int rc = 0;
416 struct platform_device *pdev = res->pdev;
417
418 if (!of_find_property(pdev->dev.of_node,
419 "qcom,capability-version", NULL)) {
420 dprintk(VIDC_DBG, "qcom,capability-version not found\n");
421 return 0;
422 }
423
424 rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node,
425 "qcom,capability-version",
426 sizeof(*res->pf_cap_tbl),
427 (u32 **)&res->pf_cap_tbl,
428 NULL);
429 if (rc) {
430 dprintk(VIDC_ERR,
431 "%s: failed to read platform version table\n",
432 __func__);
433 return rc;
434 }
435
436 return 0;
437}
438
439static void clock_override(struct platform_device *pdev,
440 struct msm_vidc_platform_resources *platform_res,
441 struct allowed_clock_rates_table *clk_table)
442{
443 struct resource *res;
444 void __iomem *base = NULL;
445 u32 config_efuse, bin;
446 u32 venus_uplift_freq;
447 u32 is_speed_bin = 7;
448 int rc = 0;
449
450 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
451 "efuse");
452 if (!res) {
453 dprintk(VIDC_DBG,
454 "Failed to get resource efuse\n");
455 return;
456 }
457
458 rc = of_property_read_u32(pdev->dev.of_node, "qcom,venus-uplift-freq",
459 &venus_uplift_freq);
460 if (rc) {
461 dprintk(VIDC_DBG,
462 "Failed to determine venus-uplift-freq: %d\n", rc);
463 return;
464 }
465
466 if (!of_find_property(pdev->dev.of_node,
467 "qcom,speedbin-version", NULL)) {
468 dprintk(VIDC_DBG, "qcom,speedbin-version not found\n");
469 return;
470 }
471
472 rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node,
473 "qcom,speedbin-version",
474 sizeof(*platform_res->pf_speedbin_tbl),
475 (u32 **)&platform_res->pf_speedbin_tbl,
476 NULL);
477 if (rc) {
478 dprintk(VIDC_ERR,
479 "%s: failed to read speedbin version table\n",
480 __func__);
481 return;
482 }
483 base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
484 if (!base) {
485 dev_warn(&pdev->dev,
486 "Unable to ioremap efuse reg address. Defaulting to 0.\n");
487 return;
488 }
489
490 config_efuse = readl_relaxed(base);
491 devm_iounmap(&pdev->dev, base);
492
493 bin = (config_efuse >> platform_res->pf_speedbin_tbl->version_shift) &
494 platform_res->pf_speedbin_tbl->version_mask;
495
496 if (bin == is_speed_bin) {
497 dprintk(VIDC_DBG,
498 "Venus speed binning available overwriting %d to %d\n",
499 clk_table[0].clock_rate, venus_uplift_freq);
500 clk_table[0].clock_rate = venus_uplift_freq;
501 }
502}
503
504static int msm_vidc_load_allowed_clocks_table(
505 struct msm_vidc_platform_resources *res)
506{
507 int rc = 0;
508 struct platform_device *pdev = res->pdev;
509
510 if (!of_find_property(pdev->dev.of_node,
511 "qcom,allowed-clock-rates", NULL)) {
512 dprintk(VIDC_DBG, "qcom,allowed-clock-rates not found\n");
513 return 0;
514 }
515
516 rc = msm_vidc_load_u32_table(pdev, pdev->dev.of_node,
517 "qcom,allowed-clock-rates",
518 sizeof(*res->allowed_clks_tbl),
519 (u32 **)&res->allowed_clks_tbl,
520 &res->allowed_clks_tbl_size);
521 if (rc) {
522 dprintk(VIDC_ERR,
523 "%s: failed to read allowed clocks table\n", __func__);
524 return rc;
525 }
526 if (res->allowed_clks_tbl_size)
527 clock_override(pdev, res, res->allowed_clks_tbl);
528
529 return 0;
530}
531
532static int msm_vidc_load_cycles_per_mb_table(
533 struct msm_vidc_platform_resources *res)
534{
535 int rc = 0, i = 0;
536 struct clock_freq_table *clock_freq_tbl = &res->clock_freq_tbl;
537 struct clock_profile_entry *entry = NULL;
538 struct device_node *parent_node = NULL;
539 struct device_node *child_node = NULL;
540 struct platform_device *pdev = res->pdev;
541
542 parent_node = of_find_node_by_name(pdev->dev.of_node,
543 "qcom,clock-freq-tbl");
544 if (!parent_node) {
545 dprintk(VIDC_DBG, "Node qcom,clock-freq-tbl not found.\n");
546 return 0;
547 }
548
549 clock_freq_tbl->count = 0;
550 for_each_child_of_node(parent_node, child_node)
551 clock_freq_tbl->count++;
552
553 if (!clock_freq_tbl->count) {
554 dprintk(VIDC_DBG, "No child nodes in qcom,clock-freq-tbl\n");
555 return 0;
556 }
557
558 clock_freq_tbl->clk_prof_entries = devm_kzalloc(&pdev->dev,
559 sizeof(*clock_freq_tbl->clk_prof_entries) *
560 clock_freq_tbl->count, GFP_KERNEL);
561 if (!clock_freq_tbl->clk_prof_entries) {
562 dprintk(VIDC_DBG, "no memory to allocate clk_prof_entries\n");
563 return -ENOMEM;
564 }
565
566 for_each_child_of_node(parent_node, child_node) {
567
568 if (i >= clock_freq_tbl->count) {
569 dprintk(VIDC_ERR,
570 "qcom,clock-freq-tbl: invalid child node %d, max is %d\n",
571 i, clock_freq_tbl->count);
572 break;
573 }
574
575 entry = &clock_freq_tbl->clk_prof_entries[i];
576 dprintk(VIDC_DBG, "qcom,clock-freq-tbl: profile[%d]\n", i);
577
578 if (of_find_property(child_node, "qcom,codec-mask", NULL)) {
579 rc = of_property_read_u32(child_node,
580 "qcom,codec-mask", &entry->codec_mask);
581 if (rc) {
582 dprintk(VIDC_ERR,
583 "qcom,codec-mask not found\n");
584 goto error;
585 }
586 } else {
587 entry->codec_mask = 0;
588 }
589 dprintk(VIDC_DBG, "codec_mask %#x\n", entry->codec_mask);
590
591 if (of_find_property(child_node, "qcom,cycles-per-mb", NULL)) {
592 rc = of_property_read_u32(child_node,
593 "qcom,cycles-per-mb", &entry->cycles);
594 if (rc) {
595 dprintk(VIDC_ERR,
596 "qcom,cycles-per-mb not found\n");
597 goto error;
598 }
599 } else {
600 entry->cycles = 0;
601 }
602 dprintk(VIDC_DBG, "cycles_per_mb %d\n", entry->cycles);
603
604 if (of_find_property(child_node,
605 "qcom,low-power-mode-factor", NULL)) {
606 rc = of_property_read_u32(child_node,
607 "qcom,low-power-mode-factor",
608 &entry->low_power_factor);
609 if (rc) {
610 dprintk(VIDC_ERR,
611 "qcom,low-power-mode-factor not found\n");
612 goto error;
613 }
614 } else {
615 entry->low_power_factor = 0;
616 }
617 dprintk(VIDC_DBG, "low_power_factor %d\n",
618 entry->low_power_factor);
619
620 i++;
621 }
622
623error:
624 return rc;
625}
626
627static int msm_vidc_load_freq_table(struct msm_vidc_platform_resources *res)
628{
629 int rc = 0;
630 int num_elements = 0;
631 struct platform_device *pdev = res->pdev;
632
633 /* A comparator to compare loads (needed later on) */
634 int cmp(const void *a, const void *b)
635 {
636 /* want to sort in reverse so flip the comparison */
637 return ((struct load_freq_table *)b)->load -
638 ((struct load_freq_table *)a)->load;
639 }
640
641 if (!of_find_property(pdev->dev.of_node, "qcom,load-freq-tbl", NULL)) {
642 /* qcom,load-freq-tbl is an optional property. It likely won't
643 * be present on cores that we can't clock scale on.
644 */
645 dprintk(VIDC_DBG, "qcom,load-freq-tbl not found\n");
646 return 0;
647 }
648
649 num_elements = get_u32_array_num_elements(pdev->dev.of_node,
650 "qcom,load-freq-tbl");
651 num_elements /= sizeof(*res->load_freq_tbl) / sizeof(u32);
652 if (!num_elements) {
653 dprintk(VIDC_ERR, "no elements in frequency table\n");
654 return rc;
655 }
656
657 res->load_freq_tbl = devm_kzalloc(&pdev->dev, num_elements *
658 sizeof(*res->load_freq_tbl), GFP_KERNEL);
659 if (!res->load_freq_tbl) {
660 dprintk(VIDC_ERR,
661 "%s Failed to alloc load_freq_tbl\n",
662 __func__);
663 return -ENOMEM;
664 }
665
666 if (of_property_read_u32_array(pdev->dev.of_node,
667 "qcom,load-freq-tbl", (u32 *)res->load_freq_tbl,
668 num_elements * sizeof(*res->load_freq_tbl) / sizeof(u32))) {
669 dprintk(VIDC_ERR, "Failed to read frequency table\n");
670 msm_vidc_free_freq_table(res);
671 return -EINVAL;
672 }
673
674 res->load_freq_tbl_size = num_elements;
675
676 /* The entries in the DT might not be sorted (for aesthetic purposes).
677 * Given that we expect the loads in descending order for our scaling
678 * logic to work, just sort it ourselves
679 */
680 sort(res->load_freq_tbl, res->load_freq_tbl_size,
681 sizeof(*res->load_freq_tbl), cmp, NULL);
682 return rc;
683}
684
685static int msm_vidc_load_dcvs_table(struct msm_vidc_platform_resources *res)
686{
687 int rc = 0;
688 int num_elements = 0;
689 struct platform_device *pdev = res->pdev;
690
691 if (!of_find_property(pdev->dev.of_node, "qcom,dcvs-tbl", NULL)) {
692 /*
693 * qcom,dcvs-tbl is an optional property. Incase qcom,dcvs-limit
694 * property is present, it becomes mandatory. It likely won't
695 * be present on targets that does not support the feature
696 */
697 dprintk(VIDC_DBG, "qcom,dcvs-tbl not found\n");
698 return 0;
699 }
700
701 num_elements = get_u32_array_num_elements(pdev->dev.of_node,
702 "qcom,dcvs-tbl");
703 num_elements /= sizeof(*res->dcvs_tbl) / sizeof(u32);
704 if (!num_elements) {
705 dprintk(VIDC_ERR, "no elements in dcvs table\n");
706 return rc;
707 }
708
709 res->dcvs_tbl = devm_kzalloc(&pdev->dev, num_elements *
710 sizeof(*res->dcvs_tbl), GFP_KERNEL);
711 if (!res->dcvs_tbl) {
712 dprintk(VIDC_ERR,
713 "%s Failed to alloc dcvs_tbl\n",
714 __func__);
715 return -ENOMEM;
716 }
717
718 if (of_property_read_u32_array(pdev->dev.of_node,
719 "qcom,dcvs-tbl", (u32 *)res->dcvs_tbl,
720 num_elements * sizeof(*res->dcvs_tbl) / sizeof(u32))) {
721 dprintk(VIDC_ERR, "Failed to read dcvs table\n");
722 msm_vidc_free_dcvs_table(res);
723 return -EINVAL;
724 }
725 res->dcvs_tbl_size = num_elements;
726
727 return rc;
728}
729
730static int msm_vidc_load_dcvs_limit(struct msm_vidc_platform_resources *res)
731{
732 int rc = 0;
733 int num_elements = 0;
734 struct platform_device *pdev = res->pdev;
735
736 if (!of_find_property(pdev->dev.of_node, "qcom,dcvs-limit", NULL)) {
737 /*
738 * qcom,dcvs-limit is an optional property. Incase qcom,dcvs-tbl
739 * property is present, it becomes mandatory. It likely won't
740 * be present on targets that does not support the feature
741 */
742 dprintk(VIDC_DBG, "qcom,dcvs-limit not found\n");
743 return 0;
744 }
745
746 num_elements = get_u32_array_num_elements(pdev->dev.of_node,
747 "qcom,dcvs-limit");
748 num_elements /= sizeof(*res->dcvs_limit) / sizeof(u32);
749 if (!num_elements) {
750 dprintk(VIDC_ERR, "no elements in dcvs limit\n");
751 res->dcvs_limit = NULL;
752 return rc;
753 }
754
755 res->dcvs_limit = devm_kzalloc(&pdev->dev, num_elements *
756 sizeof(*res->dcvs_limit), GFP_KERNEL);
757 if (!res->dcvs_limit) {
758 dprintk(VIDC_ERR,
759 "%s Failed to alloc dcvs_limit\n",
760 __func__);
761 return -ENOMEM;
762 }
763 if (of_property_read_u32_array(pdev->dev.of_node,
764 "qcom,dcvs-limit", (u32 *)res->dcvs_limit,
765 num_elements * sizeof(*res->dcvs_limit) / sizeof(u32))) {
766 dprintk(VIDC_ERR, "Failed to read dcvs limit\n");
767 msm_vidc_free_dcvs_limit(res);
768 return -EINVAL;
769 }
770
771 return rc;
772}
773
774
775static int msm_vidc_populate_bus(struct device *dev,
776 struct msm_vidc_platform_resources *res)
777{
778 struct bus_set *buses = &res->bus_set;
779 const char *temp_name = NULL;
780 struct bus_info *bus = NULL, *temp_table;
781 u32 range[2];
782 int rc = 0;
783
784 temp_table = krealloc(buses->bus_tbl, sizeof(*temp_table) *
785 (buses->count + 1), GFP_KERNEL);
786 if (!temp_table) {
787 dprintk(VIDC_ERR, "%s: Failed to allocate memory", __func__);
788 rc = -ENOMEM;
789 goto err_bus;
790 }
791
792 buses->bus_tbl = temp_table;
793 bus = &buses->bus_tbl[buses->count];
794
795 rc = of_property_read_string(dev->of_node, "label", &temp_name);
796 if (rc) {
797 dprintk(VIDC_ERR, "'label' not found in node\n");
798 goto err_bus;
799 }
800 /* need a non-const version of name, hence copying it over */
801 bus->name = devm_kstrdup(dev, temp_name, GFP_KERNEL);
802 if (!bus->name) {
803 rc = -ENOMEM;
804 goto err_bus;
805 }
806
807 rc = of_property_read_u32(dev->of_node, "qcom,bus-master",
808 &bus->master);
809 if (rc) {
810 dprintk(VIDC_ERR, "'qcom,bus-master' not found in node\n");
811 goto err_bus;
812 }
813
814 rc = of_property_read_u32(dev->of_node, "qcom,bus-slave", &bus->slave);
815 if (rc) {
816 dprintk(VIDC_ERR, "'qcom,bus-slave' not found in node\n");
817 goto err_bus;
818 }
819
820 rc = of_property_read_string(dev->of_node, "qcom,bus-governor",
821 &bus->governor);
822 if (rc) {
823 rc = 0;
824 dprintk(VIDC_DBG,
825 "'qcom,bus-governor' not found, default to performance governor\n");
826 bus->governor = "performance";
827 }
828
829 rc = of_property_read_u32_array(dev->of_node, "qcom,bus-range-kbps",
830 range, ARRAY_SIZE(range));
831 if (rc) {
832 rc = 0;
833 dprintk(VIDC_DBG,
834 "'qcom,range' not found defaulting to <0 INT_MAX>\n");
835 range[0] = 0;
836 range[1] = INT_MAX;
837 }
838
839 bus->range[0] = range[0]; /* min */
840 bus->range[1] = range[1]; /* max */
841
842 buses->count++;
843 bus->dev = dev;
844 dprintk(VIDC_DBG, "Found bus %s [%d->%d] with governor %s\n",
845 bus->name, bus->master, bus->slave, bus->governor);
846err_bus:
847 return rc;
848}
849
850static int msm_vidc_load_buffer_usage_table(
851 struct msm_vidc_platform_resources *res)
852{
853 int rc = 0;
854 struct platform_device *pdev = res->pdev;
855 struct buffer_usage_set *buffer_usage_set = &res->buffer_usage_set;
856
857 if (!of_find_property(pdev->dev.of_node,
858 "qcom,buffer-type-tz-usage-table", NULL)) {
859 /* qcom,buffer-type-tz-usage-table is an optional property. It
860 * likely won't be present if the core doesn't support content
861 * protection
862 */
863 dprintk(VIDC_DBG, "buffer-type-tz-usage-table not found\n");
864 return 0;
865 }
866
867 buffer_usage_set->count = get_u32_array_num_elements(
868 pdev->dev.of_node, "qcom,buffer-type-tz-usage-table");
869 buffer_usage_set->count /=
870 sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32);
871 if (!buffer_usage_set->count) {
872 dprintk(VIDC_DBG, "no elements in buffer usage set\n");
873 return 0;
874 }
875
876 buffer_usage_set->buffer_usage_tbl = devm_kzalloc(&pdev->dev,
877 buffer_usage_set->count *
878 sizeof(*buffer_usage_set->buffer_usage_tbl),
879 GFP_KERNEL);
880 if (!buffer_usage_set->buffer_usage_tbl) {
881 dprintk(VIDC_ERR, "%s Failed to alloc buffer usage table\n",
882 __func__);
883 rc = -ENOMEM;
884 goto err_load_buf_usage;
885 }
886
887 rc = of_property_read_u32_array(pdev->dev.of_node,
888 "qcom,buffer-type-tz-usage-table",
889 (u32 *)buffer_usage_set->buffer_usage_tbl,
890 buffer_usage_set->count *
891 sizeof(*buffer_usage_set->buffer_usage_tbl) / sizeof(u32));
892 if (rc) {
893 dprintk(VIDC_ERR, "Failed to read buffer usage table\n");
894 goto err_load_buf_usage;
895 }
896
897 return 0;
898err_load_buf_usage:
899 msm_vidc_free_buffer_usage_table(res);
900 return rc;
901}
902
903static int msm_vidc_load_regulator_table(
904 struct msm_vidc_platform_resources *res)
905{
906 int rc = 0;
907 struct platform_device *pdev = res->pdev;
908 struct regulator_set *regulators = &res->regulator_set;
909 struct device_node *domains_parent_node = NULL;
910 struct property *domains_property = NULL;
911 int reg_count = 0;
912
913 regulators->count = 0;
914 regulators->regulator_tbl = NULL;
915
916 domains_parent_node = pdev->dev.of_node;
917 for_each_property_of_node(domains_parent_node, domains_property) {
918 const char *search_string = "-supply";
919 char *supply;
920 bool matched = false;
921
922 /* check if current property is possibly a regulator */
923 supply = strnstr(domains_property->name, search_string,
924 strlen(domains_property->name) + 1);
925 matched = supply && (*(supply + strlen(search_string)) == '\0');
926 if (!matched)
927 continue;
928
929 reg_count++;
930 }
931
932 regulators->regulator_tbl = devm_kzalloc(&pdev->dev,
933 sizeof(*regulators->regulator_tbl) *
934 reg_count, GFP_KERNEL);
935
936 if (!regulators->regulator_tbl) {
937 rc = -ENOMEM;
938 dprintk(VIDC_ERR,
939 "Failed to alloc memory for regulator table\n");
940 goto err_reg_tbl_alloc;
941 }
942
943 for_each_property_of_node(domains_parent_node, domains_property) {
944 const char *search_string = "-supply";
945 char *supply;
946 bool matched = false;
947 struct device_node *regulator_node = NULL;
948 struct regulator_info *rinfo = NULL;
949
950 /* check if current property is possibly a regulator */
951 supply = strnstr(domains_property->name, search_string,
952 strlen(domains_property->name) + 1);
953 matched = supply && (supply[strlen(search_string)] == '\0');
954 if (!matched)
955 continue;
956
957 /* make sure prop isn't being misused */
958 regulator_node = of_parse_phandle(domains_parent_node,
959 domains_property->name, 0);
960 if (IS_ERR(regulator_node)) {
961 dprintk(VIDC_WARN, "%s is not a phandle\n",
962 domains_property->name);
963 continue;
964 }
965 regulators->count++;
966
967 /* populate regulator info */
968 rinfo = &regulators->regulator_tbl[regulators->count - 1];
969 rinfo->name = devm_kzalloc(&pdev->dev,
970 (supply - domains_property->name) + 1, GFP_KERNEL);
971 if (!rinfo->name) {
972 rc = -ENOMEM;
973 dprintk(VIDC_ERR,
974 "Failed to alloc memory for regulator name\n");
975 goto err_reg_name_alloc;
976 }
977 strlcpy(rinfo->name, domains_property->name,
978 (supply - domains_property->name) + 1);
979
980 rinfo->has_hw_power_collapse = of_property_read_bool(
981 regulator_node, "qcom,support-hw-trigger");
982
983 dprintk(VIDC_DBG, "Found regulator %s: h/w collapse = %s\n",
984 rinfo->name,
985 rinfo->has_hw_power_collapse ? "yes" : "no");
986 }
987
988 if (!regulators->count)
989 dprintk(VIDC_DBG, "No regulators found");
990
991 return 0;
992
993err_reg_name_alloc:
994err_reg_tbl_alloc:
995 msm_vidc_free_regulator_table(res);
996 return rc;
997}
998
999static int msm_vidc_load_clock_table(
1000 struct msm_vidc_platform_resources *res)
1001{
1002 int rc = 0, num_clocks = 0, c = 0;
1003 struct platform_device *pdev = res->pdev;
1004 int *clock_props = NULL;
1005 struct clock_set *clocks = &res->clock_set;
1006
1007 num_clocks = of_property_count_strings(pdev->dev.of_node,
1008 "clock-names");
1009 if (num_clocks <= 0) {
1010 dprintk(VIDC_DBG, "No clocks found\n");
1011 clocks->count = 0;
1012 rc = 0;
1013 goto err_load_clk_table_fail;
1014 }
1015
1016 clock_props = devm_kzalloc(&pdev->dev, num_clocks *
1017 sizeof(*clock_props), GFP_KERNEL);
1018 if (!clock_props) {
1019 dprintk(VIDC_ERR, "No memory to read clock properties\n");
1020 rc = -ENOMEM;
1021 goto err_load_clk_table_fail;
1022 }
1023
1024 rc = of_property_read_u32_array(pdev->dev.of_node,
1025 "qcom,clock-configs", clock_props,
1026 num_clocks);
1027 if (rc) {
1028 dprintk(VIDC_ERR, "Failed to read clock properties: %d\n", rc);
1029 goto err_load_clk_prop_fail;
1030 }
1031
1032 clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl)
1033 * num_clocks, GFP_KERNEL);
1034 if (!clocks->clock_tbl) {
1035 dprintk(VIDC_ERR, "Failed to allocate memory for clock tbl\n");
1036 rc = -ENOMEM;
1037 goto err_load_clk_prop_fail;
1038 }
1039
1040 clocks->count = num_clocks;
1041 dprintk(VIDC_DBG, "Found %d clocks\n", num_clocks);
1042
1043 for (c = 0; c < num_clocks; ++c) {
1044 struct clock_info *vc = &res->clock_set.clock_tbl[c];
1045
1046 of_property_read_string_index(pdev->dev.of_node,
1047 "clock-names", c, &vc->name);
1048
1049 if (clock_props[c] & CLOCK_PROP_HAS_SCALING) {
1050 vc->has_scaling = true;
1051 vc->count = res->load_freq_tbl_size;
1052 vc->load_freq_tbl = res->load_freq_tbl;
1053 } else {
1054 vc->count = 0;
1055 vc->load_freq_tbl = NULL;
1056 vc->has_scaling = false;
1057 }
1058
1059 dprintk(VIDC_DBG, "Found clock %s: scale-able = %s\n", vc->name,
1060 vc->count ? "yes" : "no");
1061 }
1062
1063
1064 return 0;
1065
1066err_load_clk_prop_fail:
1067err_load_clk_table_fail:
1068 return rc;
1069}
1070
1071int read_platform_resources_from_dt(
1072 struct msm_vidc_platform_resources *res)
1073{
1074 struct platform_device *pdev = res->pdev;
1075 struct resource *kres = NULL;
1076 int rc = 0;
1077 uint32_t firmware_base = 0;
1078
1079 if (!pdev->dev.of_node) {
1080 dprintk(VIDC_ERR, "DT node not found\n");
1081 return -ENOENT;
1082 }
1083
1084 INIT_LIST_HEAD(&res->context_banks);
1085
1086 res->firmware_base = (phys_addr_t)firmware_base;
1087
1088 kres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1089 res->register_base = kres ? kres->start : -1;
1090 res->register_size = kres ? (kres->end + 1 - kres->start) : -1;
1091
1092 kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1093 res->irq = kres ? kres->start : -1;
1094
1095 of_property_read_u32(pdev->dev.of_node,
1096 "qcom,imem-size", &res->imem_size);
1097 res->imem_type = read_imem_type(pdev);
1098
1099 res->sys_idle_indicator = of_property_read_bool(pdev->dev.of_node,
1100 "qcom,enable-idle-indicator");
1101
1102 res->thermal_mitigable =
1103 of_property_read_bool(pdev->dev.of_node,
1104 "qcom,enable-thermal-mitigation");
1105
1106 rc = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name",
1107 &res->fw_name);
1108 if (rc) {
1109 dprintk(VIDC_ERR, "Failed to read firmware name: %d\n", rc);
1110 goto err_load_freq_table;
1111 }
1112 dprintk(VIDC_DBG, "Firmware filename: %s\n", res->fw_name);
1113
1114 rc = of_property_read_string(pdev->dev.of_node, "qcom,hfi-version",
1115 &res->hfi_version);
1116 if (rc)
1117 dprintk(VIDC_DBG, "HFI packetization will default to legacy\n");
1118
1119 rc = msm_vidc_load_platform_version_table(res);
1120 if (rc)
1121 dprintk(VIDC_ERR, "Failed to load pf version table: %d\n", rc);
1122
1123 rc = msm_vidc_load_capability_version_table(res);
1124 if (rc)
1125 dprintk(VIDC_ERR,
1126 "Failed to load pf capability table: %d\n", rc);
1127
1128 rc = msm_vidc_load_freq_table(res);
1129 if (rc) {
1130 dprintk(VIDC_ERR, "Failed to load freq table: %d\n", rc);
1131 goto err_load_freq_table;
1132 }
1133
1134 rc = msm_vidc_load_dcvs_table(res);
1135 if (rc)
1136 dprintk(VIDC_WARN, "Failed to load dcvs table: %d\n", rc);
1137
1138 rc = msm_vidc_load_dcvs_limit(res);
1139 if (rc)
1140 dprintk(VIDC_WARN, "Failed to load dcvs limit: %d\n", rc);
1141
1142 rc = msm_vidc_load_imem_ab_table(res);
1143 if (rc)
1144 dprintk(VIDC_WARN, "Failed to load freq table: %d\n", rc);
1145
1146 rc = msm_vidc_load_qdss_table(res);
1147 if (rc)
1148 dprintk(VIDC_WARN, "Failed to load qdss reg table: %d\n", rc);
1149
1150 rc = msm_vidc_load_reg_table(res);
1151 if (rc) {
1152 dprintk(VIDC_ERR, "Failed to load reg table: %d\n", rc);
1153 goto err_load_reg_table;
1154 }
1155
1156 rc = msm_vidc_load_buffer_usage_table(res);
1157 if (rc) {
1158 dprintk(VIDC_ERR,
1159 "Failed to load buffer usage table: %d\n", rc);
1160 goto err_load_buffer_usage_table;
1161 }
1162
1163 rc = msm_vidc_load_regulator_table(res);
1164 if (rc) {
1165 dprintk(VIDC_ERR, "Failed to load list of regulators %d\n", rc);
1166 goto err_load_regulator_table;
1167 }
1168
1169 rc = msm_vidc_load_clock_table(res);
1170 if (rc) {
1171 dprintk(VIDC_ERR,
1172 "Failed to load clock table: %d\n", rc);
1173 goto err_load_clock_table;
1174 }
1175
1176 rc = msm_vidc_load_cycles_per_mb_table(res);
1177 if (rc) {
1178 dprintk(VIDC_ERR,
1179 "Failed to load cycles per mb table: %d\n", rc);
1180 goto err_load_cycles_per_mb_table;
1181 }
1182
1183 rc = msm_vidc_load_allowed_clocks_table(res);
1184 if (rc) {
1185 dprintk(VIDC_ERR,
1186 "Failed to load allowed clocks table: %d\n", rc);
1187 goto err_load_allowed_clocks_table;
1188 }
1189
1190 rc = of_property_read_u32(pdev->dev.of_node, "qcom,max-hw-load",
1191 &res->max_load);
1192 if (rc) {
1193 dprintk(VIDC_ERR,
1194 "Failed to determine max load supported: %d\n", rc);
1195 goto err_load_max_hw_load;
1196 }
1197
1198 rc = msm_vidc_populate_legacy_context_bank(res);
1199 if (rc) {
1200 dprintk(VIDC_ERR,
1201 "Failed to setup context banks %d\n", rc);
1202 goto err_setup_legacy_cb;
1203 }
1204
1205 res->use_non_secure_pil = of_property_read_bool(pdev->dev.of_node,
1206 "qcom,use-non-secure-pil");
1207
1208 if (res->use_non_secure_pil || !is_iommu_present(res)) {
1209 of_property_read_u32(pdev->dev.of_node, "qcom,fw-bias",
1210 &firmware_base);
1211 res->firmware_base = (phys_addr_t)firmware_base;
1212 dprintk(VIDC_DBG,
1213 "Using fw-bias : %pa", &res->firmware_base);
1214 }
1215
1216 res->sw_power_collapsible = of_property_read_bool(pdev->dev.of_node,
1217 "qcom,sw-power-collapse");
1218 dprintk(VIDC_DBG, "Power collapse supported = %s\n",
1219 res->sw_power_collapsible ? "yes" : "no");
1220
1221 res->never_unload_fw = of_property_read_bool(pdev->dev.of_node,
1222 "qcom,never-unload-fw");
1223
1224 of_property_read_u32(pdev->dev.of_node,
1225 "qcom,pm-qos-latency-us", &res->pm_qos_latency_us);
1226
1227 res->slave_side_cp = of_property_read_bool(pdev->dev.of_node,
1228 "qcom,slave-side-cp");
1229 dprintk(VIDC_DBG, "Slave side cp = %s\n",
1230 res->slave_side_cp ? "yes" : "no");
1231
1232 of_property_read_u32(pdev->dev.of_node,
1233 "qcom,max-secure-instances",
1234 &res->max_secure_inst_count);
1235 return rc;
1236
1237err_setup_legacy_cb:
1238err_load_max_hw_load:
1239 msm_vidc_free_allowed_clocks_table(res);
1240err_load_allowed_clocks_table:
1241 msm_vidc_free_cycles_per_mb_table(res);
1242err_load_cycles_per_mb_table:
1243 msm_vidc_free_clock_table(res);
1244err_load_clock_table:
1245 msm_vidc_free_regulator_table(res);
1246err_load_regulator_table:
1247 msm_vidc_free_buffer_usage_table(res);
1248err_load_buffer_usage_table:
1249 msm_vidc_free_reg_table(res);
1250err_load_reg_table:
1251 msm_vidc_free_freq_table(res);
1252err_load_freq_table:
1253 return rc;
1254}
1255
1256static int get_secure_vmid(struct context_bank_info *cb)
1257{
1258 if (!strcasecmp(cb->name, "venus_sec_bitstream"))
1259 return VMID_CP_BITSTREAM;
1260 else if (!strcasecmp(cb->name, "venus_sec_pixel"))
1261 return VMID_CP_PIXEL;
1262 else if (!strcasecmp(cb->name, "venus_sec_non_pixel"))
1263 return VMID_CP_NON_PIXEL;
1264
1265 WARN(1, "No matching secure vmid for cb name: %s\n",
1266 cb->name);
1267 return VMID_INVAL;
1268}
1269
1270static int msm_vidc_setup_context_bank(struct context_bank_info *cb,
1271 struct device *dev)
1272{
1273 int rc = 0;
1274 int secure_vmid = VMID_INVAL;
1275 struct bus_type *bus;
1276
1277 if (!dev || !cb) {
1278 dprintk(VIDC_ERR,
1279 "%s: Invalid Input params\n", __func__);
1280 return -EINVAL;
1281 }
1282 cb->dev = dev;
1283
1284 bus = cb->dev->bus;
1285 if (IS_ERR_OR_NULL(bus)) {
1286 dprintk(VIDC_ERR, "%s - failed to get bus type\n", __func__);
1287 rc = PTR_ERR(bus) ?: -ENODEV;
1288 goto remove_cb;
1289 }
1290
1291 cb->mapping = arm_iommu_create_mapping(bus, cb->addr_range.start,
1292 cb->addr_range.size);
1293 if (IS_ERR_OR_NULL(cb->mapping)) {
1294 dprintk(VIDC_ERR, "%s - failed to create mapping\n", __func__);
1295 rc = PTR_ERR(cb->mapping) ?: -ENODEV;
1296 goto remove_cb;
1297 }
1298
1299 if (cb->is_secure) {
1300 secure_vmid = get_secure_vmid(cb);
1301 rc = iommu_domain_set_attr(cb->mapping->domain,
1302 DOMAIN_ATTR_SECURE_VMID, &secure_vmid);
1303 if (rc) {
1304 dprintk(VIDC_ERR,
1305 "%s - programming secure vmid failed: %s %d\n",
1306 __func__, dev_name(dev), rc);
1307 goto release_mapping;
1308 }
1309 }
1310
1311 rc = arm_iommu_attach_device(cb->dev, cb->mapping);
1312 if (rc) {
1313 dprintk(VIDC_ERR, "%s - Couldn't arm_iommu_attach_device\n",
1314 __func__);
1315 goto release_mapping;
1316 }
1317
1318 dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev));
1319 dprintk(VIDC_DBG,
1320 "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK",
1321 cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start,
1322 cb->addr_range.size, cb->dev, cb->mapping);
1323
1324 return rc;
1325
1326release_mapping:
1327 arm_iommu_release_mapping(cb->mapping);
1328remove_cb:
1329 return rc;
1330}
1331
1332int msm_vidc_smmu_fault_handler(struct iommu_domain *domain,
1333 struct device *dev, unsigned long iova, int flags, void *token)
1334{
1335 struct msm_vidc_core *core = token;
1336 struct msm_vidc_inst *inst;
1337 struct buffer_info *temp;
1338 struct internal_buf *buf;
1339 int i = 0;
1340 bool is_decode = false;
1341 enum vidc_ports port;
1342
1343 if (!domain || !core) {
1344 dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n",
1345 __func__, domain, core);
1346 return -EINVAL;
1347 }
1348
1349 if (core->smmu_fault_handled)
1350 return -EINVAL;
1351
1352 dprintk(VIDC_ERR, "%s - faulting address: %lx\n", __func__, iova);
1353
1354 mutex_lock(&core->lock);
1355 list_for_each_entry(inst, &core->instances, list) {
1356 is_decode = inst->session_type == MSM_VIDC_DECODER;
1357 port = is_decode ? OUTPUT_PORT : CAPTURE_PORT;
1358 dprintk(VIDC_ERR,
1359 "%s session, Codec type: %s HxW: %d x %d fps: %d bitrate: %d bit-depth: %s\n",
1360 is_decode ? "Decode" : "Encode", inst->fmts[port].name,
1361 inst->prop.height[port], inst->prop.width[port],
1362 inst->prop.fps, inst->prop.bitrate,
1363 !inst->bit_depth ? "8" : "10");
1364
1365 dprintk(VIDC_ERR,
1366 "---Buffer details for inst: %pK of type: %d---\n",
1367 inst, inst->session_type);
1368 mutex_lock(&inst->registeredbufs.lock);
1369 dprintk(VIDC_ERR, "registered buffer list:\n");
1370 list_for_each_entry(temp, &inst->registeredbufs.list, list)
1371 for (i = 0; i < temp->num_planes; i++)
1372 dprintk(VIDC_ERR,
1373 "type: %d plane: %d addr: %pa size: %d\n",
1374 temp->type, i, &temp->device_addr[i],
1375 temp->size[i]);
1376
1377 mutex_unlock(&inst->registeredbufs.lock);
1378
1379 mutex_lock(&inst->scratchbufs.lock);
1380 dprintk(VIDC_ERR, "scratch buffer list:\n");
1381 list_for_each_entry(buf, &inst->scratchbufs.list, list)
1382 dprintk(VIDC_ERR, "type: %d addr: %pa size: %u\n",
1383 buf->buffer_type, &buf->handle->device_addr,
1384 buf->handle->size);
1385 mutex_unlock(&inst->scratchbufs.lock);
1386
1387 mutex_lock(&inst->persistbufs.lock);
1388 dprintk(VIDC_ERR, "persist buffer list:\n");
1389 list_for_each_entry(buf, &inst->persistbufs.list, list)
1390 dprintk(VIDC_ERR, "type: %d addr: %pa size: %u\n",
1391 buf->buffer_type, &buf->handle->device_addr,
1392 buf->handle->size);
1393 mutex_unlock(&inst->persistbufs.lock);
1394
1395 mutex_lock(&inst->outputbufs.lock);
1396 dprintk(VIDC_ERR, "dpb buffer list:\n");
1397 list_for_each_entry(buf, &inst->outputbufs.list, list)
1398 dprintk(VIDC_ERR, "type: %d addr: %pa size: %u\n",
1399 buf->buffer_type, &buf->handle->device_addr,
1400 buf->handle->size);
1401 mutex_unlock(&inst->outputbufs.lock);
1402 }
1403 core->smmu_fault_handled = true;
1404 mutex_unlock(&core->lock);
1405 /*
1406 * Return -ENOSYS to elicit the default behaviour of smmu driver.
1407 * If we return -ENOSYS, then smmu driver assumes page fault handler
1408 * is not installed and prints a list of useful debug information like
1409 * FAR, SID etc. This information is not printed if we return 0.
1410 */
1411 return -EINVAL;
1412}
1413
1414static int msm_vidc_populate_context_bank(struct device *dev,
1415 struct msm_vidc_core *core)
1416{
1417 int rc = 0;
1418 struct context_bank_info *cb = NULL;
1419 struct device_node *np = NULL;
1420
1421 if (!dev || !core) {
1422 dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__);
1423 return -EINVAL;
1424 }
1425
1426 np = dev->of_node;
1427 cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL);
1428 if (!cb) {
1429 dprintk(VIDC_ERR, "%s - Failed to allocate cb\n", __func__);
1430 return -ENOMEM;
1431 }
1432
1433 INIT_LIST_HEAD(&cb->list);
1434 list_add_tail(&cb->list, &core->resources.context_banks);
1435
1436 rc = of_property_read_string(np, "label", &cb->name);
1437 if (rc) {
1438 dprintk(VIDC_DBG,
1439 "Failed to read cb label from device tree\n");
1440 rc = 0;
1441 }
1442
1443 dprintk(VIDC_DBG, "%s: context bank has name %s\n", __func__, cb->name);
1444 rc = of_property_read_u32_array(np, "virtual-addr-pool",
1445 (u32 *)&cb->addr_range, 2);
1446 if (rc) {
1447 dprintk(VIDC_ERR,
1448 "Could not read addr pool for context bank : %s %d\n",
1449 cb->name, rc);
1450 goto err_setup_cb;
1451 }
1452
1453 cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank");
1454 dprintk(VIDC_DBG, "context bank %s : secure = %d\n",
1455 cb->name, cb->is_secure);
1456
1457 /* setup buffer type for each sub device*/
1458 rc = of_property_read_u32(np, "buffer-types", &cb->buffer_type);
1459 if (rc) {
1460 dprintk(VIDC_ERR, "failed to load buffer_type info %d\n", rc);
1461 rc = -ENOENT;
1462 goto err_setup_cb;
1463 }
1464 dprintk(VIDC_DBG,
1465 "context bank %s address start = %x address size = %x buffer_type = %x\n",
1466 cb->name, cb->addr_range.start,
1467 cb->addr_range.size, cb->buffer_type);
1468
1469 rc = msm_vidc_setup_context_bank(cb, dev);
1470 if (rc) {
1471 dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc);
1472 goto err_setup_cb;
1473 }
1474
1475 iommu_set_fault_handler(cb->mapping->domain,
1476 msm_vidc_smmu_fault_handler, (void *)core);
1477
1478 return 0;
1479
1480err_setup_cb:
1481 list_del(&cb->list);
1482 return rc;
1483}
1484
1485static int msm_vidc_populate_legacy_context_bank(
1486 struct msm_vidc_platform_resources *res)
1487{
1488 int rc = 0;
1489 struct platform_device *pdev = NULL;
1490 struct device_node *domains_parent_node = NULL;
1491 struct device_node *domains_child_node = NULL;
1492 struct device_node *ctx_node = NULL;
1493 struct context_bank_info *cb;
1494
1495 if (!res || !res->pdev) {
1496 dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__);
1497 return -EINVAL;
1498 }
1499 pdev = res->pdev;
1500
1501 domains_parent_node = of_find_node_by_name(pdev->dev.of_node,
1502 "qcom,vidc-iommu-domains");
1503 if (!domains_parent_node) {
1504 dprintk(VIDC_DBG,
1505 "%s legacy iommu domains not present\n", __func__);
1506 return 0;
1507 }
1508
1509 /* set up each context bank for legacy DT bindings*/
1510 for_each_child_of_node(domains_parent_node,
1511 domains_child_node) {
1512 cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL);
1513 if (!cb) {
1514 dprintk(VIDC_ERR,
1515 "%s - Failed to allocate cb\n", __func__);
1516 return -ENOMEM;
1517 }
1518 INIT_LIST_HEAD(&cb->list);
1519 list_add_tail(&cb->list, &res->context_banks);
1520
1521 ctx_node = of_parse_phandle(domains_child_node,
1522 "qcom,vidc-domain-phandle", 0);
1523 if (!ctx_node) {
1524 dprintk(VIDC_ERR,
1525 "%s Unable to parse pHandle\n", __func__);
1526 rc = -EBADHANDLE;
1527 goto err_setup_cb;
1528 }
1529
1530 rc = of_property_read_string(ctx_node, "label", &(cb->name));
1531 if (rc) {
1532 dprintk(VIDC_ERR,
1533 "%s Could not find label\n", __func__);
1534 goto err_setup_cb;
1535 }
1536
1537 rc = of_property_read_u32_array(ctx_node,
1538 "qcom,virtual-addr-pool", (u32 *)&cb->addr_range, 2);
1539 if (rc) {
1540 dprintk(VIDC_ERR,
1541 "%s Could not read addr pool for group : %s (%d)\n",
1542 __func__, cb->name, rc);
1543 goto err_setup_cb;
1544 }
1545
1546 cb->is_secure =
1547 of_property_read_bool(ctx_node, "qcom,secure-domain");
1548
1549 rc = of_property_read_u32(domains_child_node,
1550 "qcom,vidc-buffer-types", &cb->buffer_type);
1551 if (rc) {
1552 dprintk(VIDC_ERR,
1553 "%s Could not read buffer type (%d)\n",
1554 __func__, rc);
1555 goto err_setup_cb;
1556 }
1557
1558 cb->dev = msm_iommu_get_ctx(cb->name);
1559 if (IS_ERR_OR_NULL(cb->dev)) {
1560 dprintk(VIDC_ERR, "%s could not get device for cb %s\n",
1561 __func__, cb->name);
1562 rc = -ENOENT;
1563 goto err_setup_cb;
1564 }
1565
1566 rc = msm_vidc_setup_context_bank(cb, cb->dev);
1567 if (rc) {
1568 dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc);
1569 goto err_setup_cb;
1570 }
1571 dprintk(VIDC_DBG,
1572 "%s: context bank %s secure %d addr start = %#x addr size = %#x buffer_type = %#x\n",
1573 __func__, cb->name, cb->is_secure, cb->addr_range.start,
1574 cb->addr_range.size, cb->buffer_type);
1575 }
1576 return rc;
1577
1578err_setup_cb:
1579 list_del(&cb->list);
1580 return rc;
1581}
1582
1583int read_context_bank_resources_from_dt(struct platform_device *pdev)
1584{
1585 struct msm_vidc_core *core;
1586 int rc = 0;
1587
1588 if (!pdev) {
1589 dprintk(VIDC_ERR, "Invalid platform device\n");
1590 return -EINVAL;
1591 } else if (!pdev->dev.parent) {
1592 dprintk(VIDC_ERR, "Failed to find a parent for %s\n",
1593 dev_name(&pdev->dev));
1594 return -ENODEV;
1595 }
1596
1597 core = dev_get_drvdata(pdev->dev.parent);
1598 if (!core) {
1599 dprintk(VIDC_ERR, "Failed to find cookie in parent device %s",
1600 dev_name(pdev->dev.parent));
1601 return -EINVAL;
1602 }
1603
1604 if (of_property_read_bool(pdev->dev.of_node, "qcom,fw-context-bank")) {
1605 if (core->resources.use_non_secure_pil) {
1606 struct context_bank_info *cb;
1607
1608 cb = devm_kzalloc(&pdev->dev, sizeof(*cb), GFP_KERNEL);
1609 if (!cb) {
1610 dprintk(VIDC_ERR, "alloc venus cb failed\n");
1611 return -ENOMEM;
1612 }
1613
1614 cb->dev = &pdev->dev;
1615 rc = venus_boot_init(&core->resources, cb);
1616 if (rc) {
1617 dprintk(VIDC_ERR,
1618 "Failed to init non-secure PIL %d\n", rc);
1619 }
1620 }
1621 } else {
1622 rc = msm_vidc_populate_context_bank(&pdev->dev, core);
1623 if (rc)
1624 dprintk(VIDC_ERR, "Failed to probe context bank\n");
1625 else
1626 dprintk(VIDC_DBG, "Successfully probed context bank\n");
1627 }
1628 return rc;
1629}
1630
1631int read_bus_resources_from_dt(struct platform_device *pdev)
1632{
1633 struct msm_vidc_core *core;
1634
1635 if (!pdev) {
1636 dprintk(VIDC_ERR, "Invalid platform device\n");
1637 return -EINVAL;
1638 } else if (!pdev->dev.parent) {
1639 dprintk(VIDC_ERR, "Failed to find a parent for %s\n",
1640 dev_name(&pdev->dev));
1641 return -ENODEV;
1642 }
1643
1644 core = dev_get_drvdata(pdev->dev.parent);
1645 if (!core) {
1646 dprintk(VIDC_ERR, "Failed to find cookie in parent device %s",
1647 dev_name(pdev->dev.parent));
1648 return -EINVAL;
1649 }
1650
1651 return msm_vidc_populate_bus(&pdev->dev, &core->resources);
1652}