1 /*
2  * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #include "ni_tower_rse_drv.h"
8 
9 #include <stddef.h>
10 
ni_tower_program_psam_table(const struct ni_tower_dev * dev,const struct ni_tower_psam_cfgs psam_table[],const uint32_t psam_table_count)11 enum ni_tower_err ni_tower_program_psam_table(
12     const struct ni_tower_dev *dev,
13     const struct ni_tower_psam_cfgs psam_table[],
14     const uint32_t psam_table_count)
15 {
16     enum ni_tower_err err;
17     struct ni_tower_psam_dev psam_dev = {0};
18     uint32_t p_idx, r_idx;
19 
20     if (dev == NULL || dev->periphbase == (uintptr_t)NULL) {
21         return NI_TOWER_ERR_INVALID_ARG;
22     }
23 
24     if (psam_table_count != 0 && psam_table == NULL) {
25         return NI_TOWER_ERR_INVALID_ARG;
26     }
27 
28     for (p_idx = 0; p_idx < psam_table_count; ++p_idx) {
29         err = ni_tower_psam_dev_init(
30             dev, psam_table[p_idx].component,
31             psam_table[p_idx].add_chip_addr_offset ? dev->chip_addr_offset : 0,
32             &psam_dev);
33         if (err != NI_TOWER_SUCCESS) {
34             return err;
35         }
36 
37         /* Set region fields */
38         for (r_idx = 0; r_idx < psam_table[p_idx].nh_region_count; ++r_idx) {
39             err = ni_tower_psam_configure_next_available_nhregion(
40                 &psam_dev, &psam_table[p_idx].regions[r_idx]);
41             if (err != NI_TOWER_SUCCESS) {
42                 return err;
43             }
44         }
45 
46         /* Enable the PSAM region */
47         err = ni_tower_psam_enable(&psam_dev);
48         if (err != NI_TOWER_SUCCESS) {
49             return err;
50         }
51     }
52 
53     return NI_TOWER_SUCCESS;
54 }
55 
ni_tower_program_apu_table(const struct ni_tower_dev * dev,const struct ni_tower_apu_cfgs apu_table[],const uint32_t apu_table_count)56 enum ni_tower_err ni_tower_program_apu_table(
57     const struct ni_tower_dev *dev,
58     const struct ni_tower_apu_cfgs apu_table[],
59     const uint32_t apu_table_count)
60 {
61     enum ni_tower_err err;
62     struct ni_tower_apu_dev apu_dev = {0};
63     uint32_t a_idx, r_idx;
64 
65     if (dev == NULL || dev->periphbase == (uintptr_t)NULL) {
66         return NI_TOWER_ERR_INVALID_ARG;
67     }
68 
69     if (apu_table_count != 0 && apu_table == NULL) {
70         return NI_TOWER_ERR_INVALID_ARG;
71     }
72 
73     for (a_idx = 0; a_idx < apu_table_count; ++a_idx) {
74         err = ni_tower_apu_dev_init(
75             dev, apu_table[a_idx].component,
76             apu_table[a_idx].add_chip_addr_offset ? dev->chip_addr_offset : 0,
77             &apu_dev);
78         if (err != NI_TOWER_SUCCESS) {
79             return err;
80         }
81 
82         /* Set region fields */
83         for (r_idx = 0; r_idx < apu_table[a_idx].region_count; ++r_idx) {
84             err = ni_tower_apu_configure_next_available_region(
85                 &apu_dev, &apu_table[a_idx].regions[r_idx]);
86             if (err != NI_TOWER_SUCCESS) {
87                 return err;
88             }
89         }
90 
91         err = ni_tower_apu_sync_err_enable(&apu_dev);
92         if (err != NI_TOWER_SUCCESS) {
93             return err;
94         }
95 
96         err = ni_tower_apu_enable(&apu_dev);
97         if (err != NI_TOWER_SUCCESS) {
98             return err;
99         }
100     }
101 
102     return NI_TOWER_SUCCESS;
103 }
104