1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2026, Advanced Micro Devices, Inc. 4 */ 5 6 #include <drm/drm_device.h> 7 #include <drm/drm_managed.h> 8 #include <drm/drm_print.h> 9 #include <linux/bitfield.h> 10 #include <linux/iopoll.h> 11 #include <linux/slab.h> 12 13 #include "aie.h" 14 15 #define PSP_STATUS_READY BIT(31) 16 17 /* PSP commands */ 18 #define PSP_VALIDATE 1 19 #define PSP_START 2 20 #define PSP_RELEASE_TMR 3 21 #define PSP_VALIDATE_CERT 4 22 23 /* PSP special arguments */ 24 #define PSP_START_COPY_FW 1 25 26 /* PSP response error code */ 27 #define PSP_ERROR_CANCEL 0xFFFF0002 28 #define PSP_ERROR_BAD_STATE 0xFFFF0007 29 30 #define PSP_FW_ALIGN 0x10000 31 #define PSP_CFW_ALIGN 0x8000 32 #define PSP_POLL_INTERVAL 20000 /* us */ 33 #define PSP_POLL_TIMEOUT 1000000 /* us */ 34 35 #define PSP_REG(p, reg) ((p)->conf.psp_regs[reg]) 36 #define PSP_SET_CMD(psp, reg_vals, cmd, arg0, arg1, arg2) \ 37 ({ \ 38 u32 *_regs = reg_vals; \ 39 u32 _cmd = cmd; \ 40 _regs[0] = _cmd; \ 41 _regs[1] = arg0; \ 42 _regs[2] = arg1; \ 43 _regs[3] = ((arg2) | ((_cmd) << 24)) & (psp)->conf.arg2_mask; \ 44 }) 45 46 struct psp_device { 47 struct drm_device *ddev; 48 struct psp_config conf; 49 u32 fw_buf_sz; 50 u64 fw_paddr; 51 void *fw_buffer; 52 u32 certfw_buf_sz; 53 u64 certfw_paddr; 54 void *certfw_buffer; 55 }; 56 57 static int psp_exec(struct psp_device *psp, u32 *reg_vals) 58 { 59 u32 resp_code; 60 int ret, i; 61 u32 ready; 62 63 /* Check for PSP ready before any write */ 64 ret = readx_poll_timeout(readl, PSP_REG(psp, PSP_STATUS_REG), ready, 65 FIELD_GET(PSP_STATUS_READY, ready), 66 PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT); 67 if (ret) { 68 drm_err(psp->ddev, "PSP is not ready, ret 0x%x", ret); 69 return ret; 70 } 71 72 /* Write command and argument registers */ 73 for (i = 0; i < PSP_NUM_IN_REGS; i++) 74 writel(reg_vals[i], PSP_REG(psp, i)); 75 76 /* clear and set PSP INTR register to kick off */ 77 writel(0, PSP_REG(psp, PSP_INTR_REG)); 78 writel(psp->conf.notify_val, PSP_REG(psp, PSP_INTR_REG)); 79 80 /* PSP should be busy. Wait for ready, so we know task is done. */ 81 ret = readx_poll_timeout(readl, PSP_REG(psp, PSP_STATUS_REG), ready, 82 FIELD_GET(PSP_STATUS_READY, ready), 83 PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT); 84 if (ret) { 85 drm_err(psp->ddev, "PSP is not ready, ret 0x%x", ret); 86 return ret; 87 } 88 89 resp_code = readl(PSP_REG(psp, PSP_RESP_REG)); 90 if (resp_code) { 91 drm_err(psp->ddev, "fw return error 0x%x", resp_code); 92 return -EIO; 93 } 94 95 return 0; 96 } 97 98 int aie_psp_waitmode_poll(struct psp_device *psp) 99 { 100 struct amdxdna_dev *xdna = to_xdna_dev(psp->ddev); 101 u32 mode_reg; 102 int ret; 103 104 ret = readx_poll_timeout(readl, PSP_REG(psp, PSP_PWAITMODE_REG), mode_reg, 105 (mode_reg & 0x1) == 1, 106 PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT); 107 if (ret) 108 XDNA_ERR(xdna, "fw waitmode reg error, ret %d", ret); 109 110 return ret; 111 } 112 113 void aie_psp_stop(struct psp_device *psp) 114 { 115 u32 reg_vals[PSP_NUM_IN_REGS]; 116 int ret; 117 118 PSP_SET_CMD(psp, reg_vals, PSP_RELEASE_TMR, 0, 0, 0); 119 120 ret = psp_exec(psp, reg_vals); 121 if (ret) 122 drm_err(psp->ddev, "release tmr failed, ret %d", ret); 123 } 124 125 static int psp_validate_fw(struct psp_device *psp, u8 cmd, u64 paddr, u32 buf_sz) 126 { 127 u32 reg_vals[PSP_NUM_IN_REGS]; 128 int ret; 129 130 PSP_SET_CMD(psp, reg_vals, cmd, lower_32_bits(paddr), 131 upper_32_bits(paddr), buf_sz); 132 133 ret = psp_exec(psp, reg_vals); 134 if (ret) 135 drm_err(psp->ddev, "failed to validate fw, ret %d", ret); 136 137 return ret; 138 } 139 140 static int psp_start(struct psp_device *psp) 141 { 142 u32 reg_vals[PSP_NUM_IN_REGS]; 143 int ret; 144 145 PSP_SET_CMD(psp, reg_vals, PSP_START, PSP_START_COPY_FW, 0, 0); 146 147 ret = psp_exec(psp, reg_vals); 148 if (ret) 149 drm_err(psp->ddev, "failed to start fw, ret %d", ret); 150 151 return ret; 152 } 153 154 int aie_psp_start(struct psp_device *psp) 155 { 156 int ret; 157 158 ret = psp_validate_fw(psp, PSP_VALIDATE, 159 psp->fw_paddr, psp->fw_buf_sz); 160 if (ret) 161 return ret; 162 163 if (!psp->certfw_buf_sz) 164 goto psp_start; 165 166 ret = psp_validate_fw(psp, PSP_VALIDATE_CERT, 167 psp->certfw_paddr, psp->certfw_buf_sz); 168 if (ret) 169 return ret; 170 psp_start: 171 return psp_start(psp); 172 } 173 174 /* 175 * PSP requires host physical address to load firmware. 176 * Allocate a buffer, obtain its physical address, align, and copy data in. 177 */ 178 static void *psp_alloc_fw_buf(struct psp_device *psp, const void *fw_data, 179 u32 fw_size, u32 align, u32 *buf_sz, 180 u64 *paddr) 181 { 182 u32 alloc_sz; 183 void *buffer; 184 u64 offset; 185 186 *buf_sz = ALIGN(fw_size, align); 187 alloc_sz = *buf_sz + align; 188 189 buffer = drmm_kmalloc(psp->ddev, alloc_sz, GFP_KERNEL); 190 if (!buffer) 191 return NULL; 192 193 *paddr = virt_to_phys(buffer); 194 offset = ALIGN(*paddr, align) - *paddr; 195 *paddr += offset; 196 memcpy(buffer + offset, fw_data, fw_size); 197 198 return buffer; 199 } 200 201 struct psp_device *aiem_psp_create(struct drm_device *ddev, struct psp_config *conf) 202 { 203 struct psp_device *psp; 204 205 psp = drmm_kzalloc(ddev, sizeof(*psp), GFP_KERNEL); 206 if (!psp) 207 return NULL; 208 209 psp->ddev = ddev; 210 psp->fw_buffer = psp_alloc_fw_buf(psp, conf->fw_buf, conf->fw_size, 211 PSP_FW_ALIGN, &psp->fw_buf_sz, 212 &psp->fw_paddr); 213 if (!psp->fw_buffer) 214 return NULL; 215 216 if (!conf->certfw_size) { 217 drm_dbg(ddev, "no cert fw"); 218 goto done; 219 } 220 221 /* CERT firmware */ 222 psp->certfw_buffer = psp_alloc_fw_buf(psp, conf->certfw_buf, 223 conf->certfw_size, PSP_CFW_ALIGN, 224 &psp->certfw_buf_sz, 225 &psp->certfw_paddr); 226 if (!psp->certfw_buffer) { 227 drm_err(ddev, "no memory for cert fw buffer"); 228 return NULL; 229 } 230 231 done: 232 memcpy(&psp->conf, conf, sizeof(psp->conf)); 233 234 return psp; 235 } 236