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