0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/sched.h>
0009 #include <linux/spinlock.h>
0010 #include <linux/delay.h>
0011 #include <linux/jiffies.h>
0012 #include "client.h"
0013 #include "hw-ish.h"
0014 #include "hbm.h"
0015
0016
0017 static struct work_struct fw_reset_work;
0018 static struct ishtp_device *ishtp_dev;
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 static inline uint32_t ish_reg_read(const struct ishtp_device *dev,
0030 unsigned long offset)
0031 {
0032 struct ish_hw *hw = to_ish_hw(dev);
0033
0034 return readl(hw->mem_addr + offset);
0035 }
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 static inline void ish_reg_write(struct ishtp_device *dev,
0046 unsigned long offset,
0047 uint32_t value)
0048 {
0049 struct ish_hw *hw = to_ish_hw(dev);
0050
0051 writel(value, hw->mem_addr + offset);
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 static inline uint32_t _ish_read_fw_sts_reg(struct ishtp_device *dev)
0063 {
0064 return ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
0065 }
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 static bool check_generated_interrupt(struct ishtp_device *dev)
0076 {
0077 bool interrupt_generated = true;
0078 uint32_t pisr_val = 0;
0079
0080 if (dev->pdev->device == CHV_DEVICE_ID) {
0081 pisr_val = ish_reg_read(dev, IPC_REG_PISR_CHV_AB);
0082 interrupt_generated =
0083 IPC_INT_FROM_ISH_TO_HOST_CHV_AB(pisr_val);
0084 } else {
0085 pisr_val = ish_reg_read(dev, IPC_REG_PISR_BXT);
0086 interrupt_generated = !!pisr_val;
0087
0088 if (pisr_val)
0089 ish_reg_write(dev, IPC_REG_PISR_BXT, pisr_val);
0090 }
0091
0092 return interrupt_generated;
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 static bool ish_is_input_ready(struct ishtp_device *dev)
0104 {
0105 uint32_t doorbell_val;
0106
0107 doorbell_val = ish_reg_read(dev, IPC_REG_HOST2ISH_DRBL);
0108 return !IPC_IS_BUSY(doorbell_val);
0109 }
0110
0111
0112
0113
0114
0115
0116
0117 static void set_host_ready(struct ishtp_device *dev)
0118 {
0119 if (dev->pdev->device == CHV_DEVICE_ID) {
0120 if (dev->pdev->revision == REVISION_ID_CHT_A0 ||
0121 (dev->pdev->revision & REVISION_ID_SI_MASK) ==
0122 REVISION_ID_CHT_Ax_SI)
0123 ish_reg_write(dev, IPC_REG_HOST_COMM, 0x81);
0124 else if (dev->pdev->revision == REVISION_ID_CHT_B0 ||
0125 (dev->pdev->revision & REVISION_ID_SI_MASK) ==
0126 REVISION_ID_CHT_Bx_SI ||
0127 (dev->pdev->revision & REVISION_ID_SI_MASK) ==
0128 REVISION_ID_CHT_Kx_SI ||
0129 (dev->pdev->revision & REVISION_ID_SI_MASK) ==
0130 REVISION_ID_CHT_Dx_SI) {
0131 uint32_t host_comm_val;
0132
0133 host_comm_val = ish_reg_read(dev, IPC_REG_HOST_COMM);
0134 host_comm_val |= IPC_HOSTCOMM_INT_EN_BIT_CHV_AB | 0x81;
0135 ish_reg_write(dev, IPC_REG_HOST_COMM, host_comm_val);
0136 }
0137 } else {
0138 uint32_t host_pimr_val;
0139
0140 host_pimr_val = ish_reg_read(dev, IPC_REG_PIMR_BXT);
0141 host_pimr_val |= IPC_PIMR_INT_EN_BIT_BXT;
0142
0143
0144
0145
0146 host_pimr_val &= ~IPC_HOST2ISH_BUSYCLEAR_MASK_BIT;
0147
0148 ish_reg_write(dev, IPC_REG_PIMR_BXT, host_pimr_val);
0149 }
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160 static bool ishtp_fw_is_ready(struct ishtp_device *dev)
0161 {
0162 uint32_t ish_status = _ish_read_fw_sts_reg(dev);
0163
0164 return IPC_IS_ISH_ILUP(ish_status) &&
0165 IPC_IS_ISH_ISHTP_READY(ish_status);
0166 }
0167
0168
0169
0170
0171
0172
0173
0174 static void ish_set_host_rdy(struct ishtp_device *dev)
0175 {
0176 uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
0177
0178 IPC_SET_HOST_READY(host_status);
0179 ish_reg_write(dev, IPC_REG_HOST_COMM, host_status);
0180 }
0181
0182
0183
0184
0185
0186
0187
0188 static void ish_clr_host_rdy(struct ishtp_device *dev)
0189 {
0190 uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
0191
0192 IPC_CLEAR_HOST_READY(host_status);
0193 ish_reg_write(dev, IPC_REG_HOST_COMM, host_status);
0194 }
0195
0196 static bool ish_chk_host_rdy(struct ishtp_device *dev)
0197 {
0198 uint32_t host_status = ish_reg_read(dev, IPC_REG_HOST_COMM);
0199
0200 return (host_status & IPC_HOSTCOMM_READY_BIT);
0201 }
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 void ish_set_host_ready(struct ishtp_device *dev)
0215 {
0216 if (ish_chk_host_rdy(dev))
0217 return;
0218
0219 ish_set_host_rdy(dev);
0220 set_host_ready(dev);
0221 }
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 static uint32_t _ishtp_read_hdr(const struct ishtp_device *dev)
0232 {
0233 return ish_reg_read(dev, IPC_REG_ISH2HOST_MSG);
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 static int _ishtp_read(struct ishtp_device *dev, unsigned char *buffer,
0247 unsigned long buffer_length)
0248 {
0249 uint32_t i;
0250 uint32_t *r_buf = (uint32_t *)buffer;
0251 uint32_t msg_offs;
0252
0253 msg_offs = IPC_REG_ISH2HOST_MSG + sizeof(struct ishtp_msg_hdr);
0254 for (i = 0; i < buffer_length; i += sizeof(uint32_t))
0255 *r_buf++ = ish_reg_read(dev, msg_offs + i);
0256
0257 return 0;
0258 }
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 static int write_ipc_from_queue(struct ishtp_device *dev)
0270 {
0271 struct wr_msg_ctl_info *ipc_link;
0272 unsigned long length;
0273 unsigned long rem;
0274 unsigned long flags;
0275 uint32_t doorbell_val;
0276 uint32_t *r_buf;
0277 uint32_t reg_addr;
0278 int i;
0279 void (*ipc_send_compl)(void *);
0280 void *ipc_send_compl_prm;
0281
0282 if (dev->dev_state == ISHTP_DEV_DISABLED)
0283 return -EINVAL;
0284
0285 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
0286 if (!ish_is_input_ready(dev)) {
0287 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0288 return -EBUSY;
0289 }
0290
0291
0292
0293
0294
0295 if (list_empty(&dev->wr_processing_list)) {
0296 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0297 return 0;
0298 }
0299
0300 ipc_link = list_first_entry(&dev->wr_processing_list,
0301 struct wr_msg_ctl_info, link);
0302
0303 length = ipc_link->length - sizeof(uint32_t);
0304 doorbell_val = *(uint32_t *)ipc_link->inline_data;
0305 r_buf = (uint32_t *)(ipc_link->inline_data + sizeof(uint32_t));
0306
0307
0308 if (IPC_HEADER_GET_PROTOCOL(doorbell_val) == IPC_PROTOCOL_MNG &&
0309 IPC_HEADER_GET_MNG_CMD(doorbell_val) == MNG_SYNC_FW_CLOCK) {
0310 uint64_t usec_system, usec_utc;
0311 struct ipc_time_update_msg time_update;
0312 struct time_sync_format ts_format;
0313
0314 usec_system = ktime_to_us(ktime_get_boottime());
0315 usec_utc = ktime_to_us(ktime_get_real());
0316 ts_format.ts1_source = HOST_SYSTEM_TIME_USEC;
0317 ts_format.ts2_source = HOST_UTC_TIME_USEC;
0318 ts_format.reserved = 0;
0319
0320 time_update.primary_host_time = usec_system;
0321 time_update.secondary_host_time = usec_utc;
0322 time_update.sync_info = ts_format;
0323
0324 memcpy(r_buf, &time_update,
0325 sizeof(struct ipc_time_update_msg));
0326 }
0327
0328 for (i = 0, reg_addr = IPC_REG_HOST2ISH_MSG; i < length >> 2; i++,
0329 reg_addr += 4)
0330 ish_reg_write(dev, reg_addr, r_buf[i]);
0331
0332 rem = length & 0x3;
0333 if (rem > 0) {
0334 uint32_t reg = 0;
0335
0336 memcpy(®, &r_buf[length >> 2], rem);
0337 ish_reg_write(dev, reg_addr, reg);
0338 }
0339 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, doorbell_val);
0340
0341
0342 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
0343
0344
0345 ++dev->ipc_tx_cnt;
0346 dev->ipc_tx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
0347
0348 ipc_send_compl = ipc_link->ipc_send_compl;
0349 ipc_send_compl_prm = ipc_link->ipc_send_compl_prm;
0350 list_del_init(&ipc_link->link);
0351 list_add(&ipc_link->link, &dev->wr_free_list);
0352 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0353
0354
0355
0356
0357
0358 if (ipc_send_compl)
0359 ipc_send_compl(ipc_send_compl_prm);
0360
0361 return 0;
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static int write_ipc_to_queue(struct ishtp_device *dev,
0381 void (*ipc_send_compl)(void *), void *ipc_send_compl_prm,
0382 unsigned char *msg, int length)
0383 {
0384 struct wr_msg_ctl_info *ipc_link;
0385 unsigned long flags;
0386
0387 if (length > IPC_FULL_MSG_SIZE)
0388 return -EMSGSIZE;
0389
0390 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
0391 if (list_empty(&dev->wr_free_list)) {
0392 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0393 return -ENOMEM;
0394 }
0395 ipc_link = list_first_entry(&dev->wr_free_list,
0396 struct wr_msg_ctl_info, link);
0397 list_del_init(&ipc_link->link);
0398
0399 ipc_link->ipc_send_compl = ipc_send_compl;
0400 ipc_link->ipc_send_compl_prm = ipc_send_compl_prm;
0401 ipc_link->length = length;
0402 memcpy(ipc_link->inline_data, msg, length);
0403
0404 list_add_tail(&ipc_link->link, &dev->wr_processing_list);
0405 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0406
0407 write_ipc_from_queue(dev);
0408
0409 return 0;
0410 }
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423 static int ipc_send_mng_msg(struct ishtp_device *dev, uint32_t msg_code,
0424 void *msg, size_t size)
0425 {
0426 unsigned char ipc_msg[IPC_FULL_MSG_SIZE];
0427 uint32_t drbl_val = IPC_BUILD_MNG_MSG(msg_code, size);
0428
0429 memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
0430 memcpy(ipc_msg + sizeof(uint32_t), msg, size);
0431 return write_ipc_to_queue(dev, NULL, NULL, ipc_msg,
0432 sizeof(uint32_t) + size);
0433 }
0434
0435 #define WAIT_FOR_FW_RDY 0x1
0436 #define WAIT_FOR_INPUT_RDY 0x2
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450 static int timed_wait_for_timeout(struct ishtp_device *dev, int condition,
0451 unsigned int timeinc, unsigned int timeout)
0452 {
0453 bool complete = false;
0454 int ret;
0455
0456 do {
0457 if (condition == WAIT_FOR_FW_RDY) {
0458 complete = ishtp_fw_is_ready(dev);
0459 } else if (condition == WAIT_FOR_INPUT_RDY) {
0460 complete = ish_is_input_ready(dev);
0461 } else {
0462 ret = -EINVAL;
0463 goto out;
0464 }
0465
0466 if (!complete) {
0467 unsigned long left_time;
0468
0469 left_time = msleep_interruptible(timeinc);
0470 timeout -= (timeinc - left_time);
0471 }
0472 } while (!complete && timeout > 0);
0473
0474 if (complete)
0475 ret = 0;
0476 else
0477 ret = -EBUSY;
0478
0479 out:
0480 return ret;
0481 }
0482
0483 #define TIME_SLICE_FOR_FW_RDY_MS 100
0484 #define TIME_SLICE_FOR_INPUT_RDY_MS 100
0485 #define TIMEOUT_FOR_FW_RDY_MS 2000
0486 #define TIMEOUT_FOR_INPUT_RDY_MS 2000
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496 static int ish_fw_reset_handler(struct ishtp_device *dev)
0497 {
0498 uint32_t reset_id;
0499 unsigned long flags;
0500
0501
0502 reset_id = ish_reg_read(dev, IPC_REG_ISH2HOST_MSG) & 0xFFFF;
0503
0504
0505 spin_lock_irqsave(&dev->wr_processing_spinlock, flags);
0506 list_splice_init(&dev->wr_processing_list, &dev->wr_free_list);
0507 spin_unlock_irqrestore(&dev->wr_processing_spinlock, flags);
0508
0509
0510 ishtp_reset_handler(dev);
0511
0512 if (!ish_is_input_ready(dev))
0513 timed_wait_for_timeout(dev, WAIT_FOR_INPUT_RDY,
0514 TIME_SLICE_FOR_INPUT_RDY_MS, TIMEOUT_FOR_INPUT_RDY_MS);
0515
0516
0517 if (!ish_is_input_ready(dev))
0518 return -EPIPE;
0519
0520
0521
0522
0523 ish_set_host_rdy(dev);
0524
0525 ipc_send_mng_msg(dev, MNG_RESET_NOTIFY_ACK, &reset_id,
0526 sizeof(uint32_t));
0527
0528
0529 timed_wait_for_timeout(dev, WAIT_FOR_FW_RDY,
0530 TIME_SLICE_FOR_FW_RDY_MS, TIMEOUT_FOR_FW_RDY_MS);
0531 if (!ishtp_fw_is_ready(dev)) {
0532
0533 uint32_t ish_status;
0534
0535 ish_status = _ish_read_fw_sts_reg(dev);
0536 dev_err(dev->devc,
0537 "[ishtp-ish]: completed reset, ISH is dead (FWSTS = %08X)\n",
0538 ish_status);
0539 return -ENODEV;
0540 }
0541 return 0;
0542 }
0543
0544 #define TIMEOUT_FOR_HW_RDY_MS 300
0545
0546
0547
0548
0549
0550
0551
0552 static void fw_reset_work_fn(struct work_struct *unused)
0553 {
0554 int rv;
0555
0556 rv = ish_fw_reset_handler(ishtp_dev);
0557 if (!rv) {
0558
0559 msleep_interruptible(TIMEOUT_FOR_HW_RDY_MS);
0560 ishtp_dev->recvd_hw_ready = 1;
0561 wake_up_interruptible(&ishtp_dev->wait_hw_ready);
0562
0563
0564 ishtp_reset_compl_handler(ishtp_dev);
0565 } else
0566 dev_err(ishtp_dev->devc, "[ishtp-ish]: FW reset failed (%d)\n",
0567 rv);
0568 }
0569
0570
0571
0572
0573
0574
0575
0576 static void _ish_sync_fw_clock(struct ishtp_device *dev)
0577 {
0578 static unsigned long prev_sync;
0579 uint64_t usec;
0580
0581 if (prev_sync && time_before(jiffies, prev_sync + 20 * HZ))
0582 return;
0583
0584 prev_sync = jiffies;
0585 usec = ktime_to_us(ktime_get_boottime());
0586 ipc_send_mng_msg(dev, MNG_SYNC_FW_CLOCK, &usec, sizeof(uint64_t));
0587 }
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598 static void recv_ipc(struct ishtp_device *dev, uint32_t doorbell_val)
0599 {
0600 uint32_t mng_cmd;
0601
0602 mng_cmd = IPC_HEADER_GET_MNG_CMD(doorbell_val);
0603
0604 switch (mng_cmd) {
0605 default:
0606 break;
0607
0608 case MNG_RX_CMPL_INDICATION:
0609 if (dev->suspend_flag) {
0610 dev->suspend_flag = 0;
0611 wake_up_interruptible(&dev->suspend_wait);
0612 }
0613 if (dev->resume_flag) {
0614 dev->resume_flag = 0;
0615 wake_up_interruptible(&dev->resume_wait);
0616 }
0617
0618 write_ipc_from_queue(dev);
0619 break;
0620
0621 case MNG_RESET_NOTIFY:
0622 if (!ishtp_dev) {
0623 ishtp_dev = dev;
0624 INIT_WORK(&fw_reset_work, fw_reset_work_fn);
0625 }
0626 schedule_work(&fw_reset_work);
0627 break;
0628
0629 case MNG_RESET_NOTIFY_ACK:
0630 dev->recvd_hw_ready = 1;
0631 wake_up_interruptible(&dev->wait_hw_ready);
0632 break;
0633 }
0634 }
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644 irqreturn_t ish_irq_handler(int irq, void *dev_id)
0645 {
0646 struct ishtp_device *dev = dev_id;
0647 uint32_t doorbell_val;
0648 bool interrupt_generated;
0649
0650
0651 interrupt_generated = check_generated_interrupt(dev);
0652
0653 if (!interrupt_generated)
0654 return IRQ_NONE;
0655
0656 doorbell_val = ish_reg_read(dev, IPC_REG_ISH2HOST_DRBL);
0657 if (!IPC_IS_BUSY(doorbell_val))
0658 return IRQ_HANDLED;
0659
0660 if (dev->dev_state == ISHTP_DEV_DISABLED)
0661 return IRQ_HANDLED;
0662
0663
0664 if (IPC_HEADER_GET_LENGTH(doorbell_val) > IPC_PAYLOAD_SIZE) {
0665 dev_err(dev->devc,
0666 "IPC hdr - bad length: %u; dropped\n",
0667 (unsigned int)IPC_HEADER_GET_LENGTH(doorbell_val));
0668 goto eoi;
0669 }
0670
0671 switch (IPC_HEADER_GET_PROTOCOL(doorbell_val)) {
0672 default:
0673 break;
0674 case IPC_PROTOCOL_MNG:
0675 recv_ipc(dev, doorbell_val);
0676 break;
0677 case IPC_PROTOCOL_ISHTP:
0678 ishtp_recv(dev);
0679 break;
0680 }
0681
0682 eoi:
0683
0684 ++dev->ipc_rx_cnt;
0685 dev->ipc_rx_bytes_cnt += IPC_HEADER_GET_LENGTH(doorbell_val);
0686
0687 ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0);
0688
0689 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
0690
0691 return IRQ_HANDLED;
0692 }
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 int ish_disable_dma(struct ishtp_device *dev)
0703 {
0704 unsigned int dma_delay;
0705
0706
0707 ish_reg_write(dev, IPC_REG_ISH_RMP2, 0);
0708
0709
0710 for (dma_delay = 0; dma_delay < MAX_DMA_DELAY &&
0711 _ish_read_fw_sts_reg(dev) & (IPC_ISH_IN_DMA);
0712 dma_delay += 5)
0713 mdelay(5);
0714
0715 if (dma_delay >= MAX_DMA_DELAY) {
0716 dev_err(dev->devc,
0717 "Wait for DMA inactive timeout\n");
0718 return -EBUSY;
0719 }
0720
0721 return 0;
0722 }
0723
0724
0725
0726
0727
0728
0729
0730
0731 static void ish_wakeup(struct ishtp_device *dev)
0732 {
0733
0734 ish_reg_write(dev, IPC_REG_ISH_RMP2, IPC_RMP2_DMA_ENABLED);
0735
0736
0737
0738
0739
0740 ish_reg_write(dev, IPC_REG_HOST2ISH_DRBL, IPC_DRBL_BUSY_BIT);
0741
0742
0743 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
0744 }
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754 static int _ish_hw_reset(struct ishtp_device *dev)
0755 {
0756 struct pci_dev *pdev = dev->pdev;
0757 int rv;
0758 uint16_t csr;
0759
0760 if (!pdev)
0761 return -ENODEV;
0762
0763 rv = pci_reset_function(pdev);
0764 if (!rv)
0765 dev->dev_state = ISHTP_DEV_RESETTING;
0766
0767 if (!pdev->pm_cap) {
0768 dev_err(&pdev->dev, "Can't reset - no PM caps\n");
0769 return -EINVAL;
0770 }
0771
0772
0773 if (ish_disable_dma(dev)) {
0774 dev_err(&pdev->dev,
0775 "Can't reset - stuck with DMA in-progress\n");
0776 return -EBUSY;
0777 }
0778
0779 pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &csr);
0780
0781 csr &= ~PCI_PM_CTRL_STATE_MASK;
0782 csr |= PCI_D3hot;
0783 pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
0784
0785 mdelay(pdev->d3hot_delay);
0786
0787 csr &= ~PCI_PM_CTRL_STATE_MASK;
0788 csr |= PCI_D0;
0789 pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
0790
0791
0792 ish_wakeup(dev);
0793
0794 return 0;
0795 }
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805 static int _ish_ipc_reset(struct ishtp_device *dev)
0806 {
0807 struct ipc_rst_payload_type ipc_mng_msg;
0808 int rv = 0;
0809
0810 ipc_mng_msg.reset_id = 1;
0811 ipc_mng_msg.reserved = 0;
0812
0813 set_host_ready(dev);
0814
0815
0816 ish_reg_write(dev, IPC_REG_ISH2HOST_DRBL, 0);
0817
0818 ish_reg_read(dev, IPC_REG_ISH_HOST_FWSTS);
0819
0820 dev->recvd_hw_ready = 0;
0821
0822
0823 rv = ipc_send_mng_msg(dev, MNG_RESET_NOTIFY, &ipc_mng_msg,
0824 sizeof(struct ipc_rst_payload_type));
0825 if (rv) {
0826 dev_err(dev->devc, "Failed to send IPC MNG_RESET_NOTIFY\n");
0827 return rv;
0828 }
0829
0830 wait_event_interruptible_timeout(dev->wait_hw_ready,
0831 dev->recvd_hw_ready, 2 * HZ);
0832 if (!dev->recvd_hw_ready) {
0833 dev_err(dev->devc, "Timed out waiting for HW ready\n");
0834 rv = -ENODEV;
0835 }
0836
0837 return rv;
0838 }
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848 int ish_hw_start(struct ishtp_device *dev)
0849 {
0850 ish_set_host_rdy(dev);
0851
0852 set_host_ready(dev);
0853
0854
0855 ish_wakeup(dev);
0856
0857
0858 if (!dev->recvd_hw_ready)
0859 wait_event_interruptible_timeout(dev->wait_hw_ready,
0860 dev->recvd_hw_ready,
0861 10 * HZ);
0862
0863 if (!dev->recvd_hw_ready) {
0864 dev_err(dev->devc,
0865 "[ishtp-ish]: Timed out waiting for FW-initiated reset\n");
0866 return -ENODEV;
0867 }
0868
0869 return 0;
0870 }
0871
0872
0873
0874
0875
0876
0877
0878
0879
0880
0881
0882 static uint32_t ish_ipc_get_header(struct ishtp_device *dev, int length,
0883 int busy)
0884 {
0885 uint32_t drbl_val;
0886
0887 drbl_val = IPC_BUILD_HEADER(length, IPC_PROTOCOL_ISHTP, busy);
0888
0889 return drbl_val;
0890 }
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910 static bool _dma_no_cache_snooping(struct ishtp_device *dev)
0911 {
0912 return (dev->pdev->device == EHL_Ax_DEVICE_ID ||
0913 dev->pdev->device == TGL_LP_DEVICE_ID ||
0914 dev->pdev->device == TGL_H_DEVICE_ID ||
0915 dev->pdev->device == ADL_S_DEVICE_ID ||
0916 dev->pdev->device == ADL_P_DEVICE_ID);
0917 }
0918
0919 static const struct ishtp_hw_ops ish_hw_ops = {
0920 .hw_reset = _ish_hw_reset,
0921 .ipc_reset = _ish_ipc_reset,
0922 .ipc_get_header = ish_ipc_get_header,
0923 .ishtp_read = _ishtp_read,
0924 .write = write_ipc_to_queue,
0925 .get_fw_status = _ish_read_fw_sts_reg,
0926 .sync_fw_clock = _ish_sync_fw_clock,
0927 .ishtp_read_hdr = _ishtp_read_hdr,
0928 .dma_no_cache_snooping = _dma_no_cache_snooping
0929 };
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939 struct ishtp_device *ish_dev_init(struct pci_dev *pdev)
0940 {
0941 struct ishtp_device *dev;
0942 int i;
0943
0944 dev = devm_kzalloc(&pdev->dev,
0945 sizeof(struct ishtp_device) + sizeof(struct ish_hw),
0946 GFP_KERNEL);
0947 if (!dev)
0948 return NULL;
0949
0950 ishtp_device_init(dev);
0951
0952 init_waitqueue_head(&dev->wait_hw_ready);
0953
0954 spin_lock_init(&dev->wr_processing_spinlock);
0955
0956
0957 INIT_LIST_HEAD(&dev->wr_processing_list);
0958 INIT_LIST_HEAD(&dev->wr_free_list);
0959 for (i = 0; i < IPC_TX_FIFO_SIZE; i++) {
0960 struct wr_msg_ctl_info *tx_buf;
0961
0962 tx_buf = devm_kzalloc(&pdev->dev,
0963 sizeof(struct wr_msg_ctl_info),
0964 GFP_KERNEL);
0965 if (!tx_buf) {
0966
0967
0968
0969
0970 dev_err(dev->devc,
0971 "[ishtp-ish]: failure in Tx FIFO allocations (%d)\n",
0972 i);
0973 break;
0974 }
0975 list_add_tail(&tx_buf->link, &dev->wr_free_list);
0976 }
0977
0978 dev->ops = &ish_hw_ops;
0979 dev->devc = &pdev->dev;
0980 dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
0981 return dev;
0982 }
0983
0984
0985
0986
0987
0988
0989
0990 void ish_device_disable(struct ishtp_device *dev)
0991 {
0992 struct pci_dev *pdev = dev->pdev;
0993
0994 if (!pdev)
0995 return;
0996
0997
0998 if (ish_disable_dma(dev)) {
0999 dev_err(&pdev->dev,
1000 "Can't reset - stuck with DMA in-progress\n");
1001 return;
1002 }
1003
1004
1005 pci_set_power_state(pdev, PCI_D3hot);
1006
1007 dev->dev_state = ISHTP_DEV_DISABLED;
1008 ish_clr_host_rdy(dev);
1009 }