1 /* $NetBSD: qcompas.c,v 1.2 2026/02/03 08:45:53 skrll Exp $ */ 2 /* $OpenBSD: qcpas.c,v 1.8 2024/11/08 21:13:34 landry Exp $ */ 3 /* 4 * Copyright (c) 2023 Patrick Wildt <patrick (at) blueri.se> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/systm.h> 21 #include <sys/device.h> 22 #include <sys/kmem.h> 23 #include <sys/mutex.h> 24 #include <sys/condvar.h> 25 #include <sys/callout.h> 26 #include <sys/exec_elf.h> 27 28 #include <uvm/uvm_extern.h> 29 30 #include <dev/firmload.h> 31 #include <dev/sysmon/sysmonvar.h> 32 #include <dev/sysmon/sysmon_taskq.h> 33 34 #include <dev/acpi/acpivar.h> 35 #include <dev/acpi/acpi_intr.h> 36 #include <dev/acpi/qcomipcc.h> 37 #include <dev/acpi/qcompep.h> 38 #include <dev/acpi/qcomscm.h> 39 #include <dev/acpi/qcomsmem.h> 40 #include <dev/acpi/qcomsmptp.h> 41 42 #define DRIVER_NAME "qcompas" 43 44 #define MDT_TYPE_MASK (7 << 24) 45 #define MDT_TYPE_HASH (2 << 24) 46 #define MDT_RELOCATABLE (1 << 27) 47 48 extern struct arm32_bus_dma_tag arm_generic_dma_tag; 49 50 enum qcpas_batt_sensor { 51 /* Battery sensors (must be first) */ 52 QCPAS_DVOLTAGE, 53 QCPAS_VOLTAGE, 54 QCPAS_DCAPACITY, 55 QCPAS_LFCCAPACITY, 56 QCPAS_CAPACITY, 57 QCPAS_CHARGERATE, 58 QCPAS_DISCHARGERATE, 59 QCPAS_CHARGING, 60 QCPAS_CHARGE_STATE, 61 QCPAS_DCYCLES, 62 QCPAS_TEMPERATURE, 63 /* AC adapter sensors */ 64 QCPAS_ACADAPTER, 65 /* Total number of sensors */ 66 QCPAS_NUM_SENSORS 67 }; 68 69 struct qcpas_dmamem { 70 bus_dmamap_t tdm_map; 71 bus_dma_segment_t tdm_seg; 72 size_t tdm_size; 73 void *tdm_kva; 74 }; 75 #define QCPAS_DMA_MAP(_tdm) ((_tdm)->tdm_map) 76 #define QCPAS_DMA_LEN(_tdm) ((_tdm)->tdm_size) 77 #define QCPAS_DMA_DVA(_tdm) ((_tdm)->tdm_map->dm_segs[0].ds_addr) 78 #define QCPAS_DMA_KVA(_tdm) ((_tdm)->tdm_kva) 79 80 struct qcpas_softc { 81 device_t sc_dev; 82 bus_dma_tag_t sc_dmat; 83 84 char *sc_sub; 85 86 void *sc_ih[5]; 87 88 kmutex_t sc_ready_lock; 89 kcondvar_t sc_ready_cv; 90 bool sc_ready; 91 92 paddr_t sc_mem_phys[2]; 93 size_t sc_mem_size[2]; 94 uint8_t *sc_mem_region[2]; 95 vaddr_t sc_mem_reloc[2]; 96 97 const char *sc_fwname; 98 const char *sc_dtb_fwname; 99 uint32_t sc_pas_id; 100 uint32_t sc_dtb_pas_id; 101 uint32_t sc_lite_pas_id; 102 const char *sc_load_state; 103 uint32_t sc_glink_remote_pid; 104 uint32_t sc_crash_reason; 105 106 struct qcpas_dmamem *sc_metadata[2]; 107 108 /* GLINK */ 109 volatile uint32_t *sc_tx_tail; 110 volatile uint32_t *sc_tx_head; 111 volatile uint32_t *sc_rx_tail; 112 volatile uint32_t *sc_rx_head; 113 114 uint32_t sc_tx_off; 115 uint32_t sc_rx_off; 116 117 uint8_t *sc_tx_fifo; 118 int sc_tx_fifolen; 119 uint8_t *sc_rx_fifo; 120 int sc_rx_fifolen; 121 void *sc_glink_ih; 122 123 void *sc_ipcc; 124 125 uint32_t sc_glink_max_channel; 126 TAILQ_HEAD(,qcpas_glink_channel) sc_glink_channels; 127 128 uint32_t sc_warning_capacity; 129 uint32_t sc_low_capacity; 130 uint32_t sc_power_state; 131 struct sysmon_envsys *sc_sme; 132 envsys_data_t sc_sens[QCPAS_NUM_SENSORS]; 133 struct sysmon_envsys *sc_sme_acadapter; 134 struct sysmon_pswitch sc_smpsw_acadapter; 135 callout_t sc_rtr_refresh; 136 }; 137 138 static int qcpas_match(device_t, cfdata_t, void *); 139 static void qcpas_attach(device_t, device_t, void *); 140 141 CFATTACH_DECL_NEW(qcompas, sizeof(struct qcpas_softc), 142 qcpas_match, qcpas_attach, NULL, NULL); 143 144 static void qcpas_mountroot(device_t); 145 static void qcpas_firmload(void *); 146 static int qcpas_map_memory(struct qcpas_softc *); 147 static int qcpas_mdt_init(struct qcpas_softc *, int, u_char *, size_t); 148 static void qcpas_glink_attach(struct qcpas_softc *); 149 static void qcpas_glink_recv(void *); 150 static void qcpas_get_limits(struct sysmon_envsys *, envsys_data_t *, 151 sysmon_envsys_lim_t *, uint32_t *); 152 153 static struct qcpas_dmamem * 154 qcpas_dmamem_alloc(struct qcpas_softc *, bus_size_t, bus_size_t); 155 static void qcpas_dmamem_free(struct qcpas_softc *, struct qcpas_dmamem *); 156 157 static int qcpas_intr_wdog(void *); 158 static int qcpas_intr_fatal(void *); 159 static int qcpas_intr_ready(void *); 160 static int qcpas_intr_handover(void *); 161 static int qcpas_intr_stop_ack(void *); 162 163 struct qcpas_mem_region { 164 bus_addr_t start; 165 bus_size_t size; 166 }; 167 168 struct qcpas_data { 169 bus_addr_t reg_addr; 170 bus_size_t reg_size; 171 uint32_t pas_id; 172 uint32_t dtb_pas_id; 173 uint32_t lite_pas_id; 174 const char *load_state; 175 uint32_t glink_remote_pid; 176 struct qcpas_mem_region mem_region[2]; 177 const char *fwname; 178 const char *dtb_fwname; 179 uint32_t crash_reason; 180 }; 181 182 static struct qcpas_data qcpas_x1e_data = { 183 .reg_addr = 0x30000000, 184 .reg_size = 0x100, 185 .pas_id = 1, 186 .dtb_pas_id = 36, 187 .lite_pas_id = 31, 188 .load_state = "adsp", 189 .glink_remote_pid = 2, 190 .mem_region = { 191 [0] = { .start = 0x87e00000, .size = 0x3a00000 }, 192 [1] = { .start = 0x8b800000, .size = 0x80000 }, 193 }, 194 .fwname = "qcadsp8380.mbn", 195 .dtb_fwname = "adsp_dtbs.elf", 196 .crash_reason = 423, 197 }; 198 199 #define IPCC_CLIENT_LPASS 3 200 #define IPCC_MPROC_SIGNAL_GLINK_QMP 0 201 202 static const struct device_compatible_entry compat_data[] = { 203 { .compat = "QCOM0C1B", .data = &qcpas_x1e_data }, 204 DEVICE_COMPAT_EOL 205 }; 206 207 static int 208 qcpas_match(device_t parent, cfdata_t match, void *aux) 209 { 210 struct acpi_attach_args *aa = aux; 211 212 return acpi_compatible_match(aa, compat_data); 213 } 214 215 static void 216 qcpas_attach(device_t parent, device_t self, void *aux) 217 { 218 struct qcpas_softc *sc = device_private(self); 219 struct acpi_attach_args *aa = aux; 220 const struct qcpas_data *data; 221 struct acpi_resources res; 222 ACPI_STATUS rv; 223 int i; 224 225 rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS", &res, 226 &acpi_resource_parse_ops_default); 227 if (ACPI_FAILURE(rv)) { 228 return; 229 } 230 acpi_resource_cleanup(&res); 231 232 data = acpi_compatible_lookup(aa, compat_data)->data; 233 234 sc->sc_dev = self; 235 sc->sc_dmat = &arm_generic_dma_tag; 236 mutex_init(&sc->sc_ready_lock, MUTEX_DEFAULT, IPL_VM); 237 cv_init(&sc->sc_ready_cv, "qcpasrdy"); 238 239 sc->sc_fwname = data->fwname; 240 sc->sc_dtb_fwname = data->dtb_fwname; 241 sc->sc_pas_id = data->pas_id; 242 sc->sc_dtb_pas_id = data->dtb_pas_id; 243 sc->sc_lite_pas_id = data->lite_pas_id; 244 sc->sc_load_state = data->load_state; 245 sc->sc_glink_remote_pid = data->glink_remote_pid; 246 sc->sc_crash_reason = data->crash_reason; 247 for (i = 0; i < __arraycount(sc->sc_mem_phys); i++) { 248 sc->sc_mem_phys[i] = data->mem_region[i].start; 249 KASSERT((sc->sc_mem_phys[i] & PAGE_MASK) == 0); 250 sc->sc_mem_size[i] = data->mem_region[i].size; 251 KASSERT((sc->sc_mem_size[i] & PAGE_MASK) == 0); 252 } 253 254 rv = acpi_eval_string(aa->aa_node->ad_handle, "_SUB", &sc->sc_sub); 255 if (ACPI_FAILURE(rv)) { 256 aprint_error_dev(self, "failed to evaluate _SUB: %s\n", 257 AcpiFormatException(rv)); 258 return; 259 } 260 aprint_verbose_dev(self, "subsystem ID %s\n", sc->sc_sub); 261 262 sc->sc_ih[0] = acpi_intr_establish(self, 263 (uint64_t)(uintptr_t)aa->aa_node->ad_handle, 264 IPL_VM, false, qcpas_intr_wdog, sc, device_xname(self)); 265 sc->sc_ih[1] = 266 qcsmptp_intr_establish(0, qcpas_intr_fatal, sc); 267 sc->sc_ih[2] = 268 qcsmptp_intr_establish(1, qcpas_intr_ready, sc); 269 sc->sc_ih[3] = 270 qcsmptp_intr_establish(2, qcpas_intr_handover, sc); 271 sc->sc_ih[4] = 272 qcsmptp_intr_establish(3, qcpas_intr_stop_ack, sc); 273 274 if (qcpas_map_memory(sc) != 0) 275 return; 276 277 config_mountroot(self, qcpas_mountroot); 278 } 279 280 static void 281 qcpas_firmload(void *arg) 282 { 283 struct qcpas_softc *sc = arg; 284 firmware_handle_t fwh = NULL, dtb_fwh = NULL; 285 char fwname[128]; 286 size_t fwlen = 0, dtb_fwlen = 0; 287 u_char *fw = NULL, *dtb_fw = NULL; 288 int ret, error; 289 290 snprintf(fwname, sizeof(fwname), "%s/%s", sc->sc_sub, sc->sc_fwname); 291 error = firmware_open(DRIVER_NAME, fwname, &fwh); 292 if (error == 0) { 293 fwlen = firmware_get_size(fwh); 294 fw = fwlen ? firmware_malloc(fwlen) : NULL; 295 error = fw == NULL ? ENOMEM : 296 firmware_read(fwh, 0, fw, fwlen); 297 } 298 if (error) { 299 device_printf(sc->sc_dev, "failed to load %s/%s: %d\n", 300 DRIVER_NAME, fwname, error); 301 goto cleanup; 302 } 303 aprint_normal_dev(sc->sc_dev, "loading %s/%s\n", DRIVER_NAME, fwname); 304 305 if (sc->sc_lite_pas_id) { 306 if (qcscm_pas_shutdown(sc->sc_lite_pas_id)) { 307 device_printf(sc->sc_dev, 308 "failed to shutdown lite firmware\n"); 309 } 310 } 311 312 if (sc->sc_dtb_pas_id) { 313 snprintf(fwname, sizeof(fwname), "%s/%s", sc->sc_sub, 314 sc->sc_dtb_fwname); 315 error = firmware_open(DRIVER_NAME, fwname, &dtb_fwh); 316 if (error == 0) { 317 dtb_fwlen = firmware_get_size(dtb_fwh); 318 dtb_fw = dtb_fwlen ? firmware_malloc(dtb_fwlen) : NULL; 319 error = dtb_fw == NULL ? ENOMEM : 320 firmware_read(dtb_fwh, 0, dtb_fw, dtb_fwlen); 321 } 322 if (error) { 323 device_printf(sc->sc_dev, "failed to load %s/%s: %d\n", 324 DRIVER_NAME, fwname, error); 325 goto cleanup; 326 } 327 aprint_normal_dev(sc->sc_dev, "loading %s/%s\n", DRIVER_NAME, fwname); 328 } 329 330 if (sc->sc_load_state) { 331 char buf[64]; 332 snprintf(buf, sizeof(buf), 333 "{class: image, res: load_state, name: %s, val: on}", 334 sc->sc_load_state); 335 ret = qcaoss_send(buf, sizeof(buf)); 336 if (ret != 0) { 337 device_printf(sc->sc_dev, "failed to toggle load state\n"); 338 goto cleanup; 339 } 340 } 341 342 if (sc->sc_dtb_pas_id) { 343 qcpas_mdt_init(sc, sc->sc_dtb_pas_id, dtb_fw, dtb_fwlen); 344 } 345 346 ret = qcpas_mdt_init(sc, sc->sc_pas_id, fw, fwlen); 347 if (ret != 0) { 348 device_printf(sc->sc_dev, "failed to boot coprocessor\n"); 349 goto cleanup; 350 } 351 352 qcpas_glink_attach(sc); 353 354 /* Battery sensors */ 355 sc->sc_sme = sysmon_envsys_create(); 356 sc->sc_sme->sme_name = "battery"; 357 sc->sc_sme->sme_cookie = sc; 358 sc->sc_sme->sme_flags = SME_DISABLE_REFRESH; 359 sc->sc_sme->sme_class = SME_CLASS_BATTERY; 360 sc->sc_sme->sme_get_limits = qcpas_get_limits; 361 362 /* AC adapter sensors */ 363 sc->sc_sme_acadapter = sysmon_envsys_create(); 364 sc->sc_sme_acadapter->sme_name = "charger"; 365 sc->sc_sme_acadapter->sme_cookie = sc; 366 sc->sc_sme_acadapter->sme_flags = SME_DISABLE_REFRESH; 367 sc->sc_sme_acadapter->sme_class = SME_CLASS_ACADAPTER; 368 369 #define INIT_SENSOR(sme, idx, unit, str) \ 370 do { \ 371 strlcpy(sc->sc_sens[idx].desc, str, \ 372 sizeof(sc->sc_sens[0].desc)); \ 373 sc->sc_sens[idx].units = unit; \ 374 sc->sc_sens[idx].state = ENVSYS_SINVALID; \ 375 sysmon_envsys_sensor_attach(sme, \ 376 &sc->sc_sens[idx]); \ 377 } while (0) 378 379 INIT_SENSOR(sc->sc_sme, QCPAS_DVOLTAGE, ENVSYS_SVOLTS_DC, "design voltage"); 380 INIT_SENSOR(sc->sc_sme, QCPAS_VOLTAGE, ENVSYS_SVOLTS_DC, "voltage"); 381 INIT_SENSOR(sc->sc_sme, QCPAS_DCAPACITY, ENVSYS_SWATTHOUR, "design cap"); 382 INIT_SENSOR(sc->sc_sme, QCPAS_LFCCAPACITY, ENVSYS_SWATTHOUR, "last full cap"); 383 INIT_SENSOR(sc->sc_sme, QCPAS_CAPACITY, ENVSYS_SWATTHOUR, "charge"); 384 INIT_SENSOR(sc->sc_sme, QCPAS_CHARGERATE, ENVSYS_SWATTS, "charge rate"); 385 INIT_SENSOR(sc->sc_sme, QCPAS_DISCHARGERATE, ENVSYS_SWATTS, "discharge rate"); 386 INIT_SENSOR(sc->sc_sme, QCPAS_CHARGING, ENVSYS_BATTERY_CHARGE, "charging"); 387 INIT_SENSOR(sc->sc_sme, QCPAS_CHARGE_STATE, ENVSYS_BATTERY_CAPACITY, "charge state"); 388 INIT_SENSOR(sc->sc_sme, QCPAS_DCYCLES, ENVSYS_INTEGER, "discharge cycles"); 389 INIT_SENSOR(sc->sc_sme, QCPAS_TEMPERATURE, ENVSYS_STEMP, "temperature"); 390 INIT_SENSOR(sc->sc_sme_acadapter, QCPAS_ACADAPTER, ENVSYS_INDICATOR, "connected"); 391 392 #undef INIT_SENSOR 393 394 sc->sc_sens[QCPAS_CHARGE_STATE].value_cur = 395 ENVSYS_BATTERY_CAPACITY_NORMAL; 396 sc->sc_sens[QCPAS_CAPACITY].flags |= 397 ENVSYS_FPERCENT | ENVSYS_FVALID_MAX | ENVSYS_FMONLIMITS; 398 sc->sc_sens[QCPAS_CHARGE_STATE].flags |= 399 ENVSYS_FMONSTCHANGED; 400 401 sc->sc_sens[QCPAS_VOLTAGE].flags = ENVSYS_FMONNOTSUPP; 402 sc->sc_sens[QCPAS_CHARGERATE].flags = ENVSYS_FMONNOTSUPP; 403 sc->sc_sens[QCPAS_DISCHARGERATE].flags = ENVSYS_FMONNOTSUPP; 404 sc->sc_sens[QCPAS_DCAPACITY].flags = ENVSYS_FMONNOTSUPP; 405 sc->sc_sens[QCPAS_LFCCAPACITY].flags = ENVSYS_FMONNOTSUPP; 406 sc->sc_sens[QCPAS_DVOLTAGE].flags = ENVSYS_FMONNOTSUPP; 407 408 sc->sc_sens[QCPAS_CHARGERATE].flags |= ENVSYS_FHAS_ENTROPY; 409 sc->sc_sens[QCPAS_DISCHARGERATE].flags |= ENVSYS_FHAS_ENTROPY; 410 411 sysmon_envsys_register(sc->sc_sme); 412 sysmon_envsys_register(sc->sc_sme_acadapter); 413 414 sc->sc_smpsw_acadapter.smpsw_name = "acpiacad0"; 415 sc->sc_smpsw_acadapter.smpsw_type = PSWITCH_TYPE_ACADAPTER; 416 sysmon_pswitch_register(&sc->sc_smpsw_acadapter); 417 418 cleanup: 419 if (dtb_fw != NULL) { 420 firmware_free(dtb_fw, dtb_fwlen); 421 } 422 if (fw != NULL) { 423 firmware_free(fw, fwlen); 424 } 425 if (dtb_fwh != NULL) { 426 firmware_close(dtb_fwh); 427 } 428 if (fwh != NULL) { 429 firmware_close(fwh); 430 } 431 } 432 433 static void 434 qcpas_mountroot(device_t self) 435 { 436 struct qcpas_softc *sc = device_private(self); 437 438 sysmon_task_queue_sched(0, qcpas_firmload, sc); 439 } 440 441 static int 442 qcpas_map_memory(struct qcpas_softc *sc) 443 { 444 int i; 445 446 for (i = 0; i < __arraycount(sc->sc_mem_phys); i++) { 447 paddr_t pa, epa; 448 vaddr_t va; 449 450 if (sc->sc_mem_size[i] == 0) 451 break; 452 453 va = uvm_km_alloc(kernel_map, sc->sc_mem_size[i], 0, UVM_KMF_VAONLY); 454 KASSERT(va != 0); 455 sc->sc_mem_region[i] = (void *)va; 456 457 for (pa = sc->sc_mem_phys[i], epa = sc->sc_mem_phys[i] + sc->sc_mem_size[i]; 458 pa < epa; 459 pa += PAGE_SIZE, va += PAGE_SIZE) { 460 pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, PMAP_WRITE_COMBINE); 461 } 462 pmap_update(pmap_kernel()); 463 } 464 465 return 0; 466 } 467 468 static int 469 qcpas_mdt_init(struct qcpas_softc *sc, int pas_id, u_char *fw, size_t fwlen) 470 { 471 Elf32_Ehdr *ehdr; 472 Elf32_Phdr *phdr; 473 paddr_t minpa = -1, maxpa = 0; 474 int i, hashseg = 0, relocate = 0; 475 uint8_t *metadata; 476 int error; 477 ssize_t off; 478 int idx; 479 480 if (pas_id == sc->sc_dtb_pas_id) 481 idx = 1; 482 else 483 idx = 0; 484 485 ehdr = (Elf32_Ehdr *)fw; 486 phdr = (Elf32_Phdr *)&ehdr[1]; 487 488 if (ehdr->e_phnum < 2 || phdr[0].p_type == PT_LOAD) 489 return EINVAL; 490 491 for (i = 0; i < ehdr->e_phnum; i++) { 492 if ((phdr[i].p_flags & MDT_TYPE_MASK) == MDT_TYPE_HASH) { 493 if (i > 0 && !hashseg) 494 hashseg = i; 495 continue; 496 } 497 if (phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0) 498 continue; 499 if (phdr[i].p_flags & MDT_RELOCATABLE) 500 relocate = 1; 501 if (phdr[i].p_paddr < minpa) 502 minpa = phdr[i].p_paddr; 503 if (phdr[i].p_paddr + phdr[i].p_memsz > maxpa) 504 maxpa = 505 roundup(phdr[i].p_paddr + phdr[i].p_memsz, 506 PAGE_SIZE); 507 } 508 509 if (!hashseg) 510 return EINVAL; 511 512 if (sc->sc_metadata[idx] == NULL) { 513 sc->sc_metadata[idx] = qcpas_dmamem_alloc(sc, phdr[0].p_filesz + 514 phdr[hashseg].p_filesz, PAGE_SIZE); 515 if (sc->sc_metadata[idx] == NULL) { 516 return EINVAL; 517 } 518 } 519 520 metadata = QCPAS_DMA_KVA(sc->sc_metadata[idx]); 521 522 memcpy(metadata, fw, phdr[0].p_filesz); 523 if (phdr[0].p_filesz + phdr[hashseg].p_filesz == fwlen) { 524 memcpy(metadata + phdr[0].p_filesz, 525 fw + phdr[0].p_filesz, phdr[hashseg].p_filesz); 526 } else if (phdr[hashseg].p_offset + phdr[hashseg].p_filesz <= fwlen) { 527 memcpy(metadata + phdr[0].p_filesz, 528 fw + phdr[hashseg].p_offset, phdr[hashseg].p_filesz); 529 } else { 530 device_printf(sc->sc_dev, "metadata split segment not supported\n"); 531 return EINVAL; 532 } 533 534 cpu_drain_writebuf(); 535 536 error = qcscm_pas_init_image(pas_id, 537 QCPAS_DMA_DVA(sc->sc_metadata[idx])); 538 if (error != 0) { 539 device_printf(sc->sc_dev, "init image failed: %d\n", error); 540 qcpas_dmamem_free(sc, sc->sc_metadata[idx]); 541 return error; 542 } 543 544 if (relocate) { 545 if (qcscm_pas_mem_setup(pas_id, 546 sc->sc_mem_phys[idx], maxpa - minpa) != 0) { 547 device_printf(sc->sc_dev, "mem setup failed\n"); 548 qcpas_dmamem_free(sc, sc->sc_metadata[idx]); 549 return EINVAL; 550 } 551 } 552 553 sc->sc_mem_reloc[idx] = relocate ? minpa : sc->sc_mem_phys[idx]; 554 555 for (i = 0; i < ehdr->e_phnum; i++) { 556 if ((phdr[i].p_flags & MDT_TYPE_MASK) == MDT_TYPE_HASH || 557 phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0) 558 continue; 559 off = phdr[i].p_paddr - sc->sc_mem_reloc[idx]; 560 if (off < 0 || off + phdr[i].p_memsz > sc->sc_mem_size[0]) 561 return EINVAL; 562 if (phdr[i].p_filesz > phdr[i].p_memsz) 563 return EINVAL; 564 565 if (phdr[i].p_filesz && phdr[i].p_offset < fwlen && 566 phdr[i].p_offset + phdr[i].p_filesz <= fwlen) { 567 memcpy(sc->sc_mem_region[idx] + off, 568 fw + phdr[i].p_offset, phdr[i].p_filesz); 569 } else if (phdr[i].p_filesz) { 570 device_printf(sc->sc_dev, "firmware split segment not supported\n"); 571 return EINVAL; 572 } 573 574 if (phdr[i].p_memsz > phdr[i].p_filesz) 575 memset(sc->sc_mem_region[idx] + off + phdr[i].p_filesz, 576 0, phdr[i].p_memsz - phdr[i].p_filesz); 577 } 578 579 cpu_drain_writebuf(); 580 581 if (qcscm_pas_auth_and_reset(pas_id) != 0) { 582 device_printf(sc->sc_dev, "auth and reset failed\n"); 583 qcpas_dmamem_free(sc, sc->sc_metadata[idx]); 584 return EINVAL; 585 } 586 587 if (pas_id == sc->sc_dtb_pas_id) 588 return 0; 589 590 mutex_enter(&sc->sc_ready_lock); 591 while (!sc->sc_ready) { 592 error = cv_timedwait(&sc->sc_ready_cv, &sc->sc_ready_lock, 593 hz * 5); 594 if (error == EWOULDBLOCK) { 595 break; 596 } 597 } 598 mutex_exit(&sc->sc_ready_lock); 599 if (!sc->sc_ready) { 600 device_printf(sc->sc_dev, "timeout waiting for ready signal\n"); 601 return ETIMEDOUT; 602 } 603 604 /* XXX: free metadata ? */ 605 606 return 0; 607 } 608 609 static struct qcpas_dmamem * 610 qcpas_dmamem_alloc(struct qcpas_softc *sc, bus_size_t size, bus_size_t align) 611 { 612 struct qcpas_dmamem *tdm; 613 int nsegs; 614 615 tdm = kmem_zalloc(sizeof(*tdm), KM_SLEEP); 616 tdm->tdm_size = size; 617 618 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 619 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0) 620 goto tdmfree; 621 622 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, 623 &tdm->tdm_seg, 1, &nsegs, BUS_DMA_WAITOK) != 0) 624 goto destroy; 625 626 if (bus_dmamem_map(sc->sc_dmat, &tdm->tdm_seg, nsegs, size, 627 &tdm->tdm_kva, BUS_DMA_WAITOK | BUS_DMA_PREFETCHABLE) != 0) 628 goto free; 629 630 if (bus_dmamap_load(sc->sc_dmat, tdm->tdm_map, tdm->tdm_kva, size, 631 NULL, BUS_DMA_WAITOK) != 0) 632 goto unmap; 633 634 memset(tdm->tdm_kva, 0, size); 635 636 return (tdm); 637 638 unmap: 639 bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, size); 640 free: 641 bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); 642 destroy: 643 bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); 644 tdmfree: 645 kmem_free(tdm, sizeof(*tdm)); 646 647 return (NULL); 648 } 649 650 static void 651 qcpas_dmamem_free(struct qcpas_softc *sc, struct qcpas_dmamem *tdm) 652 { 653 bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, tdm->tdm_size); 654 bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); 655 bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); 656 kmem_free(tdm, sizeof(*tdm)); 657 } 658 659 static void 660 qcpas_report_crash(struct qcpas_softc *sc, const char *source) 661 { 662 char *msg; 663 int size; 664 665 msg = qcsmem_get(-1, sc->sc_crash_reason, &size); 666 if (msg == NULL || size <= 0) { 667 device_printf(sc->sc_dev, "%s\n", source); 668 } else { 669 device_printf(sc->sc_dev, "%s: \"%s\"\n", source, msg); 670 } 671 } 672 673 static int 674 qcpas_intr_wdog(void *cookie) 675 { 676 struct qcpas_softc *sc = cookie; 677 678 qcpas_report_crash(sc, "watchdog"); 679 680 return 0; 681 } 682 683 static int 684 qcpas_intr_fatal(void *cookie) 685 { 686 struct qcpas_softc *sc = cookie; 687 688 qcpas_report_crash(sc, "fatal error"); 689 690 return 0; 691 } 692 693 static int 694 qcpas_intr_ready(void *cookie) 695 { 696 struct qcpas_softc *sc = cookie; 697 698 aprint_debug_dev(sc->sc_dev, "%s\n", __func__); 699 700 mutex_enter(&sc->sc_ready_lock); 701 sc->sc_ready = true; 702 cv_broadcast(&sc->sc_ready_cv); 703 mutex_exit(&sc->sc_ready_lock); 704 705 return 0; 706 } 707 708 static int 709 qcpas_intr_handover(void *cookie) 710 { 711 struct qcpas_softc *sc = cookie; 712 713 aprint_debug_dev(sc->sc_dev, "%s\n", __func__); 714 715 return 0; 716 } 717 718 static int 719 qcpas_intr_stop_ack(void *cookie) 720 { 721 struct qcpas_softc *sc = cookie; 722 723 aprint_debug_dev(sc->sc_dev, "%s\n", __func__); 724 725 return 0; 726 } 727 728 /* GLINK */ 729 730 #define SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR 478 731 #define SMEM_GLINK_NATIVE_XPRT_FIFO_0 479 732 #define SMEM_GLINK_NATIVE_XPRT_FIFO_1 480 733 734 struct glink_msg { 735 uint16_t cmd; 736 uint16_t param1; 737 uint32_t param2; 738 uint8_t data[]; 739 } __packed; 740 741 struct qcpas_glink_intent_pair { 742 uint32_t size; 743 uint32_t iid; 744 } __packed; 745 746 struct qcpas_glink_intent { 747 TAILQ_ENTRY(qcpas_glink_intent) it_q; 748 uint32_t it_id; 749 uint32_t it_size; 750 int it_inuse; 751 }; 752 753 struct qcpas_glink_channel { 754 TAILQ_ENTRY(qcpas_glink_channel) ch_q; 755 struct qcpas_softc *ch_sc; 756 struct qcpas_glink_protocol *ch_proto; 757 uint32_t ch_rcid; 758 uint32_t ch_lcid; 759 uint32_t ch_max_intent; 760 TAILQ_HEAD(,qcpas_glink_intent) ch_l_intents; 761 TAILQ_HEAD(,qcpas_glink_intent) ch_r_intents; 762 }; 763 764 #define GLINK_CMD_VERSION 0 765 #define GLINK_CMD_VERSION_ACK 1 766 #define GLINK_VERSION 1 767 #define GLINK_FEATURE_INTENT_REUSE (1 << 0) 768 #define GLINK_CMD_OPEN 2 769 #define GLINK_CMD_CLOSE 3 770 #define GLINK_CMD_OPEN_ACK 4 771 #define GLINK_CMD_INTENT 5 772 #define GLINK_CMD_RX_DONE 6 773 #define GLINK_CMD_RX_INTENT_REQ 7 774 #define GLINK_CMD_RX_INTENT_REQ_ACK 8 775 #define GLINK_CMD_TX_DATA 9 776 #define GLINK_CMD_CLOSE_ACK 11 777 #define GLINK_CMD_TX_DATA_CONT 12 778 #define GLINK_CMD_READ_NOTIF 13 779 #define GLINK_CMD_RX_DONE_W_REUSE 14 780 781 static int qcpas_glink_intr(void *); 782 783 static void qcpas_glink_tx(struct qcpas_softc *, uint8_t *, int); 784 static void qcpas_glink_tx_commit(struct qcpas_softc *); 785 static void qcpas_glink_rx(struct qcpas_softc *, uint8_t *, int); 786 static void qcpas_glink_rx_commit(struct qcpas_softc *); 787 788 static void qcpas_glink_send(void *, void *, int); 789 790 static int qcpas_pmic_rtr_init(void *); 791 static int qcpas_pmic_rtr_recv(void *, uint8_t *, int); 792 793 struct qcpas_glink_protocol { 794 const char *name; 795 int (*init)(void *cookie); 796 int (*recv)(void *cookie, uint8_t *buf, int len); 797 } qcpas_glink_protocols[] = { 798 { "PMIC_RTR_ADSP_APPS", qcpas_pmic_rtr_init , qcpas_pmic_rtr_recv }, 799 }; 800 801 static void 802 qcpas_glink_attach(struct qcpas_softc *sc) 803 { 804 uint32_t remote = sc->sc_glink_remote_pid; 805 uint32_t *descs; 806 int size; 807 808 if (qcsmem_alloc(remote, SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, 32) != 0 || 809 qcsmem_alloc(remote, SMEM_GLINK_NATIVE_XPRT_FIFO_0, 16384) != 0) 810 return; 811 812 descs = qcsmem_get(remote, SMEM_GLINK_NATIVE_XPRT_DESCRIPTOR, &size); 813 if (descs == NULL || size != 32) 814 return; 815 816 sc->sc_tx_tail = &descs[0]; 817 sc->sc_tx_head = &descs[1]; 818 sc->sc_rx_tail = &descs[2]; 819 sc->sc_rx_head = &descs[3]; 820 821 sc->sc_tx_fifo = qcsmem_get(remote, SMEM_GLINK_NATIVE_XPRT_FIFO_0, 822 &sc->sc_tx_fifolen); 823 if (sc->sc_tx_fifo == NULL) 824 return; 825 sc->sc_rx_fifo = qcsmem_get(remote, SMEM_GLINK_NATIVE_XPRT_FIFO_1, 826 &sc->sc_rx_fifolen); 827 if (sc->sc_rx_fifo == NULL) 828 return; 829 830 sc->sc_ipcc = qcipcc_channel(IPCC_CLIENT_LPASS, 831 IPCC_MPROC_SIGNAL_GLINK_QMP); 832 if (sc->sc_ipcc == NULL) 833 return; 834 835 TAILQ_INIT(&sc->sc_glink_channels); 836 837 sc->sc_glink_ih = qcipcc_intr_establish(IPCC_CLIENT_LPASS, 838 IPCC_MPROC_SIGNAL_GLINK_QMP, IPL_VM, qcpas_glink_intr, sc); 839 if (sc->sc_glink_ih == NULL) 840 return; 841 842 /* Expect peer to send initial message */ 843 } 844 845 static void 846 qcpas_glink_rx(struct qcpas_softc *sc, uint8_t *buf, int len) 847 { 848 uint32_t head, tail; 849 int avail; 850 851 head = *sc->sc_rx_head; 852 tail = *sc->sc_rx_tail + sc->sc_rx_off; 853 if (tail >= sc->sc_rx_fifolen) 854 tail -= sc->sc_rx_fifolen; 855 856 /* Checked by caller */ 857 KASSERT(head != tail); 858 859 if (head >= tail) 860 avail = head - tail; 861 else 862 avail = (sc->sc_rx_fifolen - tail) + head; 863 864 /* Dumb, but should do. */ 865 KASSERT(avail >= len); 866 867 while (len > 0) { 868 *buf = sc->sc_rx_fifo[tail]; 869 tail++; 870 if (tail >= sc->sc_rx_fifolen) 871 tail -= sc->sc_rx_fifolen; 872 buf++; 873 sc->sc_rx_off++; 874 len--; 875 } 876 } 877 878 static void 879 qcpas_glink_rx_commit(struct qcpas_softc *sc) 880 { 881 uint32_t tail; 882 883 tail = *sc->sc_rx_tail + roundup(sc->sc_rx_off, 8); 884 if (tail >= sc->sc_rx_fifolen) 885 tail -= sc->sc_rx_fifolen; 886 887 membar_producer(); 888 *sc->sc_rx_tail = tail; 889 sc->sc_rx_off = 0; 890 } 891 892 static void 893 qcpas_glink_tx(struct qcpas_softc *sc, uint8_t *buf, int len) 894 { 895 uint32_t head, tail; 896 int avail; 897 898 head = *sc->sc_tx_head + sc->sc_tx_off; 899 if (head >= sc->sc_tx_fifolen) 900 head -= sc->sc_tx_fifolen; 901 tail = *sc->sc_tx_tail; 902 903 if (head < tail) 904 avail = tail - head; 905 else 906 avail = (sc->sc_rx_fifolen - head) + tail; 907 908 /* Dumb, but should do. */ 909 KASSERT(avail >= len); 910 911 while (len > 0) { 912 sc->sc_tx_fifo[head] = *buf; 913 head++; 914 if (head >= sc->sc_tx_fifolen) 915 head -= sc->sc_tx_fifolen; 916 buf++; 917 sc->sc_tx_off++; 918 len--; 919 } 920 } 921 922 static void 923 qcpas_glink_tx_commit(struct qcpas_softc *sc) 924 { 925 uint32_t head; 926 927 head = *sc->sc_tx_head + roundup(sc->sc_tx_off, 8); 928 if (head >= sc->sc_tx_fifolen) 929 head -= sc->sc_tx_fifolen; 930 931 membar_producer(); 932 *sc->sc_tx_head = head; 933 sc->sc_tx_off = 0; 934 qcipcc_send(sc->sc_ipcc); 935 } 936 937 static void 938 qcpas_glink_send(void *cookie, void *buf, int len) 939 { 940 struct qcpas_glink_channel *ch = cookie; 941 struct qcpas_softc *sc = ch->ch_sc; 942 struct qcpas_glink_intent *it; 943 struct glink_msg msg; 944 uint32_t chunk_size, left_size; 945 946 TAILQ_FOREACH(it, &ch->ch_r_intents, it_q) { 947 if (!it->it_inuse) 948 break; 949 if (it->it_size < len) 950 continue; 951 } 952 if (it == NULL) { 953 device_printf(sc->sc_dev, "all intents in use\n"); 954 return; 955 } 956 it->it_inuse = 1; 957 958 msg.cmd = GLINK_CMD_TX_DATA; 959 msg.param1 = ch->ch_lcid; 960 msg.param2 = it->it_id; 961 962 chunk_size = len; 963 left_size = 0; 964 965 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 966 qcpas_glink_tx(sc, (char *)&chunk_size, sizeof(chunk_size)); 967 qcpas_glink_tx(sc, (char *)&left_size, sizeof(left_size)); 968 qcpas_glink_tx(sc, buf, len); 969 qcpas_glink_tx_commit(sc); 970 } 971 972 static void 973 qcpas_glink_recv_version(struct qcpas_softc *sc, uint32_t ver, 974 uint32_t features) 975 { 976 struct glink_msg msg; 977 978 if (ver != GLINK_VERSION) { 979 device_printf(sc->sc_dev, 980 "unsupported glink version %u\n", ver); 981 return; 982 } 983 984 msg.cmd = GLINK_CMD_VERSION_ACK; 985 msg.param1 = GLINK_VERSION; 986 msg.param2 = features & GLINK_FEATURE_INTENT_REUSE; 987 988 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 989 qcpas_glink_tx_commit(sc); 990 } 991 992 static void 993 qcpas_glink_recv_open(struct qcpas_softc *sc, uint32_t rcid, uint32_t namelen) 994 { 995 struct qcpas_glink_protocol *proto = NULL; 996 struct qcpas_glink_channel *ch; 997 struct glink_msg msg; 998 char *name; 999 int i, err; 1000 1001 name = kmem_zalloc(namelen, KM_SLEEP); 1002 qcpas_glink_rx(sc, name, namelen); 1003 qcpas_glink_rx_commit(sc); 1004 1005 TAILQ_FOREACH(ch, &sc->sc_glink_channels, ch_q) { 1006 if (ch->ch_rcid == rcid) { 1007 device_printf(sc->sc_dev, "duplicate open for %s\n", 1008 name); 1009 kmem_free(name, namelen); 1010 return; 1011 } 1012 } 1013 1014 for (i = 0; i < __arraycount(qcpas_glink_protocols); i++) { 1015 if (strcmp(qcpas_glink_protocols[i].name, name) != 0) 1016 continue; 1017 proto = &qcpas_glink_protocols[i]; 1018 break; 1019 } 1020 if (proto == NULL) { 1021 kmem_free(name, namelen); 1022 return; 1023 } 1024 1025 ch = kmem_zalloc(sizeof(*ch), KM_SLEEP); 1026 ch->ch_sc = sc; 1027 ch->ch_proto = proto; 1028 ch->ch_rcid = rcid; 1029 ch->ch_lcid = ++sc->sc_glink_max_channel; 1030 TAILQ_INIT(&ch->ch_l_intents); 1031 TAILQ_INIT(&ch->ch_r_intents); 1032 TAILQ_INSERT_TAIL(&sc->sc_glink_channels, ch, ch_q); 1033 1034 /* Assume we can leave HW dangling if proto init fails */ 1035 err = proto->init(ch); 1036 if (err) { 1037 TAILQ_REMOVE(&sc->sc_glink_channels, ch, ch_q); 1038 kmem_free(ch, sizeof(*ch)); 1039 kmem_free(name, namelen); 1040 return; 1041 } 1042 1043 msg.cmd = GLINK_CMD_OPEN_ACK; 1044 msg.param1 = ch->ch_rcid; 1045 msg.param2 = 0; 1046 1047 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 1048 qcpas_glink_tx_commit(sc); 1049 1050 msg.cmd = GLINK_CMD_OPEN; 1051 msg.param1 = ch->ch_lcid; 1052 msg.param2 = strlen(name) + 1; 1053 1054 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 1055 qcpas_glink_tx(sc, name, strlen(name) + 1); 1056 qcpas_glink_tx_commit(sc); 1057 1058 kmem_free(name, namelen); 1059 } 1060 1061 static void 1062 qcpas_glink_recv_open_ack(struct qcpas_softc *sc, uint32_t lcid) 1063 { 1064 struct qcpas_glink_channel *ch; 1065 struct glink_msg msg; 1066 struct qcpas_glink_intent_pair intent; 1067 int i; 1068 1069 TAILQ_FOREACH(ch, &sc->sc_glink_channels, ch_q) { 1070 if (ch->ch_lcid == lcid) 1071 break; 1072 } 1073 if (ch == NULL) { 1074 device_printf(sc->sc_dev, "unknown channel %u for OPEN_ACK\n", 1075 lcid); 1076 return; 1077 } 1078 1079 /* Respond with default intent now that channel is open */ 1080 for (i = 0; i < 5; i++) { 1081 struct qcpas_glink_intent *it; 1082 1083 it = kmem_zalloc(sizeof(*it), KM_SLEEP); 1084 it->it_id = ++ch->ch_max_intent; 1085 it->it_size = 1024; 1086 TAILQ_INSERT_TAIL(&ch->ch_l_intents, it, it_q); 1087 1088 msg.cmd = GLINK_CMD_INTENT; 1089 msg.param1 = ch->ch_lcid; 1090 msg.param2 = 1; 1091 intent.size = it->it_size; 1092 intent.iid = it->it_id; 1093 } 1094 1095 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 1096 qcpas_glink_tx(sc, (char *)&intent, sizeof(intent)); 1097 qcpas_glink_tx_commit(sc); 1098 } 1099 1100 static void 1101 qcpas_glink_recv_intent(struct qcpas_softc *sc, uint32_t rcid, uint32_t count) 1102 { 1103 struct qcpas_glink_intent_pair *intents; 1104 struct qcpas_glink_channel *ch; 1105 struct qcpas_glink_intent *it; 1106 int i; 1107 1108 intents = kmem_zalloc(sizeof(*intents) * count, KM_SLEEP); 1109 qcpas_glink_rx(sc, (char *)intents, sizeof(*intents) * count); 1110 qcpas_glink_rx_commit(sc); 1111 1112 TAILQ_FOREACH(ch, &sc->sc_glink_channels, ch_q) { 1113 if (ch->ch_rcid == rcid) 1114 break; 1115 } 1116 if (ch == NULL) { 1117 device_printf(sc->sc_dev, "unknown channel %u for INTENT\n", 1118 rcid); 1119 kmem_free(intents, sizeof(*intents) * count); 1120 return; 1121 } 1122 1123 for (i = 0; i < count; i++) { 1124 it = kmem_zalloc(sizeof(*it), KM_SLEEP); 1125 it->it_id = intents[i].iid; 1126 it->it_size = intents[i].size; 1127 TAILQ_INSERT_TAIL(&ch->ch_r_intents, it, it_q); 1128 } 1129 1130 kmem_free(intents, sizeof(*intents) * count); 1131 } 1132 1133 static void 1134 qcpas_glink_recv_tx_data(struct qcpas_softc *sc, uint32_t rcid, uint32_t liid) 1135 { 1136 struct qcpas_glink_channel *ch; 1137 struct qcpas_glink_intent *it; 1138 struct glink_msg msg; 1139 uint32_t chunk_size, left_size; 1140 char *buf; 1141 1142 qcpas_glink_rx(sc, (char *)&chunk_size, sizeof(chunk_size)); 1143 qcpas_glink_rx(sc, (char *)&left_size, sizeof(left_size)); 1144 qcpas_glink_rx_commit(sc); 1145 1146 buf = kmem_zalloc(chunk_size, KM_SLEEP); 1147 qcpas_glink_rx(sc, buf, chunk_size); 1148 qcpas_glink_rx_commit(sc); 1149 1150 TAILQ_FOREACH(ch, &sc->sc_glink_channels, ch_q) { 1151 if (ch->ch_rcid == rcid) 1152 break; 1153 } 1154 if (ch == NULL) { 1155 device_printf(sc->sc_dev, "unknown channel %u for TX_DATA\n", 1156 rcid); 1157 kmem_free(buf, chunk_size); 1158 return; 1159 } 1160 1161 TAILQ_FOREACH(it, &ch->ch_l_intents, it_q) { 1162 if (it->it_id == liid) 1163 break; 1164 } 1165 if (it == NULL) { 1166 device_printf(sc->sc_dev, "unknown intent %u for TX_DATA\n", 1167 liid); 1168 kmem_free(buf, chunk_size); 1169 return; 1170 } 1171 1172 /* FIXME: handle message chunking */ 1173 KASSERT(left_size == 0); 1174 1175 ch->ch_proto->recv(ch, buf, chunk_size); 1176 kmem_free(buf, chunk_size); 1177 1178 if (!left_size) { 1179 msg.cmd = GLINK_CMD_RX_DONE_W_REUSE; 1180 msg.param1 = ch->ch_lcid; 1181 msg.param2 = it->it_id; 1182 1183 qcpas_glink_tx(sc, (char *)&msg, sizeof(msg)); 1184 qcpas_glink_tx_commit(sc); 1185 } 1186 } 1187 1188 static void 1189 qcpas_glink_recv_rx_done(struct qcpas_softc *sc, uint32_t rcid, uint32_t riid, 1190 int reuse) 1191 { 1192 struct qcpas_glink_channel *ch; 1193 struct qcpas_glink_intent *it; 1194 1195 TAILQ_FOREACH(ch, &sc->sc_glink_channels, ch_q) { 1196 if (ch->ch_rcid == rcid) 1197 break; 1198 } 1199 if (ch == NULL) { 1200 device_printf(sc->sc_dev, "unknown channel %u for RX_DONE\n", 1201 rcid); 1202 return; 1203 } 1204 1205 TAILQ_FOREACH(it, &ch->ch_r_intents, it_q) { 1206 if (it->it_id == riid) 1207 break; 1208 } 1209 if (it == NULL) { 1210 device_printf(sc->sc_dev, "unknown intent %u for RX_DONE\n", 1211 riid); 1212 return; 1213 } 1214 1215 /* FIXME: handle non-reuse */ 1216 KASSERT(reuse); 1217 1218 KASSERT(it->it_inuse); 1219 it->it_inuse = 0; 1220 } 1221 1222 static void 1223 qcpas_glink_recv(void *arg) 1224 { 1225 struct qcpas_softc *sc = arg; 1226 struct glink_msg msg; 1227 1228 while (*sc->sc_rx_tail != *sc->sc_rx_head) { 1229 membar_consumer(); 1230 qcpas_glink_rx(sc, (uint8_t *)&msg, sizeof(msg)); 1231 qcpas_glink_rx_commit(sc); 1232 1233 switch (msg.cmd) { 1234 case GLINK_CMD_VERSION: 1235 qcpas_glink_recv_version(sc, msg.param1, msg.param2); 1236 break; 1237 case GLINK_CMD_OPEN: 1238 qcpas_glink_recv_open(sc, msg.param1, msg.param2); 1239 break; 1240 case GLINK_CMD_OPEN_ACK: 1241 qcpas_glink_recv_open_ack(sc, msg.param1); 1242 break; 1243 case GLINK_CMD_INTENT: 1244 qcpas_glink_recv_intent(sc, msg.param1, msg.param2); 1245 break; 1246 case GLINK_CMD_RX_INTENT_REQ: 1247 /* Nothing to do so far */ 1248 break; 1249 case GLINK_CMD_TX_DATA: 1250 qcpas_glink_recv_tx_data(sc, msg.param1, msg.param2); 1251 break; 1252 case GLINK_CMD_RX_DONE: 1253 qcpas_glink_recv_rx_done(sc, msg.param1, msg.param2, 0); 1254 break; 1255 case GLINK_CMD_RX_DONE_W_REUSE: 1256 qcpas_glink_recv_rx_done(sc, msg.param1, msg.param2, 1); 1257 break; 1258 default: 1259 device_printf(sc->sc_dev, "unknown cmd %u\n", msg.cmd); 1260 return; 1261 } 1262 } 1263 } 1264 1265 static int 1266 qcpas_glink_intr(void *cookie) 1267 { 1268 struct qcpas_softc *sc = cookie; 1269 1270 sysmon_task_queue_sched(0, qcpas_glink_recv, sc); 1271 1272 return 1; 1273 } 1274 1275 /* GLINK PMIC Router */ 1276 1277 struct pmic_glink_hdr { 1278 uint32_t owner; 1279 #define PMIC_GLINK_OWNER_BATTMGR 32778 1280 #define PMIC_GLINK_OWNER_USBC 32779 1281 #define PMIC_GLINK_OWNER_USBC_PAN 32780 1282 uint32_t type; 1283 #define PMIC_GLINK_TYPE_REQ_RESP 1 1284 #define PMIC_GLINK_TYPE_NOTIFY 2 1285 uint32_t opcode; 1286 }; 1287 1288 #define BATTMGR_OPCODE_BAT_STATUS 0x1 1289 #define BATTMGR_OPCODR_REQUEST_NOTIFICATION 0x4 1290 #define BATTMGR_OPCODE_NOTIF 0x7 1291 #define BATTMGR_OPCODE_BAT_INFO 0x9 1292 #define BATTMGR_OPCODE_BAT_DISCHARGE_TIME 0xc 1293 #define BATTMGR_OPCODE_BAT_CHARGE_TIME 0xd 1294 1295 #define BATTMGR_NOTIF_BAT_PROPERTY 0x30 1296 #define BATTMGR_NOTIF_USB_PROPERTY 0x32 1297 #define BATTMGR_NOTIF_WLS_PROPERTY 0x34 1298 #define BATTMGR_NOTIF_BAT_STATUS 0x80 1299 #define BATTMGR_NOTIF_BAT_INFO 0x81 1300 1301 #define BATTMGR_CHEMISTRY_LEN 4 1302 #define BATTMGR_STRING_LEN 128 1303 1304 struct battmgr_bat_info { 1305 uint32_t power_unit; 1306 uint32_t design_capacity; 1307 uint32_t last_full_capacity; 1308 uint32_t battery_tech; 1309 uint32_t design_voltage; 1310 uint32_t capacity_low; 1311 uint32_t capacity_warning; 1312 uint32_t cycle_count; 1313 uint32_t accuracy; 1314 uint32_t max_sample_time_ms; 1315 uint32_t min_sample_time_ms; 1316 uint32_t max_average_interval_ms; 1317 uint32_t min_average_interval_ms; 1318 uint32_t capacity_granularity1; 1319 uint32_t capacity_granularity2; 1320 uint32_t swappable; 1321 uint32_t capabilities; 1322 char model_number[BATTMGR_STRING_LEN]; 1323 char serial_number[BATTMGR_STRING_LEN]; 1324 char battery_type[BATTMGR_STRING_LEN]; 1325 char oem_info[BATTMGR_STRING_LEN]; 1326 char battery_chemistry[BATTMGR_CHEMISTRY_LEN]; 1327 char uid[BATTMGR_STRING_LEN]; 1328 uint32_t critical_bias; 1329 uint8_t day; 1330 uint8_t month; 1331 uint16_t year; 1332 uint32_t battery_id; 1333 }; 1334 1335 struct battmgr_bat_status { 1336 uint32_t battery_state; 1337 #define BATTMGR_BAT_STATE_DISCHARGE (1 << 0) 1338 #define BATTMGR_BAT_STATE_CHARGING (1 << 1) 1339 #define BATTMGR_BAT_STATE_CRITICAL_LOW (1 << 2) 1340 uint32_t capacity; 1341 int32_t rate; 1342 uint32_t battery_voltage; 1343 uint32_t power_state; 1344 #define BATTMGR_PWR_STATE_AC_ON (1 << 0) 1345 uint32_t charging_source; 1346 #define BATTMGR_CHARGING_SOURCE_AC 1 1347 #define BATTMGR_CHARGING_SOURCE_USB 2 1348 #define BATTMGR_CHARGING_SOURCE_WIRELESS 3 1349 uint32_t temperature; 1350 }; 1351 1352 static void qcpas_pmic_rtr_refresh(void *); 1353 static void qcpas_pmic_rtr_bat_info(struct qcpas_softc *, 1354 struct battmgr_bat_info *); 1355 static void qcpas_pmic_rtr_bat_status(struct qcpas_softc *, 1356 struct battmgr_bat_status *); 1357 1358 static void 1359 qcpas_pmic_rtr_battmgr_req_info(void *cookie) 1360 { 1361 struct { 1362 struct pmic_glink_hdr hdr; 1363 uint32_t battery_id; 1364 } msg; 1365 1366 msg.hdr.owner = PMIC_GLINK_OWNER_BATTMGR; 1367 msg.hdr.type = PMIC_GLINK_TYPE_REQ_RESP; 1368 msg.hdr.opcode = BATTMGR_OPCODE_BAT_INFO; 1369 msg.battery_id = 0; 1370 qcpas_glink_send(cookie, &msg, sizeof(msg)); 1371 } 1372 1373 static void 1374 qcpas_pmic_rtr_battmgr_req_status(void *cookie) 1375 { 1376 struct { 1377 struct pmic_glink_hdr hdr; 1378 uint32_t battery_id; 1379 } msg; 1380 1381 msg.hdr.owner = PMIC_GLINK_OWNER_BATTMGR; 1382 msg.hdr.type = PMIC_GLINK_TYPE_REQ_RESP; 1383 msg.hdr.opcode = BATTMGR_OPCODE_BAT_STATUS; 1384 msg.battery_id = 0; 1385 qcpas_glink_send(cookie, &msg, sizeof(msg)); 1386 } 1387 1388 static int 1389 qcpas_pmic_rtr_init(void *cookie) 1390 { 1391 struct qcpas_glink_channel *ch = cookie; 1392 struct qcpas_softc *sc = ch->ch_sc; 1393 1394 callout_init(&sc->sc_rtr_refresh, 0); 1395 callout_setfunc(&sc->sc_rtr_refresh, qcpas_pmic_rtr_refresh, ch); 1396 1397 callout_schedule(&sc->sc_rtr_refresh, hz * 5); 1398 1399 return 0; 1400 } 1401 1402 static int 1403 qcpas_pmic_rtr_recv(void *cookie, uint8_t *buf, int len) 1404 { 1405 struct qcpas_glink_channel *ch = cookie; 1406 struct qcpas_softc *sc = ch->ch_sc; 1407 struct pmic_glink_hdr hdr; 1408 uint32_t notification; 1409 1410 if (len < sizeof(hdr)) { 1411 device_printf(sc->sc_dev, "pmic glink message too small\n"); 1412 return 0; 1413 } 1414 1415 memcpy(&hdr, buf, sizeof(hdr)); 1416 1417 switch (hdr.owner) { 1418 case PMIC_GLINK_OWNER_BATTMGR: 1419 switch (hdr.opcode) { 1420 case BATTMGR_OPCODE_NOTIF: 1421 if (len - sizeof(hdr) != sizeof(uint32_t)) { 1422 device_printf(sc->sc_dev, 1423 "invalid battgmr notification\n"); 1424 return 0; 1425 } 1426 memcpy(¬ification, buf + sizeof(hdr), 1427 sizeof(uint32_t)); 1428 switch (notification) { 1429 case BATTMGR_NOTIF_BAT_INFO: 1430 qcpas_pmic_rtr_battmgr_req_info(cookie); 1431 /* FALLTHROUGH */ 1432 case BATTMGR_NOTIF_BAT_STATUS: 1433 case BATTMGR_NOTIF_BAT_PROPERTY: 1434 qcpas_pmic_rtr_battmgr_req_status(cookie); 1435 break; 1436 default: 1437 aprint_debug_dev(sc->sc_dev, 1438 "unknown battmgr notification 0x%02x\n", 1439 notification); 1440 break; 1441 } 1442 break; 1443 case BATTMGR_OPCODE_BAT_INFO: { 1444 struct battmgr_bat_info *bat; 1445 if (len - sizeof(hdr) < sizeof(*bat)) { 1446 device_printf(sc->sc_dev, 1447 "invalid battgmr bat info\n"); 1448 return 0; 1449 } 1450 bat = kmem_alloc(sizeof(*bat), KM_SLEEP); 1451 memcpy(bat, buf + sizeof(hdr), sizeof(*bat)); 1452 qcpas_pmic_rtr_bat_info(sc, bat); 1453 kmem_free(bat, sizeof(*bat)); 1454 break; 1455 } 1456 case BATTMGR_OPCODE_BAT_STATUS: { 1457 struct battmgr_bat_status *bat; 1458 if (len - sizeof(hdr) != sizeof(*bat)) { 1459 device_printf(sc->sc_dev, 1460 "invalid battgmr bat status\n"); 1461 return 0; 1462 } 1463 bat = kmem_alloc(sizeof(*bat), KM_SLEEP); 1464 memcpy(bat, buf + sizeof(hdr), sizeof(*bat)); 1465 qcpas_pmic_rtr_bat_status(sc, bat); 1466 kmem_free(bat, sizeof(*bat)); 1467 break; 1468 } 1469 default: 1470 device_printf(sc->sc_dev, 1471 "unknown battmgr opcode 0x%02x\n", 1472 hdr.opcode); 1473 break; 1474 } 1475 break; 1476 default: 1477 device_printf(sc->sc_dev, 1478 "unknown pmic glink owner 0x%04x\n", 1479 hdr.owner); 1480 break; 1481 } 1482 1483 return 0; 1484 } 1485 1486 static void 1487 qcpas_pmic_rtr_refresh(void *arg) 1488 { 1489 struct qcpas_glink_channel *ch = arg; 1490 struct qcpas_softc *sc = ch->ch_sc; 1491 1492 qcpas_pmic_rtr_battmgr_req_status(ch); 1493 1494 callout_schedule(&sc->sc_rtr_refresh, hz * 5); 1495 } 1496 1497 static void 1498 qcpas_pmic_rtr_bat_info(struct qcpas_softc *sc, struct battmgr_bat_info *bat) 1499 { 1500 sc->sc_warning_capacity = bat->capacity_warning; 1501 sc->sc_low_capacity = bat->capacity_low; 1502 1503 sc->sc_sens[QCPAS_DCAPACITY].value_cur = 1504 bat->design_capacity * 1000; 1505 sc->sc_sens[QCPAS_DCAPACITY].state = ENVSYS_SVALID; 1506 1507 sc->sc_sens[QCPAS_LFCCAPACITY].value_cur = 1508 bat->last_full_capacity * 1000; 1509 sc->sc_sens[QCPAS_LFCCAPACITY].state = ENVSYS_SVALID; 1510 1511 sc->sc_sens[QCPAS_DVOLTAGE].value_cur = 1512 bat->design_voltage * 1000; 1513 sc->sc_sens[QCPAS_DVOLTAGE].state = ENVSYS_SVALID; 1514 1515 sc->sc_sens[QCPAS_DCYCLES].value_cur = 1516 bat->cycle_count; 1517 sc->sc_sens[QCPAS_DCYCLES].state = ENVSYS_SVALID; 1518 1519 sc->sc_sens[QCPAS_CAPACITY].value_max = 1520 bat->last_full_capacity * 1000; 1521 sysmon_envsys_update_limits(sc->sc_sme, 1522 &sc->sc_sens[QCPAS_CAPACITY]); 1523 } 1524 1525 void 1526 qcpas_pmic_rtr_bat_status(struct qcpas_softc *sc, 1527 struct battmgr_bat_status *bat) 1528 { 1529 sc->sc_sens[QCPAS_CHARGING].value_cur = 1530 (bat->battery_state & BATTMGR_BAT_STATE_CHARGING) != 0; 1531 sc->sc_sens[QCPAS_CHARGING].state = ENVSYS_SVALID; 1532 if ((bat->battery_state & BATTMGR_BAT_STATE_CHARGING) != 0) { 1533 sc->sc_sens[QCPAS_CHARGERATE].value_cur = 1534 abs(bat->rate) * 1000; 1535 sc->sc_sens[QCPAS_CHARGERATE].state = ENVSYS_SVALID; 1536 sc->sc_sens[QCPAS_DISCHARGERATE].state = ENVSYS_SINVALID; 1537 } else if ((bat->battery_state & BATTMGR_BAT_STATE_DISCHARGE) != 0) { 1538 sc->sc_sens[QCPAS_CHARGERATE].state = ENVSYS_SINVALID; 1539 sc->sc_sens[QCPAS_DISCHARGERATE].value_cur = 1540 abs(bat->rate) * 1000; 1541 sc->sc_sens[QCPAS_DISCHARGERATE].state = ENVSYS_SVALID; 1542 } else { 1543 sc->sc_sens[QCPAS_DISCHARGERATE].state = ENVSYS_SINVALID; 1544 sc->sc_sens[QCPAS_CHARGERATE].state = ENVSYS_SINVALID; 1545 } 1546 1547 sc->sc_sens[QCPAS_VOLTAGE].value_cur = 1548 bat->battery_voltage * 1000; 1549 sc->sc_sens[QCPAS_VOLTAGE].state = ENVSYS_SVALID; 1550 1551 sc->sc_sens[QCPAS_TEMPERATURE].value_cur = 1552 (bat->temperature * 10000) + 273150000; 1553 sc->sc_sens[QCPAS_TEMPERATURE].state = ENVSYS_SVALID; 1554 1555 sc->sc_sens[QCPAS_CAPACITY].value_cur = 1556 bat->capacity * 1000; 1557 sc->sc_sens[QCPAS_CAPACITY].state = ENVSYS_SVALID; 1558 1559 sc->sc_sens[QCPAS_CHARGE_STATE].value_cur = 1560 ENVSYS_BATTERY_CAPACITY_NORMAL; 1561 sc->sc_sens[QCPAS_CHARGE_STATE].state = ENVSYS_SVALID; 1562 1563 if (bat->capacity < sc->sc_warning_capacity) { 1564 sc->sc_sens[QCPAS_CAPACITY].state = ENVSYS_SWARNUNDER; 1565 sc->sc_sens[QCPAS_CHARGE_STATE].value_cur = 1566 ENVSYS_BATTERY_CAPACITY_WARNING; 1567 } 1568 1569 if (bat->capacity < sc->sc_low_capacity) { 1570 sc->sc_sens[QCPAS_CAPACITY].state = ENVSYS_SCRITUNDER; 1571 sc->sc_sens[QCPAS_CHARGE_STATE].value_cur = 1572 ENVSYS_BATTERY_CAPACITY_LOW; 1573 } 1574 1575 if ((bat->battery_state & BATTMGR_BAT_STATE_CRITICAL_LOW) != 0) { 1576 sc->sc_sens[QCPAS_CAPACITY].state = ENVSYS_SCRITICAL; 1577 sc->sc_sens[QCPAS_CHARGE_STATE].value_cur = 1578 ENVSYS_BATTERY_CAPACITY_CRITICAL; 1579 } 1580 1581 if ((bat->power_state & BATTMGR_PWR_STATE_AC_ON) != 1582 (sc->sc_power_state & BATTMGR_PWR_STATE_AC_ON)) { 1583 sysmon_pswitch_event(&sc->sc_smpsw_acadapter, 1584 (bat->power_state & BATTMGR_PWR_STATE_AC_ON) != 0 ? 1585 PSWITCH_EVENT_PRESSED : PSWITCH_EVENT_RELEASED); 1586 1587 aprint_debug_dev(sc->sc_dev, "AC adapter %sconnected\n", 1588 (bat->power_state & BATTMGR_PWR_STATE_AC_ON) == 0 ? 1589 "not " : ""); 1590 } 1591 1592 sc->sc_power_state = bat->power_state; 1593 sc->sc_sens[QCPAS_ACADAPTER].value_cur = 1594 (bat->power_state & BATTMGR_PWR_STATE_AC_ON) != 0; 1595 sc->sc_sens[QCPAS_ACADAPTER].state = ENVSYS_SVALID; 1596 } 1597 1598 static void 1599 qcpas_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata, 1600 sysmon_envsys_lim_t *limits, uint32_t *props) 1601 { 1602 struct qcpas_softc *sc = sme->sme_cookie; 1603 1604 if (edata->sensor != QCPAS_CAPACITY) { 1605 return; 1606 } 1607 1608 limits->sel_critmin = sc->sc_low_capacity * 1000; 1609 limits->sel_warnmin = sc->sc_warning_capacity * 1000; 1610 1611 *props |= PROP_BATTCAP | PROP_BATTWARN | PROP_DRIVER_LIMITS; 1612 } 1613