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