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