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