1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2025 Cirrus Logic, Inc. and 3 // Cirrus Logic International Semiconductor Ltd. 4 5 /* 6 * The MIPI SDCA specification is available for public downloads at 7 * https://www.mipi.org/mipi-sdca-v1-0-download 8 */ 9 10 #include <linux/acpi.h> 11 #include <linux/device.h> 12 #include <linux/dev_printk.h> 13 #include <linux/dmi.h> 14 #include <linux/firmware.h> 15 #include <linux/module.h> 16 #include <linux/pci.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/regmap.h> 19 #include <linux/sprintf.h> 20 #include <linux/soundwire/sdw.h> 21 #include <linux/soundwire/sdw_registers.h> 22 #include <sound/sdca.h> 23 #include <sound/sdca_fdl.h> 24 #include <sound/sdca_function.h> 25 #include <sound/sdca_interrupts.h> 26 #include <sound/sdca_ump.h> 27 28 /** 29 * sdca_reset_function - send an SDCA function reset 30 * @dev: Device pointer for error messages. 31 * @function: Pointer to the SDCA Function. 32 * @regmap: Pointer to the SDCA Function regmap. 33 * 34 * Return: Zero on success or a negative error code. 35 */ 36 int sdca_reset_function(struct device *dev, struct sdca_function_data *function, 37 struct regmap *regmap) 38 { 39 unsigned int reg = SDW_SDCA_CTL(function->desc->adr, 40 SDCA_ENTITY_TYPE_ENTITY_0, 41 SDCA_CTL_ENTITY_0_FUNCTION_ACTION, 0); 42 unsigned int val, poll_us; 43 int ret; 44 45 ret = regmap_write(regmap, reg, SDCA_CTL_ENTITY_0_RESET_FUNCTION_NOW); 46 if (ret) // Allowed for function reset to not be implemented 47 return 0; 48 49 if (!function->reset_max_delay) { 50 dev_err(dev, "No reset delay specified in DisCo\n"); 51 return -EINVAL; 52 } 53 54 /* 55 * Poll up to 16 times but no more than once per ms, these are just 56 * arbitrarily selected values, so may be fine tuned in future. 57 */ 58 poll_us = umin(function->reset_max_delay >> 4, 1000); 59 60 ret = regmap_read_poll_timeout(regmap, reg, val, !val, poll_us, 61 function->reset_max_delay); 62 if (ret) { 63 dev_err(dev, "Failed waiting for function reset: %d\n", ret); 64 return ret; 65 } 66 67 return 0; 68 } 69 EXPORT_SYMBOL_NS(sdca_reset_function, "SND_SOC_SDCA"); 70 71 /** 72 * sdca_fdl_sync - wait for a function to finish FDL 73 * @dev: Device pointer for error messages. 74 * @function: Pointer to the SDCA Function. 75 * @info: Pointer to the SDCA interrupt info for this device. 76 * 77 * Return: Zero on success or a negative error code. 78 */ 79 int sdca_fdl_sync(struct device *dev, struct sdca_function_data *function, 80 struct sdca_interrupt_info *info) 81 { 82 static const int fdl_retries = 6; 83 unsigned long begin_timeout = msecs_to_jiffies(100); 84 unsigned long done_timeout = msecs_to_jiffies(4000); 85 int nfdl; 86 int i, j; 87 88 for (i = 0; i < fdl_retries; i++) { 89 nfdl = 0; 90 91 for (j = 0; j < SDCA_MAX_INTERRUPTS; j++) { 92 struct sdca_interrupt *interrupt = &info->irqs[j]; 93 struct fdl_state *fdl_state; 94 unsigned long time; 95 96 if (interrupt->function != function || 97 !interrupt->entity || !interrupt->control || 98 interrupt->entity->type != SDCA_ENTITY_TYPE_XU || 99 interrupt->control->sel != SDCA_CTL_XU_FDL_CURRENTOWNER) 100 continue; 101 102 fdl_state = interrupt->priv; 103 nfdl++; 104 105 /* 106 * Looking for timeout without any new FDL requests 107 * to imply the device has completed initial 108 * firmware setup. Alas the specification doesn't 109 * have any mechanism to detect this. 110 */ 111 time = wait_for_completion_timeout(&fdl_state->begin, 112 begin_timeout); 113 if (!time) { 114 dev_dbg(dev, "no new FDL starts\n"); 115 nfdl--; 116 continue; 117 } 118 119 time = wait_for_completion_timeout(&fdl_state->done, 120 done_timeout); 121 if (!time) { 122 dev_err(dev, "timed out waiting for FDL to complete\n"); 123 goto error; 124 } 125 } 126 127 if (!nfdl) 128 return 0; 129 } 130 131 dev_err(dev, "too many FDL requests\n"); 132 133 error: 134 for (j = 0; j < SDCA_MAX_INTERRUPTS; j++) { 135 struct sdca_interrupt *interrupt = &info->irqs[j]; 136 struct fdl_state *fdl_state; 137 138 if (interrupt->function != function || 139 !interrupt->entity || !interrupt->control || 140 interrupt->entity->type != SDCA_ENTITY_TYPE_XU || 141 interrupt->control->sel != SDCA_CTL_XU_FDL_CURRENTOWNER) 142 continue; 143 144 disable_irq(interrupt->irq); 145 146 fdl_state = interrupt->priv; 147 148 sdca_ump_cancel_timeout(&fdl_state->timeout); 149 } 150 151 return -ETIMEDOUT; 152 } 153 EXPORT_SYMBOL_NS_GPL(sdca_fdl_sync, "SND_SOC_SDCA"); 154 155 static char *fdl_get_sku_filename(struct device *dev, 156 struct sdca_fdl_file *fdl_file) 157 { 158 struct device *parent = dev; 159 const char *product_vendor; 160 const char *product_sku; 161 162 /* 163 * Try to find pci_dev manually because the card may not be ready to be 164 * used for snd_soc_card_get_pci_ssid yet 165 */ 166 while (parent) { 167 if (dev_is_pci(parent)) { 168 struct pci_dev *pci_dev = to_pci_dev(parent); 169 170 return kasprintf(GFP_KERNEL, "sdca/%x/%x/%x/%x.bin", 171 fdl_file->vendor_id, 172 pci_dev->subsystem_vendor, 173 pci_dev->subsystem_device, 174 fdl_file->file_id); 175 } else { 176 parent = parent->parent; 177 } 178 } 179 180 product_vendor = dmi_get_system_info(DMI_SYS_VENDOR); 181 if (!product_vendor || !strcmp(product_vendor, "Default string")) 182 product_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); 183 if (!product_vendor || !strcmp(product_vendor, "Default string")) 184 product_vendor = dmi_get_system_info(DMI_CHASSIS_VENDOR); 185 if (!product_vendor) 186 product_vendor = "unknown"; 187 188 product_sku = dmi_get_system_info(DMI_PRODUCT_SKU); 189 if (!product_sku || !strcmp(product_sku, "Default string")) 190 product_sku = dmi_get_system_info(DMI_PRODUCT_NAME); 191 if (!product_sku) 192 product_sku = "unknown"; 193 194 return kasprintf(GFP_KERNEL, "sdca/%x/%s/%s/%x.bin", fdl_file->vendor_id, 195 product_vendor, product_sku, fdl_file->file_id); 196 } 197 198 static int fdl_load_file(struct sdca_interrupt *interrupt, 199 struct sdca_fdl_set *set, int file_index) 200 { 201 struct device *dev = interrupt->dev; 202 struct sdca_fdl_data *fdl_data = &interrupt->function->fdl_data; 203 const struct firmware *firmware = NULL; 204 struct acpi_sw_file *swf = NULL, *tmp; 205 struct sdca_fdl_file *fdl_file; 206 char *disk_filename; 207 int ret; 208 int i; 209 210 if (!set) { 211 dev_err(dev, "request to load SWF with no set\n"); 212 return -EINVAL; 213 } 214 215 fdl_file = &set->files[file_index]; 216 217 if (fdl_data->swft) { 218 tmp = fdl_data->swft->files; 219 for (i = 0; i < fdl_data->swft->header.length; i += tmp->file_length, 220 tmp = ACPI_ADD_PTR(struct acpi_sw_file, tmp, tmp->file_length)) { 221 if (tmp->vendor_id == fdl_file->vendor_id && 222 tmp->file_id == fdl_file->file_id) { 223 dev_dbg(dev, "located SWF in ACPI: %x-%x-%x\n", 224 tmp->vendor_id, tmp->file_id, 225 tmp->file_version); 226 swf = tmp; 227 break; 228 } 229 } 230 } 231 232 disk_filename = fdl_get_sku_filename(dev, fdl_file); 233 if (!disk_filename) 234 return -ENOMEM; 235 236 dev_dbg(dev, "FDL disk filename: %s\n", disk_filename); 237 238 ret = firmware_request_nowarn(&firmware, disk_filename, dev); 239 kfree(disk_filename); 240 if (ret) { 241 disk_filename = kasprintf(GFP_KERNEL, "sdca/%x/%x.bin", 242 fdl_file->vendor_id, fdl_file->file_id); 243 if (!disk_filename) 244 return -ENOMEM; 245 246 dev_dbg(dev, "FDL disk filename: %s\n", disk_filename); 247 248 ret = firmware_request_nowarn(&firmware, disk_filename, dev); 249 kfree(disk_filename); 250 } 251 252 if (!ret) { 253 tmp = (struct acpi_sw_file *)&firmware->data[0]; 254 255 if (firmware->size < sizeof(*tmp) || 256 tmp->file_length != firmware->size) { 257 dev_err(dev, "bad disk SWF size\n"); 258 } else if (!swf || swf->file_version <= tmp->file_version) { 259 dev_dbg(dev, "using SWF from disk\n"); 260 swf = tmp; 261 } 262 } 263 264 if (!swf) { 265 dev_err(dev, "failed to locate SWF\n"); 266 return -ENOENT; 267 } 268 269 dev_info(dev, "loading SWF: %x-%x-%x\n", 270 swf->vendor_id, swf->file_id, swf->file_version); 271 272 ret = sdca_ump_write_message(dev, interrupt->device_regmap, 273 interrupt->function_regmap, 274 interrupt->function, interrupt->entity, 275 SDCA_CTL_XU_FDL_MESSAGEOFFSET, fdl_file->fdl_offset, 276 SDCA_CTL_XU_FDL_MESSAGELENGTH, swf->data, 277 swf->file_length - offsetof(struct acpi_sw_file, data)); 278 release_firmware(firmware); 279 return ret; 280 } 281 282 static struct sdca_fdl_set *fdl_get_set(struct sdca_interrupt *interrupt) 283 { 284 struct device *dev = interrupt->dev; 285 struct sdca_fdl_data *fdl_data = &interrupt->function->fdl_data; 286 struct sdca_entity *xu = interrupt->entity; 287 struct sdca_control_range *range; 288 unsigned int val; 289 int i, ret; 290 291 ret = regmap_read(interrupt->function_regmap, 292 SDW_SDCA_CTL(interrupt->function->desc->adr, xu->id, 293 SDCA_CTL_XU_FDL_SET_INDEX, 0), 294 &val); 295 if (ret < 0) { 296 dev_err(dev, "failed to read FDL set index: %d\n", ret); 297 return NULL; 298 } 299 300 range = sdca_selector_find_range(dev, xu, SDCA_CTL_XU_FDL_SET_INDEX, 301 SDCA_FDL_SET_INDEX_NCOLS, 0); 302 303 val = sdca_range_search(range, SDCA_FDL_SET_INDEX_SET_NUMBER, 304 val, SDCA_FDL_SET_INDEX_FILE_SET_ID); 305 306 for (i = 0; i < fdl_data->num_sets; i++) { 307 if (fdl_data->sets[i].id == val) 308 return &fdl_data->sets[i]; 309 } 310 311 dev_err(dev, "invalid fileset id: %d\n", val); 312 return NULL; 313 } 314 315 static void fdl_end(struct sdca_interrupt *interrupt) 316 { 317 struct fdl_state *fdl_state = interrupt->priv; 318 319 if (!fdl_state->set) 320 return; 321 322 fdl_state->set = NULL; 323 324 pm_runtime_put(interrupt->dev); 325 complete(&fdl_state->done); 326 327 dev_dbg(interrupt->dev, "completed FDL process\n"); 328 } 329 330 static void sdca_fdl_timeout_work(struct work_struct *work) 331 { 332 struct fdl_state *fdl_state = container_of(work, struct fdl_state, 333 timeout.work); 334 struct sdca_interrupt *interrupt = fdl_state->interrupt; 335 struct device *dev = interrupt->dev; 336 337 dev_err(dev, "FDL transaction timed out\n"); 338 339 guard(mutex)(&fdl_state->lock); 340 341 fdl_end(interrupt); 342 sdca_reset_function(dev, interrupt->function, interrupt->function_regmap); 343 } 344 345 static int fdl_status_process(struct sdca_interrupt *interrupt, unsigned int status) 346 { 347 struct fdl_state *fdl_state = interrupt->priv; 348 int ret; 349 350 switch (status) { 351 case SDCA_CTL_XU_FDLD_NEEDS_SET: 352 dev_dbg(interrupt->dev, "starting FDL process...\n"); 353 354 pm_runtime_get(interrupt->dev); 355 complete(&fdl_state->begin); 356 357 fdl_state->file_index = 0; 358 fdl_state->set = fdl_get_set(interrupt); 359 fallthrough; 360 case SDCA_CTL_XU_FDLD_MORE_FILES_OK: 361 ret = fdl_load_file(interrupt, fdl_state->set, fdl_state->file_index); 362 if (ret) { 363 fdl_end(interrupt); 364 return SDCA_CTL_XU_FDLH_REQ_ABORT; 365 } 366 367 return SDCA_CTL_XU_FDLH_FILE_AVAILABLE; 368 case SDCA_CTL_XU_FDLD_FILE_OK: 369 if (!fdl_state->set) { 370 fdl_end(interrupt); 371 return SDCA_CTL_XU_FDLH_REQ_ABORT; 372 } 373 374 fdl_state->file_index++; 375 376 if (fdl_state->file_index < fdl_state->set->num_files) 377 return SDCA_CTL_XU_FDLH_MORE_FILES; 378 fallthrough; 379 case SDCA_CTL_XU_FDLD_COMPLETE: 380 fdl_end(interrupt); 381 return SDCA_CTL_XU_FDLH_COMPLETE; 382 default: 383 fdl_end(interrupt); 384 385 if (status & SDCA_CTL_XU_FDLD_REQ_RESET) 386 return SDCA_CTL_XU_FDLH_RESET_ACK; 387 else if (status & SDCA_CTL_XU_FDLD_REQ_ABORT) 388 return SDCA_CTL_XU_FDLH_COMPLETE; 389 390 dev_err(interrupt->dev, "invalid FDL status: %x\n", status); 391 return -EINVAL; 392 } 393 } 394 395 /** 396 * sdca_fdl_process - Process the FDL state machine 397 * @interrupt: SDCA interrupt structure 398 * 399 * Based on section 13.2.5 Flow Diagram for File Download, Host side. 400 * 401 * Return: Zero on success or a negative error code. 402 */ 403 int sdca_fdl_process(struct sdca_interrupt *interrupt) 404 { 405 struct device *dev = interrupt->dev; 406 struct sdca_entity_xu *xu = &interrupt->entity->xu; 407 struct fdl_state *fdl_state = interrupt->priv; 408 unsigned int reg, status; 409 int response, ret; 410 411 ret = sdca_ump_get_owner_host(dev, interrupt->function_regmap, 412 interrupt->function, interrupt->entity, 413 interrupt->control); 414 if (ret) 415 goto reset_function; 416 417 sdca_ump_cancel_timeout(&fdl_state->timeout); 418 419 scoped_guard(mutex, &fdl_state->lock) { 420 reg = SDW_SDCA_CTL(interrupt->function->desc->adr, 421 interrupt->entity->id, SDCA_CTL_XU_FDL_STATUS, 0); 422 ret = regmap_read(interrupt->function_regmap, reg, &status); 423 if (ret < 0) { 424 dev_err(dev, "failed to read FDL status: %d\n", ret); 425 return ret; 426 } 427 428 dev_dbg(dev, "FDL status: %#x\n", status); 429 430 ret = fdl_status_process(interrupt, status); 431 if (ret < 0) 432 goto reset_function; 433 434 response = ret; 435 436 dev_dbg(dev, "FDL response: %#x\n", response); 437 438 ret = regmap_write(interrupt->function_regmap, reg, 439 response | (status & ~SDCA_CTL_XU_FDLH_MASK)); 440 if (ret < 0) { 441 dev_err(dev, "failed to set FDL status signal: %d\n", ret); 442 return ret; 443 } 444 445 ret = sdca_ump_set_owner_device(dev, interrupt->function_regmap, 446 interrupt->function, 447 interrupt->entity, 448 interrupt->control); 449 if (ret) 450 return ret; 451 452 switch (response) { 453 case SDCA_CTL_XU_FDLH_RESET_ACK: 454 dev_dbg(dev, "FDL request reset\n"); 455 456 switch (xu->reset_mechanism) { 457 default: 458 dev_warn(dev, "Requested reset mechanism not implemented\n"); 459 fallthrough; 460 case SDCA_XU_RESET_FUNCTION: 461 goto reset_function; 462 } 463 case SDCA_CTL_XU_FDLH_COMPLETE: 464 if (status & SDCA_CTL_XU_FDLD_REQ_ABORT || 465 status == SDCA_CTL_XU_FDLD_COMPLETE) 466 return 0; 467 fallthrough; 468 default: 469 sdca_ump_schedule_timeout(&fdl_state->timeout, xu->max_delay); 470 return 0; 471 } 472 } 473 474 reset_function: 475 sdca_reset_function(dev, interrupt->function, interrupt->function_regmap); 476 477 return ret; 478 } 479 EXPORT_SYMBOL_NS_GPL(sdca_fdl_process, "SND_SOC_SDCA"); 480 481 /** 482 * sdca_fdl_alloc_state - allocate state for an FDL interrupt 483 * @interrupt: SDCA interrupt structure. 484 * 485 * Return: Zero on success or a negative error code. 486 */ 487 int sdca_fdl_alloc_state(struct sdca_interrupt *interrupt) 488 { 489 struct device *dev = interrupt->dev; 490 struct fdl_state *fdl_state; 491 492 fdl_state = devm_kzalloc(dev, sizeof(*fdl_state), GFP_KERNEL); 493 if (!fdl_state) 494 return -ENOMEM; 495 496 INIT_DELAYED_WORK(&fdl_state->timeout, sdca_fdl_timeout_work); 497 init_completion(&fdl_state->begin); 498 init_completion(&fdl_state->done); 499 mutex_init(&fdl_state->lock); 500 fdl_state->interrupt = interrupt; 501 502 interrupt->priv = fdl_state; 503 504 return 0; 505 } 506 EXPORT_SYMBOL_NS_GPL(sdca_fdl_alloc_state, "SND_SOC_SDCA"); 507