1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 /* **** Includes **** */
22 #include <string.h>
23 #include <stdint.h>
24 #include "mxc_errors.h"
25 #include "mxc_assert.h"
26 #include "hpb_reva.h"
27 #include "emcc.h"
28 #include "mxc_sys.h"
29 
30 /* **** Definitions **** */
31 
32 /* **** Globals **** */
33 
34 /* **** Functions **** */
35 
36 /* ************************************************************************** */
MXC_HPB_RevA_ConfigMem(mxc_hpb_reva_regs_t * hpb,mxc_hpb_mem_config_t * mem,unsigned index)37 static void MXC_HPB_RevA_ConfigMem(mxc_hpb_reva_regs_t *hpb, mxc_hpb_mem_config_t *mem,
38                                    unsigned index)
39 {
40     int i;
41 
42     // Set the base address
43     hpb->membaddr[index] = mem->base_addr;
44 
45     // Set the device type and fixed latency mode (Xccela only)
46     hpb->memctrl[index] = 0x3 | (mem->device_type << MXC_F_HPB_REVA_MEMCTRL_DEVTYPE_POS) |
47                           ((!!(mem->fixed_latency)) << MXC_F_HPB_REVA_MEMCTRL_RDLAT_EN_POS);
48 
49     // Setup memory timings
50     hpb->memtim[index] = (mem->read_cs_high << MXC_F_HPB_REVA_MEMTIM_RDCSHI_POS) |
51                          (mem->write_cs_high << MXC_F_HPB_REVA_MEMTIM_WRCSHI_POS) |
52                          (mem->read_cs_setup << MXC_F_HPB_REVA_MEMTIM_RDCSST_POS) |
53                          (mem->write_cs_setup << MXC_F_HPB_REVA_MEMTIM_WRCSST_POS) |
54                          (mem->read_cs_hold << MXC_F_HPB_REVA_MEMTIM_RDCSHD_POS) |
55                          (mem->write_cs_hold << MXC_F_HPB_REVA_MEMTIM_WRCSHD_POS) |
56                          (mem->latency_cycle << MXC_F_HPB_REVA_MEMTIM_LAT_POS);
57 
58     // Send configuration commands
59     for (i = 0; i < mem->cfg_reg_val_len; i++) {
60         if (mem->device_type == (mxc_hpb_device_t)MXC_HPB_REVA_DEV_XCCELA_PSRAM) {
61             MXC_HPB_RegWrite8(&(mem->cfg_reg_val[i]), mem->base_addr, index);
62         } else {
63             MXC_HPB_RegWrite16(&(mem->cfg_reg_val[i]), mem->base_addr, index);
64         }
65     }
66 }
67 
68 /* ************************************************************************** */
MXC_HPB_RevA_RegRead8(mxc_hpb_reva_regs_t * hpb,mxc_hpb_cfg_reg_val_t * cfg_reg_val,uint32_t base_addr,unsigned int index)69 void MXC_HPB_RevA_RegRead8(mxc_hpb_reva_regs_t *hpb, mxc_hpb_cfg_reg_val_t *cfg_reg_val,
70                            uint32_t base_addr, unsigned int index)
71 {
72     if (!hpb || !cfg_reg_val || index > 1) {
73         return;
74     }
75 
76     MXC_EMCC_Disable();
77     hpb->memctrl[index] |= MXC_F_HPB_REVA_MEMCTRL_CRT;
78     cfg_reg_val->val = *((volatile unsigned char *)(base_addr + cfg_reg_val->addr));
79     hpb->memctrl[index] &= ~(MXC_F_HPB_REVA_MEMCTRL_CRT);
80     MXC_EMCC_Enable();
81 }
82 
83 /* ************************************************************************** */
MXC_HPB_RevA_RegWrite8(mxc_hpb_reva_regs_t * hpb,mxc_hpb_cfg_reg_val_t * cfg_reg_val,uint32_t base_addr,unsigned int index)84 void MXC_HPB_RevA_RegWrite8(mxc_hpb_reva_regs_t *hpb, mxc_hpb_cfg_reg_val_t *cfg_reg_val,
85                             uint32_t base_addr, unsigned int index)
86 {
87     if (!hpb || !cfg_reg_val || index > 1) {
88         return;
89     }
90 
91     MXC_EMCC_Disable();
92     hpb->memctrl[index] |= MXC_F_HPB_REVA_MEMCTRL_CRT;
93     *((volatile unsigned char *)(base_addr + cfg_reg_val->addr)) = cfg_reg_val->val;
94     hpb->memctrl[index] &= ~(MXC_F_HPB_REVA_MEMCTRL_CRT);
95     MXC_EMCC_Enable();
96 }
97 
98 /* ************************************************************************** */
MXC_HPB_RevA_RegRead16(mxc_hpb_reva_regs_t * hpb,mxc_hpb_cfg_reg_val_t * cfg_reg_val,uint32_t base_addr,unsigned int index)99 void MXC_HPB_RevA_RegRead16(mxc_hpb_reva_regs_t *hpb, mxc_hpb_cfg_reg_val_t *cfg_reg_val,
100                             uint32_t base_addr, unsigned int index)
101 {
102     if (!hpb || !cfg_reg_val || index > 1) {
103         return;
104     }
105 
106     MXC_EMCC_Disable();
107     hpb->memctrl[index] |= MXC_F_HPB_REVA_MEMCTRL_CRT;
108     cfg_reg_val->val = *((volatile uint16_t *)(base_addr + cfg_reg_val->addr));
109     hpb->memctrl[index] &= ~(MXC_F_HPB_REVA_MEMCTRL_CRT);
110     MXC_EMCC_Enable();
111 }
112 
113 /* ************************************************************************** */
MXC_HPB_RevA_RegWrite16(mxc_hpb_reva_regs_t * hpb,mxc_hpb_cfg_reg_val_t * cfg_reg_val,uint32_t base_addr,unsigned int index)114 void MXC_HPB_RevA_RegWrite16(mxc_hpb_reva_regs_t *hpb, mxc_hpb_cfg_reg_val_t *cfg_reg_val,
115                              uint32_t base_addr, unsigned int index)
116 {
117     if (!hpb || !cfg_reg_val || index > 1) {
118         return;
119     }
120 
121     MXC_EMCC_Disable();
122     hpb->memctrl[index] |= MXC_F_HPB_REVA_MEMCTRL_CRT;
123     *((volatile uint16_t *)(base_addr + cfg_reg_val->addr)) = cfg_reg_val->val;
124     hpb->memctrl[index] &= ~(MXC_F_HPB_REVA_MEMCTRL_CRT);
125     MXC_EMCC_Enable();
126 }
127 
128 /* ************************************************************************** */
MXC_HPB_RevA_Init(mxc_hpb_reva_regs_t * hpb,mxc_hpb_mem_config_t * mem0,mxc_hpb_mem_config_t * mem1)129 int MXC_HPB_RevA_Init(mxc_hpb_reva_regs_t *hpb, mxc_hpb_mem_config_t *mem0,
130                       mxc_hpb_mem_config_t *mem1)
131 {
132     if (mem0) {
133         MXC_HPB_RevA_ConfigMem(hpb, mem0, 0);
134     }
135     if (mem1) {
136         MXC_HPB_RevA_ConfigMem(hpb, mem1, 1);
137     }
138 
139     return E_NO_ERROR;
140 }
141 
142 /* ************************************************************************** */
MXC_HPB_RevA_GetStatus(mxc_hpb_reva_regs_t * hpb)143 uint32_t MXC_HPB_RevA_GetStatus(mxc_hpb_reva_regs_t *hpb)
144 {
145     return hpb->stat;
146 }
147 
148 /* ************************************************************************** */
MXC_HPB_RevA_EnableInt(mxc_hpb_reva_regs_t * hpb,unsigned polarity)149 void MXC_HPB_RevA_EnableInt(mxc_hpb_reva_regs_t *hpb, unsigned polarity)
150 {
151     if (polarity) {
152         hpb->inten |= MXC_F_HPB_REVA_INTEN_ERR;
153     } else {
154         hpb->inten &= ~(MXC_F_HPB_REVA_INTEN_ERR);
155     }
156 }
157 
158 /* ************************************************************************** */
MXC_HPB_RevA_GetFlag(mxc_hpb_reva_regs_t * hpb)159 unsigned MXC_HPB_RevA_GetFlag(mxc_hpb_reva_regs_t *hpb)
160 {
161     return hpb->intfl;
162 }
163