1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * H/W layer of ISHTP provider device (ISH) 4 * 5 * Copyright (c) 2014-2016, Intel Corporation. 6 */ 7 8 #include <linux/sched.h> 9 #include <linux/spinlock.h> 10 #include <linux/delay.h> 11 #include <linux/jiffies.h> 12 #include "client.h" 13 #include "hw-ish.h" 14 #include "hbm.h" 15 16 /* For FW reset flow */ 17 static struct work_struct fw_reset_work; 18 static struct ishtp_device *ishtp_dev; 19 20 /** 21 * ish_reg_read() - Read register 22 * @dev: ISHTP device pointer 23 * @offset: Register offset 24 * 25 * Read 32 bit register at a given offset 26 * 27 * Return: Read register value 28 */ 29 static inline uint32_t ish_reg_read(const struct ishtp_device *dev, 30 unsigned long offset) 31 { 32 struct ish_hw *hw = to_ish_hw(dev); 33 34 return readl(hw->mem_addr + offset); 35 } 36 37 /** 38 * ish_reg_write() - Write register 39 * @dev: ISHTP device pointer 40 * @offset: Register offset 41 * @value: Value to write 42 * 43 * Writes 32 bit register at a give offset 44 */ 45 static inline void ish_reg_write(struct ishtp_device *dev, 46 unsigned long offset, 47 uint32_t value) 48 { 49 struct ish_hw *hw = to_ish_hw(dev); 50 51 writel(value, hw->mem_addr + offset); 52 } 53 54 /** 55 * _ish_read_fw_sts_reg() - Read FW status register 56 * @dev: ISHTP device pointer 57 * 58 * Read FW status register 59 * 60 * Return: Read register value 61 */ 62 static inline uint32_t _ish_read_fw_sts_reg(struct ishtp_device *dev) 63 { 64 return ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 65 } 66 67 /** 68 * check_generated_interrupt() - Check if ISH interrupt 69 * @dev: ISHTP device pointer 70 * 71 * Check if an interrupt was generated for ISH 72 * 73 * Return: Read true or false 74 */ 75 static bool check_generated_interrupt(struct ishtp_device *dev) 76 { 77 bool interrupt_generated = true; 78 uint32_t pisr_val = 0; 79 80 if (dev->pdev->device == CHV_DEVICE_ID) { 81 pisr_val = ish_reg_read(dev, IPC_REG_PISR_CHV_AB); 82 interrupt_generated = 83 IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val); 84 } else { 85 pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT); 86 interrupt_generated = !!pisr_val; 87 /* only busy-clear bit is RW, others are RO */ 88 if (pisr_val) 89 ish_reg_write(dev, IPC_REG_PISR_BXT, pisr_val); 90 } 91 92 return interrupt_generated; 93 } 94 95 /** 96 * ish_is_input_ready() - Check if FW ready for RX 97 * @dev: ISHTP device pointer 98 * 99 * Check if ISH FW is ready for receiving data 100 * 101 * Return: Read true or false 102 */ 103 static bool ish_is_input_ready(struct ishtp_device *dev) 104 { 105 uint32_t doorbell_val; 106 107 doorbell_val = ish_reg_read(dev, IPC_REG_HOST2ISH_DRBL); 108 return !IPC_IS_BUSY(doorbell_val); 109 } 110 111 /** 112 * set_host_ready() - Indicate host ready 113 * @dev: ISHTP device pointer 114 * 115 * Set host ready indication to FW 116 */ 117 static void set_host_ready(struct ishtp_device *dev) 118 { 119 if (dev->pdev->device == CHV_DEVICE_ID) { 120 if (dev->pdev->revision == REVISION_ID_CHT_A0 || 121 (dev->pdev->revision & REVISION_ID_SI_MASK) == 122 REVISION_ID_CHT_Ax_SI) 123 ish_reg_write(dev, IPC_REG_HOST_COMM, 0x81); 124 else if (dev->pdev->revision == REVISION_ID_CHT_B0 || 125 (dev->pdev->revision & REVISION_ID_SI_MASK) == 126 REVISION_ID_CHT_Bx_SI || 127 (dev->pdev->revision & REVISION_ID_SI_MASK) == 128 REVISION_ID_CHT_Kx_SI || 129 (dev->pdev->revision & REVISION_ID_SI_MASK) == 130 REVISION_ID_CHT_Dx_SI) { 131 uint32_t host_comm_val; 132 133 host_comm_val = ish_reg_read(dev, IPC_REG_HOST_COMM); 134 host_comm_val |= IPC_HOSTCOMM_INT_EN_BIT_CHV_AB | 0x81; 135 ish_reg_write(dev, IPC_REG_HOST_COMM, host_comm_val); 136 } 137 } else { 138 uint32_t host_pimr_val; 139 140 host_pimr_val = ish_reg_read(dev, IPC_REG_PIMR_BXT); 141 host_pimr_val |= IPC_PIMR_INT_EN_BIT_BXT; 142 /* 143 * disable interrupt generated instead of 144 * RX_complete_msg 145 */ 146 host_pimr_val &= ~IPC_HOST2ISH_BUSYCLEAR_MASK_BIT; 147 148 ish_reg_write(dev, IPC_REG_PIMR_BXT, host_pimr_val); 149 } 150 } 151 152 /** 153 * ishtp_fw_is_ready() - Check if FW ready 154 * @dev: ISHTP device pointer 155 * 156 * Check if ISH FW is ready 157 * 158 * Return: Read true or false 159 */ 160 static bool ishtp_fw_is_ready(struct ishtp_device *dev) 161 { 162 uint32_t ish_status = _ish_read_fw_sts_reg(dev); 163 164 return IPC_IS_ISH_ILUP(ish_status) && 165 IPC_IS_ISH_ISHTP_READY(ish_status); 166 } 167 168 /** 169 * ish_set_host_rdy() - Indicate host ready 170 * @dev: ISHTP device pointer 171 * 172 * Set host ready indication to FW 173 */ 174 static void ish_set_host_rdy(struct ishtp_device *dev) 175 { 176 uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM); 177 178 IPC_SET_HOST_READY(host_status); 179 ish_reg_write(dev, IPC_REG_HOST_COMM, host_status); 180 } 181 182 /** 183 * ish_clr_host_rdy() - Indicate host not ready 184 * @dev: ISHTP device pointer 185 * 186 * Send host not ready indication to FW 187 */ 188 static void ish_clr_host_rdy(struct ishtp_device *dev) 189 { 190 uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM); 191 192 IPC_CLEAR_HOST_READY(host_status); 193 ish_reg_write(dev, IPC_REG_HOST_COMM, host_status); 194 } 195 196 /** 197 * _ishtp_read_hdr() - Read message header 198 * @dev: ISHTP device pointer 199 * 200 * Read header of 32bit length 201 * 202 * Return: Read register value 203 */ 204 static uint32_t _ishtp_read_hdr(const struct ishtp_device *dev) 205 { 206 return ish_reg_read(dev, IPC_REG_ISH2HOST_MSG); 207 } 208 209 /** 210 * _ishtp_read - Read message 211 * @dev: ISHTP device pointer 212 * @buffer: message buffer 213 * @buffer_length: length of message buffer 214 * 215 * Read message from FW 216 * 217 * Return: Always 0 218 */ 219 static int _ishtp_read(struct ishtp_device *dev, unsigned char *buffer, 220 unsigned long buffer_length) 221 { 222 uint32_t i; 223 uint32_t *r_buf = (uint32_t *)buffer; 224 uint32_t msg_offs; 225 226 msg_offs = IPC_REG_ISH2HOST_MSG + sizeof(struct ishtp_msg_hdr); 227 for (i = 0; i < buffer_length; i += sizeof(uint32_t)) 228 *r_buf++ = ish_reg_read(dev, msg_offs + i); 229 230 return 0; 231 } 232 233 /** 234 * write_ipc_from_queue() - try to write ipc msg from Tx queue to device 235 * @dev: ishtp device pointer 236 * 237 * Check if DRBL is cleared. if it is - write the first IPC msg, then call 238 * the callback function (unless it's NULL) 239 * 240 * Return: 0 for success else failure code 241 */ 242 static int write_ipc_from_queue(struct ishtp_device *dev) 243 { 244 struct wr_msg_ctl_info *ipc_link; 245 unsigned long length; 246 unsigned long rem; 247 unsigned long flags; 248 uint32_t doorbell_val; 249 uint32_t *r_buf; 250 uint32_t reg_addr; 251 int i; 252 void (*ipc_send_compl)(void *); 253 void *ipc_send_compl_prm; 254 255 if (dev->dev_state == ISHTP_DEV_DISABLED) 256 return -EINVAL; 257 258 spin_lock_irqsave(&dev->wr_processing_spinlock, flags); 259 if (!ish_is_input_ready(dev)) { 260 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 261 return -EBUSY; 262 } 263 264 /* 265 * if tx send list is empty - return 0; 266 * may happen, as RX_COMPLETE handler doesn't check list emptiness. 267 */ 268 if (list_empty(&dev->wr_processing_list)) { 269 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 270 return 0; 271 } 272 273 ipc_link = list_first_entry(&dev->wr_processing_list, 274 struct wr_msg_ctl_info, link); 275 /* first 4 bytes of the data is the doorbell value (IPC header) */ 276 length = ipc_link->length - sizeof(uint32_t); 277 doorbell_val = *(uint32_t *)ipc_link->inline_data; 278 r_buf = (uint32_t *)(ipc_link->inline_data + sizeof(uint32_t)); 279 280 /* If sending MNG_SYNC_FW_CLOCK, update clock again */ 281 if (IPC_HEADER_GET_PROTOCOL(doorbell_val) == IPC_PROTOCOL_MNG && 282 IPC_HEADER_GET_MNG_CMD(doorbell_val) == MNG_SYNC_FW_CLOCK) { 283 uint64_t usec_system, usec_utc; 284 struct ipc_time_update_msg time_update; 285 struct time_sync_format ts_format; 286 287 usec_system = ktime_to_us(ktime_get_boottime()); 288 usec_utc = ktime_to_us(ktime_get_real()); 289 ts_format.ts1_source = HOST_SYSTEM_TIME_USEC; 290 ts_format.ts2_source = HOST_UTC_TIME_USEC; 291 ts_format.reserved = 0; 292 293 time_update.primary_host_time = usec_system; 294 time_update.secondary_host_time = usec_utc; 295 time_update.sync_info = ts_format; 296 297 memcpy(r_buf, &time_update, 298 sizeof(struct ipc_time_update_msg)); 299 } 300 301 for (i = 0, reg_addr = IPC_REG_HOST2ISH_MSG; i < length >> 2; i++, 302 reg_addr += 4) 303 ish_reg_write(dev, reg_addr, r_buf[i]); 304 305 rem = length & 0x3; 306 if (rem > 0) { 307 uint32_t reg = 0; 308 309 memcpy(®, &r_buf[length >> 2], rem); 310 ish_reg_write(dev, reg_addr, reg); 311 } 312 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val); 313 314 /* Flush writes to msg registers and doorbell */ 315 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 316 317 /* Update IPC counters */ 318 ++dev->ipc_tx_cnt; 319 dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val); 320 321 ipc_send_compl = ipc_link->ipc_send_compl; 322 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm; 323 list_del_init(&ipc_link->link); 324 list_add(&ipc_link->link, &dev->wr_free_list); 325 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 326 327 /* 328 * callback will be called out of spinlock, 329 * after ipc_link returned to free list 330 */ 331 if (ipc_send_compl) 332 ipc_send_compl(ipc_send_compl_prm); 333 334 return 0; 335 } 336 337 /** 338 * write_ipc_to_queue() - write ipc msg to Tx queue 339 * @dev: ishtp device instance 340 * @ipc_send_compl: Send complete callback 341 * @ipc_send_compl_prm: Parameter to send in complete callback 342 * @msg: Pointer to message 343 * @length: Length of message 344 * 345 * Recived msg with IPC (and upper protocol) header and add it to the device 346 * Tx-to-write list then try to send the first IPC waiting msg 347 * (if DRBL is cleared) 348 * This function returns negative value for failure (means free list 349 * is empty, or msg too long) and 0 for success. 350 * 351 * Return: 0 for success else failure code 352 */ 353 static int write_ipc_to_queue(struct ishtp_device *dev, 354 void (*ipc_send_compl)(void *), void *ipc_send_compl_prm, 355 unsigned char *msg, int length) 356 { 357 struct wr_msg_ctl_info *ipc_link; 358 unsigned long flags; 359 360 if (length > IPC_FULL_MSG_SIZE) 361 return -EMSGSIZE; 362 363 spin_lock_irqsave(&dev->wr_processing_spinlock, flags); 364 if (list_empty(&dev->wr_free_list)) { 365 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 366 return -ENOMEM; 367 } 368 ipc_link = list_first_entry(&dev->wr_free_list, 369 struct wr_msg_ctl_info, link); 370 list_del_init(&ipc_link->link); 371 372 ipc_link->ipc_send_compl = ipc_send_compl; 373 ipc_link->ipc_send_compl_prm = ipc_send_compl_prm; 374 ipc_link->length = length; 375 memcpy(ipc_link->inline_data, msg, length); 376 377 list_add_tail(&ipc_link->link, &dev->wr_processing_list); 378 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 379 380 write_ipc_from_queue(dev); 381 382 return 0; 383 } 384 385 /** 386 * ipc_send_mng_msg() - Send management message 387 * @dev: ishtp device instance 388 * @msg_code: Message code 389 * @msg: Pointer to message 390 * @size: Length of message 391 * 392 * Send management message to FW 393 * 394 * Return: 0 for success else failure code 395 */ 396 static int ipc_send_mng_msg(struct ishtp_device *dev, uint32_t msg_code, 397 void *msg, size_t size) 398 { 399 unsigned char ipc_msg[IPC_FULL_MSG_SIZE]; 400 uint32_t drbl_val = IPC_BUILD_MNG_MSG(msg_code, size); 401 402 memcpy(ipc_msg, &drbl_val, sizeof(uint32_t)); 403 memcpy(ipc_msg + sizeof(uint32_t), msg, size); 404 return write_ipc_to_queue(dev, NULL, NULL, ipc_msg, 405 sizeof(uint32_t) + size); 406 } 407 408 #define WAIT_FOR_FW_RDY 0x1 409 #define WAIT_FOR_INPUT_RDY 0x2 410 411 /** 412 * timed_wait_for_timeout() - wait special event with timeout 413 * @dev: ISHTP device pointer 414 * @condition: indicate the condition for waiting 415 * @timeinc: time slice for every wait cycle, in ms 416 * @timeout: time in ms for timeout 417 * 418 * This function will check special event to be ready in a loop, the loop 419 * period is specificd in timeinc. Wait timeout will causes failure. 420 * 421 * Return: 0 for success else failure code 422 */ 423 static int timed_wait_for_timeout(struct ishtp_device *dev, int condition, 424 unsigned int timeinc, unsigned int timeout) 425 { 426 bool complete = false; 427 int ret; 428 429 do { 430 if (condition == WAIT_FOR_FW_RDY) { 431 complete = ishtp_fw_is_ready(dev); 432 } else if (condition == WAIT_FOR_INPUT_RDY) { 433 complete = ish_is_input_ready(dev); 434 } else { 435 ret = -EINVAL; 436 goto out; 437 } 438 439 if (!complete) { 440 unsigned long left_time; 441 442 left_time = msleep_interruptible(timeinc); 443 timeout -= (timeinc - left_time); 444 } 445 } while (!complete && timeout > 0); 446 447 if (complete) 448 ret = 0; 449 else 450 ret = -EBUSY; 451 452 out: 453 return ret; 454 } 455 456 #define TIME_SLICE_FOR_FW_RDY_MS 100 457 #define TIME_SLICE_FOR_INPUT_RDY_MS 100 458 #define TIMEOUT_FOR_FW_RDY_MS 2000 459 #define TIMEOUT_FOR_INPUT_RDY_MS 2000 460 461 /** 462 * ish_fw_reset_handler() - FW reset handler 463 * @dev: ishtp device pointer 464 * 465 * Handle FW reset 466 * 467 * Return: 0 for success else failure code 468 */ 469 static int ish_fw_reset_handler(struct ishtp_device *dev) 470 { 471 uint32_t reset_id; 472 unsigned long flags; 473 474 /* Read reset ID */ 475 reset_id = ish_reg_read(dev, IPC_REG_ISH2HOST_MSG) & 0xFFFF; 476 477 /* Clear IPC output queue */ 478 spin_lock_irqsave(&dev->wr_processing_spinlock, flags); 479 list_splice_init(&dev->wr_processing_list, &dev->wr_free_list); 480 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags); 481 482 /* ISHTP notification in IPC_RESET */ 483 ishtp_reset_handler(dev); 484 485 if (!ish_is_input_ready(dev)) 486 timed_wait_for_timeout(dev, WAIT_FOR_INPUT_RDY, 487 TIME_SLICE_FOR_INPUT_RDY_MS, TIMEOUT_FOR_INPUT_RDY_MS); 488 489 /* ISH FW is dead */ 490 if (!ish_is_input_ready(dev)) 491 return -EPIPE; 492 /* 493 * Set HOST2ISH.ILUP. Apparently we need this BEFORE sending 494 * RESET_NOTIFY_ACK - FW will be checking for it 495 */ 496 ish_set_host_rdy(dev); 497 /* Send RESET_NOTIFY_ACK (with reset_id) */ 498 ipc_send_mng_msg(dev, MNG_RESET_NOTIFY_ACK, &reset_id, 499 sizeof(uint32_t)); 500 501 /* Wait for ISH FW'es ILUP and ISHTP_READY */ 502 timed_wait_for_timeout(dev, WAIT_FOR_FW_RDY, 503 TIME_SLICE_FOR_FW_RDY_MS, TIMEOUT_FOR_FW_RDY_MS); 504 if (!ishtp_fw_is_ready(dev)) { 505 /* ISH FW is dead */ 506 uint32_t ish_status; 507 508 ish_status = _ish_read_fw_sts_reg(dev); 509 dev_err(dev->devc, 510 "[ishtp-ish]: completed reset, ISH is dead (FWSTS = %08X)\n", 511 ish_status); 512 return -ENODEV; 513 } 514 return 0; 515 } 516 517 #define TIMEOUT_FOR_HW_RDY_MS 300 518 519 /** 520 * ish_fw_reset_work_fn() - FW reset worker function 521 * @unused: not used 522 * 523 * Call ish_fw_reset_handler to complete FW reset 524 */ 525 static void fw_reset_work_fn(struct work_struct *unused) 526 { 527 int rv; 528 529 rv = ish_fw_reset_handler(ishtp_dev); 530 if (!rv) { 531 /* ISH is ILUP & ISHTP-ready. Restart ISHTP */ 532 msleep_interruptible(TIMEOUT_FOR_HW_RDY_MS); 533 ishtp_dev->recvd_hw_ready = 1; 534 wake_up_interruptible(&ishtp_dev->wait_hw_ready); 535 536 /* ISHTP notification in IPC_RESET sequence completion */ 537 ishtp_reset_compl_handler(ishtp_dev); 538 } else 539 dev_err(ishtp_dev->devc, "[ishtp-ish]: FW reset failed (%d)\n", 540 rv); 541 } 542 543 /** 544 * _ish_sync_fw_clock() -Sync FW clock with the OS clock 545 * @dev: ishtp device pointer 546 * 547 * Sync FW and OS time 548 */ 549 static void _ish_sync_fw_clock(struct ishtp_device *dev) 550 { 551 static unsigned long prev_sync; 552 uint64_t usec; 553 554 if (prev_sync && jiffies - prev_sync < 20 * HZ) 555 return; 556 557 prev_sync = jiffies; 558 usec = ktime_to_us(ktime_get_boottime()); 559 ipc_send_mng_msg(dev, MNG_SYNC_FW_CLOCK, &usec, sizeof(uint64_t)); 560 } 561 562 /** 563 * recv_ipc() - Receive and process IPC management messages 564 * @dev: ishtp device instance 565 * @doorbell_val: doorbell value 566 * 567 * This function runs in ISR context. 568 * NOTE: Any other mng command than reset_notify and reset_notify_ack 569 * won't wake BH handler 570 */ 571 static void recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val) 572 { 573 uint32_t mng_cmd; 574 575 mng_cmd = IPC_HEADER_GET_MNG_CMD(doorbell_val); 576 577 switch (mng_cmd) { 578 default: 579 break; 580 581 case MNG_RX_CMPL_INDICATION: 582 if (dev->suspend_flag) { 583 dev->suspend_flag = 0; 584 wake_up_interruptible(&dev->suspend_wait); 585 } 586 if (dev->resume_flag) { 587 dev->resume_flag = 0; 588 wake_up_interruptible(&dev->resume_wait); 589 } 590 591 write_ipc_from_queue(dev); 592 break; 593 594 case MNG_RESET_NOTIFY: 595 if (!ishtp_dev) { 596 ishtp_dev = dev; 597 INIT_WORK(&fw_reset_work, fw_reset_work_fn); 598 } 599 schedule_work(&fw_reset_work); 600 break; 601 602 case MNG_RESET_NOTIFY_ACK: 603 dev->recvd_hw_ready = 1; 604 wake_up_interruptible(&dev->wait_hw_ready); 605 break; 606 } 607 } 608 609 /** 610 * ish_irq_handler() - ISH IRQ handler 611 * @irq: irq number 612 * @dev_id: ishtp device pointer 613 * 614 * ISH IRQ handler. If interrupt is generated and is for ISH it will process 615 * the interrupt. 616 */ 617 irqreturn_t ish_irq_handler(int irq, void *dev_id) 618 { 619 struct ishtp_device *dev = dev_id; 620 uint32_t doorbell_val; 621 bool interrupt_generated; 622 623 /* Check that it's interrupt from ISH (may be shared) */ 624 interrupt_generated = check_generated_interrupt(dev); 625 626 if (!interrupt_generated) 627 return IRQ_NONE; 628 629 doorbell_val = ish_reg_read(dev, IPC_REG_ISH2HOST_DRBL); 630 if (!IPC_IS_BUSY(doorbell_val)) 631 return IRQ_HANDLED; 632 633 if (dev->dev_state == ISHTP_DEV_DISABLED) 634 return IRQ_HANDLED; 635 636 /* Sanity check: IPC dgram length in header */ 637 if (IPC_HEADER_GET_LENGTH(doorbell_val) > IPC_PAYLOAD_SIZE) { 638 dev_err(dev->devc, 639 "IPC hdr - bad length: %u; dropped\n", 640 (unsigned int)IPC_HEADER_GET_LENGTH(doorbell_val)); 641 goto eoi; 642 } 643 644 switch (IPC_HEADER_GET_PROTOCOL(doorbell_val)) { 645 default: 646 break; 647 case IPC_PROTOCOL_MNG: 648 recv_ipc(dev, doorbell_val); 649 break; 650 case IPC_PROTOCOL_ISHTP: 651 ishtp_recv(dev); 652 break; 653 } 654 655 eoi: 656 /* Update IPC counters */ 657 ++dev->ipc_rx_cnt; 658 dev->ipc_rx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val); 659 660 ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0); 661 /* Flush write to doorbell */ 662 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 663 664 return IRQ_HANDLED; 665 } 666 667 /** 668 * ish_disable_dma() - disable dma communication between host and ISHFW 669 * @dev: ishtp device pointer 670 * 671 * Clear the dma enable bit and wait for dma inactive. 672 * 673 * Return: 0 for success else error code. 674 */ 675 static int ish_disable_dma(struct ishtp_device *dev) 676 { 677 unsigned int dma_delay; 678 679 /* Clear the dma enable bit */ 680 ish_reg_write(dev, IPC_REG_ISH_RMP2, 0); 681 682 /* wait for dma inactive */ 683 for (dma_delay = 0; dma_delay < MAX_DMA_DELAY && 684 _ish_read_fw_sts_reg(dev) & (IPC_ISH_IN_DMA); 685 dma_delay += 5) 686 mdelay(5); 687 688 if (dma_delay >= MAX_DMA_DELAY) { 689 dev_err(dev->devc, 690 "Wait for DMA inactive timeout\n"); 691 return -EBUSY; 692 } 693 694 return 0; 695 } 696 697 /** 698 * ish_wakeup() - wakeup ishfw from waiting-for-host state 699 * @dev: ishtp device pointer 700 * 701 * Set the dma enable bit and send a void message to FW, 702 * it wil wakeup FW from waiting-for-host state. 703 */ 704 static void ish_wakeup(struct ishtp_device *dev) 705 { 706 /* Set dma enable bit */ 707 ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED); 708 709 /* 710 * Send 0 IPC message so that ISH FW wakes up if it was already 711 * asleep. 712 */ 713 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT); 714 715 /* Flush writes to doorbell and REMAP2 */ 716 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 717 } 718 719 /** 720 * _ish_hw_reset() - HW reset 721 * @dev: ishtp device pointer 722 * 723 * Reset ISH HW to recover if any error 724 * 725 * Return: 0 for success else error fault code 726 */ 727 static int _ish_hw_reset(struct ishtp_device *dev) 728 { 729 struct pci_dev *pdev = dev->pdev; 730 int rv; 731 uint16_t csr; 732 733 if (!pdev) 734 return -ENODEV; 735 736 rv = pci_reset_function(pdev); 737 if (!rv) 738 dev->dev_state = ISHTP_DEV_RESETTING; 739 740 if (!pdev->pm_cap) { 741 dev_err(&pdev->dev, "Can't reset - no PM caps\n"); 742 return -EINVAL; 743 } 744 745 /* Disable dma communication between FW and host */ 746 if (ish_disable_dma(dev)) { 747 dev_err(&pdev->dev, 748 "Can't reset - stuck with DMA in-progress\n"); 749 return -EBUSY; 750 } 751 752 pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &csr); 753 754 csr &= ~PCI_PM_CTRL_STATE_MASK; 755 csr |= PCI_D3hot; 756 pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr); 757 758 mdelay(pdev->d3_delay); 759 760 csr &= ~PCI_PM_CTRL_STATE_MASK; 761 csr |= PCI_D0; 762 pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr); 763 764 /* Now we can enable ISH DMA operation and wakeup ISHFW */ 765 ish_wakeup(dev); 766 767 return 0; 768 } 769 770 /** 771 * _ish_ipc_reset() - IPC reset 772 * @dev: ishtp device pointer 773 * 774 * Resets host and fw IPC and upper layers 775 * 776 * Return: 0 for success else error fault code 777 */ 778 static int _ish_ipc_reset(struct ishtp_device *dev) 779 { 780 struct ipc_rst_payload_type ipc_mng_msg; 781 int rv = 0; 782 783 ipc_mng_msg.reset_id = 1; 784 ipc_mng_msg.reserved = 0; 785 786 set_host_ready(dev); 787 788 /* Clear the incoming doorbell */ 789 ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0); 790 /* Flush write to doorbell */ 791 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS); 792 793 dev->recvd_hw_ready = 0; 794 795 /* send message */ 796 rv = ipc_send_mng_msg(dev, MNG_RESET_NOTIFY, &ipc_mng_msg, 797 sizeof(struct ipc_rst_payload_type)); 798 if (rv) { 799 dev_err(dev->devc, "Failed to send IPC MNG_RESET_NOTIFY\n"); 800 return rv; 801 } 802 803 wait_event_interruptible_timeout(dev->wait_hw_ready, 804 dev->recvd_hw_ready, 2 * HZ); 805 if (!dev->recvd_hw_ready) { 806 dev_err(dev->devc, "Timed out waiting for HW ready\n"); 807 rv = -ENODEV; 808 } 809 810 return rv; 811 } 812 813 /** 814 * ish_hw_start() -Start ISH HW 815 * @dev: ishtp device pointer 816 * 817 * Set host to ready state and wait for FW reset 818 * 819 * Return: 0 for success else error fault code 820 */ 821 int ish_hw_start(struct ishtp_device *dev) 822 { 823 ish_set_host_rdy(dev); 824 825 set_host_ready(dev); 826 827 /* After that we can enable ISH DMA operation and wakeup ISHFW */ 828 ish_wakeup(dev); 829 830 /* wait for FW-initiated reset flow */ 831 if (!dev->recvd_hw_ready) 832 wait_event_interruptible_timeout(dev->wait_hw_ready, 833 dev->recvd_hw_ready, 834 10 * HZ); 835 836 if (!dev->recvd_hw_ready) { 837 dev_err(dev->devc, 838 "[ishtp-ish]: Timed out waiting for FW-initiated reset\n"); 839 return -ENODEV; 840 } 841 842 return 0; 843 } 844 845 /** 846 * ish_ipc_get_header() -Get doorbell value 847 * @dev: ishtp device pointer 848 * @length: length of message 849 * @busy: busy status 850 * 851 * Get door bell value from message header 852 * 853 * Return: door bell value 854 */ 855 static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length, 856 int busy) 857 { 858 uint32_t drbl_val; 859 860 drbl_val = IPC_BUILD_HEADER(length, IPC_PROTOCOL_ISHTP, busy); 861 862 return drbl_val; 863 } 864 865 static const struct ishtp_hw_ops ish_hw_ops = { 866 .hw_reset = _ish_hw_reset, 867 .ipc_reset = _ish_ipc_reset, 868 .ipc_get_header = ish_ipc_get_header, 869 .ishtp_read = _ishtp_read, 870 .write = write_ipc_to_queue, 871 .get_fw_status = _ish_read_fw_sts_reg, 872 .sync_fw_clock = _ish_sync_fw_clock, 873 .ishtp_read_hdr = _ishtp_read_hdr 874 }; 875 876 /** 877 * ish_dev_init() -Initialize ISH devoce 878 * @pdev: PCI device 879 * 880 * Allocate ISHTP device and initialize IPC processing 881 * 882 * Return: ISHTP device instance on success else NULL 883 */ 884 struct ishtp_device *ish_dev_init(struct pci_dev *pdev) 885 { 886 struct ishtp_device *dev; 887 int i; 888 889 dev = devm_kzalloc(&pdev->dev, 890 sizeof(struct ishtp_device) + sizeof(struct ish_hw), 891 GFP_KERNEL); 892 if (!dev) 893 return NULL; 894 895 ishtp_device_init(dev); 896 897 init_waitqueue_head(&dev->wait_hw_ready); 898 899 spin_lock_init(&dev->wr_processing_spinlock); 900 901 /* Init IPC processing and free lists */ 902 INIT_LIST_HEAD(&dev->wr_processing_list); 903 INIT_LIST_HEAD(&dev->wr_free_list); 904 for (i = 0; i < IPC_TX_FIFO_SIZE; i++) { 905 struct wr_msg_ctl_info *tx_buf; 906 907 tx_buf = devm_kzalloc(&pdev->dev, 908 sizeof(struct wr_msg_ctl_info), 909 GFP_KERNEL); 910 if (!tx_buf) { 911 /* 912 * IPC buffers may be limited or not available 913 * at all - although this shouldn't happen 914 */ 915 dev_err(dev->devc, 916 "[ishtp-ish]: failure in Tx FIFO allocations (%d)\n", 917 i); 918 break; 919 } 920 list_add_tail(&tx_buf->link, &dev->wr_free_list); 921 } 922 923 dev->ops = &ish_hw_ops; 924 dev->devc = &pdev->dev; 925 dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr); 926 return dev; 927 } 928 929 /** 930 * ish_device_disable() - Disable ISH device 931 * @dev: ISHTP device pointer 932 * 933 * Disable ISH by clearing host ready to inform firmware. 934 */ 935 void ish_device_disable(struct ishtp_device *dev) 936 { 937 struct pci_dev *pdev = dev->pdev; 938 939 if (!pdev) 940 return; 941 942 /* Disable dma communication between FW and host */ 943 if (ish_disable_dma(dev)) { 944 dev_err(&pdev->dev, 945 "Can't reset - stuck with DMA in-progress\n"); 946 return; 947 } 948 949 /* Put ISH to D3hot state for power saving */ 950 pci_set_power_state(pdev, PCI_D3hot); 951 952 dev->dev_state = ISHTP_DEV_DISABLED; 953 ish_clr_host_rdy(dev); 954 } 955