Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* |
| 3 | * Copyright (C) 2025 Altera Corporation <www.altera.com> |
| 4 | * |
| 5 | */ |
| 6 | |
| 7 | #define MAX_IO96B_SUPPORTED 2 |
| 8 | #define MAX_MEM_INTERFACE_SUPPORTED 2 |
| 9 | #define NUM_CMD_RESPONSE_DATA 3 |
| 10 | #define NUM_CMD_PARAM 7 |
| 11 | |
| 12 | /* supported mailbox command type */ |
| 13 | enum iossm_mailbox_cmd_type { |
| 14 | CMD_NOP, |
| 15 | CMD_GET_SYS_INFO, |
| 16 | CMD_GET_MEM_INFO, |
| 17 | CMD_GET_MEM_CAL_INFO, |
| 18 | CMD_TRIG_CONTROLLER_OP, |
| 19 | CMD_TRIG_MEM_CAL_OP |
| 20 | }; |
| 21 | |
| 22 | /* supported mailbox command opcode */ |
| 23 | enum iossm_mailbox_cmd_opcode { |
| 24 | ECC_ENABLE_SET = 0x0101, |
| 25 | ECC_INTERRUPT_MASK = 0x0105, |
| 26 | ECC_WRITEBACK_ENABLE = 0x0106, |
| 27 | ECC_INJECT_ERROR = 0x0109, |
| 28 | ECC_SCRUB_MODE_0_START = 0x0202, |
| 29 | ECC_SCRUB_MODE_1_START = 0x0203, |
| 30 | BIST_STANDARD_MODE_START = 0x0301, |
| 31 | BIST_MEM_INIT_START = 0x0303, |
| 32 | BIST_SET_DATA_PATTERN_UPPER = 0x0305, |
| 33 | BIST_SET_DATA_PATTERN_LOWER = 0x0306, |
| 34 | TRIG_MEM_CAL = 0x000a |
| 35 | }; |
| 36 | |
| 37 | /* |
| 38 | * IOSSM mailbox required information |
| 39 | * |
| 40 | * @num_mem_interface: Number of memory interfaces instantiated |
| 41 | * @ip_type: IP type implemented on the IO96B |
| 42 | * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B |
Tingting Meng | dc6c927 | 2025-04-15 14:50:51 +0800 | [diff] [blame^] | 43 | * @memory_size[2]: Memory size for every IP instance implemented on the IO96B |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 44 | */ |
| 45 | struct io96b_mb_ctrl { |
| 46 | u32 num_mem_interface; |
| 47 | u32 ip_type[2]; |
| 48 | u32 ip_id[2]; |
Tingting Meng | dc6c927 | 2025-04-15 14:50:51 +0800 | [diff] [blame^] | 49 | phys_size_t memory_size[2]; |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 50 | }; |
| 51 | |
| 52 | /* CMD_REQ Register Definition */ |
| 53 | #define CMD_TARGET_IP_TYPE_MASK GENMASK(31, 29) |
| 54 | #define CMD_TARGET_IP_INSTANCE_ID_MASK GENMASK(28, 24) |
| 55 | #define CMD_TYPE_MASK GENMASK(23, 16) |
| 56 | #define CMD_OPCODE_MASK GENMASK(15, 0) |
| 57 | |
Tingting Meng | dc6c927 | 2025-04-15 14:50:51 +0800 | [diff] [blame^] | 58 | /* Computes the Inline ECC data region size */ |
| 59 | #define CALC_INLINE_ECC_HW_SIZE(size) (((size) * 7) / 8) |
| 60 | |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 61 | /* |
| 62 | * IOSSM mailbox request |
| 63 | * @ip_type: IP type for the specified memory interface |
| 64 | * @ip_id: IP instance ID for the specified memory interface |
| 65 | * @usr_cmd_type: User desire IOSSM mailbox command type |
| 66 | * @usr_cmd_opcode: User desire IOSSM mailbox command opcode |
| 67 | * @cmd_param_*: Parameters (if applicable) for the requested IOSSM mailbox command |
| 68 | */ |
| 69 | struct io96b_mb_req { |
| 70 | u32 ip_type; |
| 71 | u32 ip_id; |
| 72 | u32 usr_cmd_type; |
| 73 | u32 usr_cmd_opcode; |
| 74 | u32 cmd_param[NUM_CMD_PARAM]; |
| 75 | }; |
| 76 | |
| 77 | /* |
| 78 | * IOSSM mailbox response outputs |
| 79 | * |
| 80 | * @cmd_resp_status: Command Interface status |
| 81 | * @cmd_resp_data_*: More spaces for command response |
| 82 | */ |
| 83 | struct io96b_mb_resp { |
| 84 | u32 cmd_resp_status; |
| 85 | u32 cmd_resp_data[NUM_CMD_RESPONSE_DATA]; |
| 86 | }; |
| 87 | |
| 88 | /* |
| 89 | * IO96B instance specific information |
| 90 | * |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 91 | * @io96b_csr_addr: IO96B instance CSR address |
| 92 | * @cal_status: IO96B instance calibration status |
| 93 | * @mb_ctrl: IOSSM mailbox required information |
| 94 | */ |
| 95 | struct io96b_instance { |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 96 | phys_addr_t io96b_csr_addr; |
| 97 | bool cal_status; |
| 98 | struct io96b_mb_ctrl mb_ctrl; |
| 99 | }; |
| 100 | |
| 101 | /* |
| 102 | * Overall IO96B instance(s) information |
| 103 | * |
| 104 | * @num_instance: Number of instance(s) assigned to HPS |
| 105 | * @overall_cal_status: Overall calibration status for all IO96B instance(s) |
| 106 | * @ddr_type: DDR memory type |
| 107 | * @ecc_status: ECC enable status (false = disabled, true = enabled) |
Tingting Meng | dc6c927 | 2025-04-15 14:50:51 +0800 | [diff] [blame^] | 108 | * @inline_ecc: Inline ECC or Out of Band ECC (false = Out of Band ECC, true = Inline ECC) |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 109 | * @overall_size: Total DDR memory size |
| 110 | * @io96b[]: IO96B instance specific information |
| 111 | * @ckgen_lock: IO96B GEN PLL lock (false = not locked, true = locked) |
| 112 | * @num_port: Number of IO96B port. |
| 113 | * @io96b_pll: Selected IO96B PLL. Example bit 0: EMIF0 PLL A selected, |
| 114 | * bit 1: EMIF0 PLL B selected, bit 2 - EMIF1 PLL A selected, |
| 115 | * bit 3: EMIF1 PLL B selected |
| 116 | */ |
| 117 | struct io96b_info { |
| 118 | u8 num_instance; |
| 119 | bool overall_cal_status; |
| 120 | const char *ddr_type; |
| 121 | bool ecc_status; |
Tingting Meng | dc6c927 | 2025-04-15 14:50:51 +0800 | [diff] [blame^] | 122 | bool inline_ecc; |
| 123 | phys_size_t overall_size; |
Tingting Meng | a1a24f1 | 2025-02-21 21:49:41 +0800 | [diff] [blame] | 124 | struct io96b_instance io96b[MAX_IO96B_SUPPORTED]; |
| 125 | bool ckgen_lock; |
| 126 | u8 num_port; |
| 127 | u8 io96b_pll; |
| 128 | }; |
| 129 | |
| 130 | int io96b_mb_req(phys_addr_t io96b_csr_addr, struct io96b_mb_req req, |
| 131 | u32 resp_data_len, struct io96b_mb_resp *resp); |
| 132 | |
| 133 | /* Supported IOSSM mailbox function */ |
| 134 | void io96b_mb_init(struct io96b_info *io96b_ctrl); |
| 135 | int io96b_cal_status(phys_addr_t addr); |
| 136 | void init_mem_cal(struct io96b_info *io96b_ctrl); |
| 137 | int get_mem_technology(struct io96b_info *io96b_ctrl); |
| 138 | int get_mem_width_info(struct io96b_info *io96b_ctrl); |
| 139 | int ecc_enable_status(struct io96b_info *io96b_ctrl); |
| 140 | int bist_mem_init_start(struct io96b_info *io96b_ctrl); |
| 141 | bool ecc_interrupt_status(struct io96b_info *io96b_ctrl); |