1 /* 2 * Copyright (c) 2024-2025, Altera Corporation. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef AGILEX5_IOSSM_MAILBOX_H 8 #define AGILEX5_IOSSM_MAILBOX_H 9 10 #include <stdbool.h> 11 #include <stdint.h> 12 #include <stdlib.h> 13 14 #include "lib/mmio.h" 15 #include "agilex5_ddr.h" 16 17 #define __bf_shf(x) (__builtin_ffsll(x) - 1U) 18 #define FIELD_GET(_mask, _reg) \ 19 ({ \ 20 (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ 21 }) 22 23 #define FIELD_PREP(_mask, _val) \ 24 ({ \ 25 ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ 26 }) 27 28 #define IOSSM_TIMEOUT_MS 120000U 29 #define TIMEOUT_5000MS 5000 30 #define TIMEOUT TIMEOUT_5000MS 31 #define IOSSM_STATUS_CAL_SUCCESS BIT(0) 32 #define IOSSM_STATUS_CAL_FAIL BIT(1) 33 #define IOSSM_STATUS_CAL_BUSY BIT(2) 34 #define IOSSM_STATUS_COMMAND_RESPONSE_READY 1 35 #define IOSSM_CMD_RESPONSE_STATUS_OFFSET 0x45C 36 #define IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x458 37 #define IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x454 38 #define IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x450 39 #define IOSSM_CMD_REQ_OFFSET 0x43C 40 #define IOSSM_CMD_PARAM_0_OFFSET 0x438 41 #define IOSSM_CMD_PARAM_1_OFFSET 0x434 42 #define IOSSM_CMD_PARAM_2_OFFSET 0x430 43 #define IOSSM_CMD_PARAM_3_OFFSET 0x42C 44 #define IOSSM_CMD_PARAM_4_OFFSET 0x428 45 #define IOSSM_CMD_PARAM_5_OFFSET 0x424 46 #define IOSSM_CMD_PARAM_6_OFFSET 0x420 47 #define IOSSM_STATUS_OFFSET 0x400 48 #define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK GENMASK(31, 16) 49 #define IOSSM_CMD_RESPONSE_DATA_SHORT(data) (((data) & \ 50 IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16) 51 #define MAX_IO96B_SUPPORTED 2 52 #define MAX_MEM_INTERFACES_SUPPORTED 2 53 #define SZ_8 0x00000008 54 #define GET_INLINE_ECC_HW_DDR_SIZE(size) (((size) * 7) / 8) 55 56 #define IOSSM_MEM_INTF_INFO_0_OFFSET 0x200 57 #define IOSSM_MEM_INTF_INFO_1_OFFSET 0x280 58 #define INTF_IP_TYPE_MASK GENMASK(31, 29) 59 #define INTF_INSTANCE_ID_MASK GENMASK(28, 24) 60 61 #define IOSSM_ECC_ENABLE_INTF0_OFFSET 0x240 62 #define IOSSM_ECC_ENABLE_INTF1_OFFSET 0x2C0 63 #define INTF_ECC_ENABLE_TYPE_MASK GENMASK(1, 0) 64 #define INTF_ECC_TYPE_MASK BIT(8) 65 66 #define MAX_MEM_INTERFACE_SUPPORTED 2 67 #define IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET 0x234 68 #define IOSSM_MEM_TOTAL_CAPACITY_INTF1_OFFSET 0x2B4 69 70 /* offset info of MEM_TOTAL_CAPACITY_INTF */ 71 #define INTF_CAPACITY_GBITS_MASK GENMASK(7, 0) 72 73 /* offset info of ECC_ENABLE_INTF */ 74 #define INTF_BIST_STATUS_MASK BIT(0) 75 76 #define IOSSM_MEM_INIT_STATUS_INTF0_OFFSET 0x260 77 #define IOSSM_MEM_INIT_STATUS_INTF1_OFFSET 0x2E0 78 79 /* ECC error status related register offsets/commands. */ 80 #define IOSSM_ECC_ERR_STATUS_OFFSET 0x300 81 #define IOSSM_ECC_ERR_DATA_START_OFFSET 0x310 82 #define IOSSM_ECC_CLEAR_ERR_BUFFER 0x0110 83 84 /* Offset info of ECC_ERR_STATUS */ 85 #define ECC_ERR_COUNTER_MASK GENMASK(15, 0) 86 #define ECC_ERR_OVERFLOW_MASK GENMASK(31, 16) 87 88 /* Offset info of ECC_ERR_DATA */ 89 #define ECC_ERR_IP_TYPE_MASK GENMASK(24, 22) 90 #define ECC_ERR_INSTANCE_ID_MASK GENMASK(21, 17) 91 #define ECC_ERR_SOURCE_ID_MASK GENMASK(16, 10) 92 #define ECC_ERR_TYPE_MASK GENMASK(9, 6) 93 #define ECC_ERR_ADDR_UPPER_MASK GENMASK(5, 0) 94 #define ECC_ERR_ADDR_LOWER_MASK GENMASK(31, 0) 95 96 #define MAX_ECC_ERR_COUNT 16U 97 98 #define IOSSM_CONTROLLER_TRIGGER_OFFSET 0x300 99 100 #define BIST_START_ADDR_SPACE_MASK GENMASK(5, 0) 101 #define BIST_START_ADDR_LOW_MASK GENMASK(31, 0) 102 #define BIST_START_ADDR_HIGH_MASK GENMASK(37, 32) 103 104 /* supported mailbox command type */ 105 enum iossm_mailbox_cmd_type { 106 CMD_NOP, 107 CMD_GET_SYS_INFO, 108 CMD_GET_MEM_INFO, 109 CMD_GET_MEM_CAL_INFO, 110 CMD_TRIG_CONTROLLER_OP, 111 CMD_TRIG_MEM_CAL_OP 112 }; 113 114 /* ECC error types */ 115 enum ecc_error_type { 116 SINGLE_BIT_ERROR = 0, /* 0b0000 */ 117 MULTIPLE_SINGLE_BIT_ERRORS = 1, /* 0b0001 */ 118 DOUBLE_BIT_ERROR = 2, /* 0b0010 */ 119 MULTIPLE_DOUBLE_BIT_ERRORS = 3, /* 0b0011 */ 120 SINGLE_BIT_ERROR_SCRUBBING = 8, /* 0b1000 */ 121 WRITE_LINK_SINGLE_BIT_ERROR = 9, /* 0b1001 */ 122 WRITE_LINK_DOUBLE_BIT_ERROR = 10, /* 0b1010 */ 123 READ_LINK_SINGLE_BIT_ERROR = 11, /* 0b1011 */ 124 READ_LINK_DOUBLE_BIT_ERROR = 12, /* 0b1100 */ 125 READ_MODIFY_WRITE_DOUBLE_BIT_ERROR = 13 /* 0b1101 */ 126 }; 127 128 /* supported mailbox command opcode */ 129 enum iossm_mailbox_cmd_opcode { 130 GET_MEM_INTF_INFO = 0x0001, 131 GET_MEM_TECHNOLOGY, 132 GET_MEMCLK_FREQ_KHZ, 133 GET_MEM_WIDTH_INFO, 134 ECC_ENABLE_SET = 0x0101, 135 ECC_ENABLE_STATUS, 136 ECC_INTERRUPT_STATUS, 137 ECC_INTERRUPT_ACK, 138 ECC_INTERRUPT_MASK, 139 ECC_WRITEBACK_ENABLE, 140 ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201, 141 ECC_SCRUB_MODE_0_START, 142 ECC_SCRUB_MODE_1_START, 143 BIST_STANDARD_MODE_START = 0x0301, 144 BIST_RESULTS_STATUS, 145 BIST_MEM_INIT_START, 146 BIST_MEM_INIT_STATUS, 147 BIST_SET_DATA_PATTERN_UPPER, 148 BIST_SET_DATA_PATTERN_LOWER, 149 TRIG_MEM_CAL = 0x000a, 150 GET_MEM_CAL_STATUS 151 }; 152 153 /* 154 * IOSSM mailbox required information 155 * 156 * @num_mem_interface: Number of memory interfaces instantiated 157 * @ip_type: IP type implemented on the IO96B 158 * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B 159 * @memory_size[2]: Memory size for every IP instance implemented on the IO96B 160 */ 161 struct io96b_mb_ctrl { 162 uint32_t num_mem_interface; 163 uint32_t ip_type[2]; 164 uint32_t ip_instance_id[2]; 165 phys_size_t memory_size[2]; 166 }; 167 168 /* 169 * IOSSM mailbox response outputs 170 * 171 * @cmd_resp_status: Command Interface status 172 * @cmd_resp_data_*: More spaces for command response 173 */ 174 struct io96b_mb_resp { 175 uint32_t cmd_resp_status; 176 uint32_t cmd_resp_data_0; 177 uint32_t cmd_resp_data_1; 178 uint32_t cmd_resp_data_2; 179 }; 180 181 /* 182 * IO96B instance specific information 183 * 184 * @io96b_csr_addr: IO96B instance CSR address 185 * @cal_status: IO96B instance calibration status 186 * @mb_ctrl: IOSSM mailbox required information 187 */ 188 struct io96b_instance { 189 phys_addr_t io96b_csr_addr; 190 bool cal_status; 191 struct io96b_mb_ctrl mb_ctrl; 192 }; 193 194 /* 195 * Overall IO96B instance(s) information 196 * 197 * @num_instance: Number of instance(s) assigned to HPS 198 * @overall_cal_status: Overall calibration status for all IO96B instance(s) 199 * @ddr_type: DDR memory type 200 * @ecc_status: ECC enable status (false = disabled, true = enabled) 201 * @overall_size: Total DDR memory size 202 * @io96b_0: IO96B 0 instance specific information 203 * @io96b_1: IO96B 1 instance specific information 204 */ 205 struct io96b_info { 206 uint8_t num_instance; 207 bool overall_cal_status; 208 const char *ddr_type; 209 bool ecc_status; 210 bool is_inline_ecc; 211 phys_size_t overall_size; 212 struct io96b_instance io96b_0; 213 struct io96b_instance io96b_1; 214 }; 215 216 int io96b_mb_req(phys_addr_t io96b_csr_addr, uint32_t ip_type, uint32_t instance_id, 217 uint32_t usr_cmd_type, uint32_t usr_cmd_opcode, uint32_t cmd_param_0, 218 uint32_t cmd_param_1, uint32_t cmd_param_2, uint32_t cmd_param_3, 219 uint32_t cmd_param_4, uint32_t cmd_param_5, uint32_t cmd_param_6, 220 uint32_t resp_data_len, struct io96b_mb_resp *resp); 221 222 /* Supported IOSSM mailbox function */ 223 void io96b_mb_init(struct io96b_info *io96b_ctrl); 224 int io96b_cal_status(phys_addr_t addr); 225 void init_mem_cal(struct io96b_info *io96b_ctrl); 226 int trig_mem_cal(struct io96b_info *io96b_ctrl); 227 int get_mem_technology(struct io96b_info *io96b_ctrl); 228 int get_mem_width_info(struct io96b_info *io96b_ctrl); 229 int ecc_enable_status(struct io96b_info *io96b_ctrl); 230 int bist_mem_init_start(struct io96b_info *io96b_ctrl); 231 bool get_ecc_dbe_status(struct io96b_info *io96b_ctrl); 232 233 #endif /* AGILEX5_IOSSM_MAILBOX_H */ 234