0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include <linux/acpi.h>
0050 #include <linux/delay.h>
0051 #include <linux/io.h>
0052 #include <linux/init.h>
0053 #include <linux/interrupt.h>
0054 #include <linux/list.h>
0055 #include <linux/log2.h>
0056 #include <linux/platform_device.h>
0057 #include <linux/mailbox_controller.h>
0058 #include <linux/mailbox_client.h>
0059 #include <linux/io-64-nonatomic-lo-hi.h>
0060 #include <acpi/pcc.h>
0061
0062 #include "mailbox.h"
0063
0064 #define MBOX_IRQ_NAME "pcc-mbox"
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 struct pcc_chan_reg {
0076 void __iomem *vaddr;
0077 struct acpi_generic_address *gas;
0078 u64 preserve_mask;
0079 u64 set_mask;
0080 u64 status_mask;
0081 };
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 struct pcc_chan_info {
0096 struct pcc_mbox_chan chan;
0097 struct pcc_chan_reg db;
0098 struct pcc_chan_reg plat_irq_ack;
0099 struct pcc_chan_reg cmd_complete;
0100 struct pcc_chan_reg cmd_update;
0101 struct pcc_chan_reg error;
0102 int plat_irq;
0103 };
0104
0105 #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan)
0106 static struct pcc_chan_info *chan_info;
0107 static int pcc_chan_count;
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 static void read_register(void __iomem *vaddr, u64 *val, unsigned int bit_width)
0118 {
0119 switch (bit_width) {
0120 case 8:
0121 *val = readb(vaddr);
0122 break;
0123 case 16:
0124 *val = readw(vaddr);
0125 break;
0126 case 32:
0127 *val = readl(vaddr);
0128 break;
0129 case 64:
0130 *val = readq(vaddr);
0131 break;
0132 }
0133 }
0134
0135 static void write_register(void __iomem *vaddr, u64 val, unsigned int bit_width)
0136 {
0137 switch (bit_width) {
0138 case 8:
0139 writeb(val, vaddr);
0140 break;
0141 case 16:
0142 writew(val, vaddr);
0143 break;
0144 case 32:
0145 writel(val, vaddr);
0146 break;
0147 case 64:
0148 writeq(val, vaddr);
0149 break;
0150 }
0151 }
0152
0153 static int pcc_chan_reg_read(struct pcc_chan_reg *reg, u64 *val)
0154 {
0155 int ret = 0;
0156
0157 if (!reg->gas) {
0158 *val = 0;
0159 return 0;
0160 }
0161
0162 if (reg->vaddr)
0163 read_register(reg->vaddr, val, reg->gas->bit_width);
0164 else
0165 ret = acpi_read(val, reg->gas);
0166
0167 return ret;
0168 }
0169
0170 static int pcc_chan_reg_write(struct pcc_chan_reg *reg, u64 val)
0171 {
0172 int ret = 0;
0173
0174 if (!reg->gas)
0175 return 0;
0176
0177 if (reg->vaddr)
0178 write_register(reg->vaddr, val, reg->gas->bit_width);
0179 else
0180 ret = acpi_write(val, reg->gas);
0181
0182 return ret;
0183 }
0184
0185 static int pcc_chan_reg_read_modify_write(struct pcc_chan_reg *reg)
0186 {
0187 int ret = 0;
0188 u64 val;
0189
0190 ret = pcc_chan_reg_read(reg, &val);
0191 if (ret)
0192 return ret;
0193
0194 val &= reg->preserve_mask;
0195 val |= reg->set_mask;
0196
0197 return pcc_chan_reg_write(reg, val);
0198 }
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 static int pcc_map_interrupt(u32 interrupt, u32 flags)
0209 {
0210 int trigger, polarity;
0211
0212 if (!interrupt)
0213 return 0;
0214
0215 trigger = (flags & ACPI_PCCT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
0216 : ACPI_LEVEL_SENSITIVE;
0217
0218 polarity = (flags & ACPI_PCCT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
0219 : ACPI_ACTIVE_HIGH;
0220
0221 return acpi_register_gsi(NULL, interrupt, trigger, polarity);
0222 }
0223
0224
0225
0226
0227
0228
0229
0230
0231 static irqreturn_t pcc_mbox_irq(int irq, void *p)
0232 {
0233 struct pcc_chan_info *pchan;
0234 struct mbox_chan *chan = p;
0235 u64 val;
0236 int ret;
0237
0238 pchan = chan->con_priv;
0239
0240 ret = pcc_chan_reg_read(&pchan->cmd_complete, &val);
0241 if (ret)
0242 return IRQ_NONE;
0243
0244 if (val) {
0245 val &= pchan->cmd_complete.status_mask;
0246 if (!val)
0247 return IRQ_NONE;
0248 }
0249
0250 ret = pcc_chan_reg_read(&pchan->error, &val);
0251 if (ret)
0252 return IRQ_NONE;
0253 val &= pchan->error.status_mask;
0254 if (val) {
0255 val &= ~pchan->error.status_mask;
0256 pcc_chan_reg_write(&pchan->error, val);
0257 return IRQ_NONE;
0258 }
0259
0260 if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
0261 return IRQ_NONE;
0262
0263 mbox_chan_received_data(chan, NULL);
0264
0265 return IRQ_HANDLED;
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280 struct pcc_mbox_chan *
0281 pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
0282 {
0283 struct pcc_chan_info *pchan;
0284 struct mbox_chan *chan;
0285 struct device *dev;
0286 unsigned long flags;
0287
0288 if (subspace_id < 0 || subspace_id >= pcc_chan_count)
0289 return ERR_PTR(-ENOENT);
0290
0291 pchan = chan_info + subspace_id;
0292 chan = pchan->chan.mchan;
0293 if (IS_ERR(chan) || chan->cl) {
0294 pr_err("Channel not found for idx: %d\n", subspace_id);
0295 return ERR_PTR(-EBUSY);
0296 }
0297 dev = chan->mbox->dev;
0298
0299 spin_lock_irqsave(&chan->lock, flags);
0300 chan->msg_free = 0;
0301 chan->msg_count = 0;
0302 chan->active_req = NULL;
0303 chan->cl = cl;
0304 init_completion(&chan->tx_complete);
0305
0306 if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone)
0307 chan->txdone_method = TXDONE_BY_ACK;
0308
0309 spin_unlock_irqrestore(&chan->lock, flags);
0310
0311 if (pchan->plat_irq > 0) {
0312 int rc;
0313
0314 rc = devm_request_irq(dev, pchan->plat_irq, pcc_mbox_irq, 0,
0315 MBOX_IRQ_NAME, chan);
0316 if (unlikely(rc)) {
0317 dev_err(dev, "failed to register PCC interrupt %d\n",
0318 pchan->plat_irq);
0319 pcc_mbox_free_channel(&pchan->chan);
0320 return ERR_PTR(rc);
0321 }
0322 }
0323
0324 return &pchan->chan;
0325 }
0326 EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);
0327
0328
0329
0330
0331
0332
0333
0334 void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
0335 {
0336 struct pcc_chan_info *pchan_info = to_pcc_chan_info(pchan);
0337 struct mbox_chan *chan = pchan->mchan;
0338 unsigned long flags;
0339
0340 if (!chan || !chan->cl)
0341 return;
0342
0343 if (pchan_info->plat_irq > 0)
0344 devm_free_irq(chan->mbox->dev, pchan_info->plat_irq, chan);
0345
0346 spin_lock_irqsave(&chan->lock, flags);
0347 chan->cl = NULL;
0348 chan->active_req = NULL;
0349 if (chan->txdone_method == TXDONE_BY_ACK)
0350 chan->txdone_method = TXDONE_BY_POLL;
0351
0352 spin_unlock_irqrestore(&chan->lock, flags);
0353 }
0354 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368 static int pcc_send_data(struct mbox_chan *chan, void *data)
0369 {
0370 int ret;
0371 struct pcc_chan_info *pchan = chan->con_priv;
0372
0373 ret = pcc_chan_reg_read_modify_write(&pchan->cmd_update);
0374 if (ret)
0375 return ret;
0376
0377 return pcc_chan_reg_read_modify_write(&pchan->db);
0378 }
0379
0380 static const struct mbox_chan_ops pcc_chan_ops = {
0381 .send_data = pcc_send_data,
0382 };
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 static int parse_pcc_subspace(union acpi_subtable_headers *header,
0395 const unsigned long end)
0396 {
0397 struct acpi_pcct_subspace *ss = (struct acpi_pcct_subspace *) header;
0398
0399 if (ss->header.type < ACPI_PCCT_TYPE_RESERVED)
0400 return 0;
0401
0402 return -EINVAL;
0403 }
0404
0405 static int
0406 pcc_chan_reg_init(struct pcc_chan_reg *reg, struct acpi_generic_address *gas,
0407 u64 preserve_mask, u64 set_mask, u64 status_mask, char *name)
0408 {
0409 if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
0410 if (!(gas->bit_width >= 8 && gas->bit_width <= 64 &&
0411 is_power_of_2(gas->bit_width))) {
0412 pr_err("Error: Cannot access register of %u bit width",
0413 gas->bit_width);
0414 return -EFAULT;
0415 }
0416
0417 reg->vaddr = acpi_os_ioremap(gas->address, gas->bit_width / 8);
0418 if (!reg->vaddr) {
0419 pr_err("Failed to ioremap PCC %s register\n", name);
0420 return -ENOMEM;
0421 }
0422 }
0423 reg->gas = gas;
0424 reg->preserve_mask = preserve_mask;
0425 reg->set_mask = set_mask;
0426 reg->status_mask = status_mask;
0427 return 0;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442 static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
0443 struct acpi_subtable_header *pcct_entry)
0444 {
0445 int ret = 0;
0446 struct acpi_pcct_hw_reduced *pcct_ss;
0447
0448 if (pcct_entry->type < ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
0449 pcct_entry->type > ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
0450 return 0;
0451
0452 pcct_ss = (struct acpi_pcct_hw_reduced *)pcct_entry;
0453 pchan->plat_irq = pcc_map_interrupt(pcct_ss->platform_interrupt,
0454 (u32)pcct_ss->flags);
0455 if (pchan->plat_irq <= 0) {
0456 pr_err("PCC GSI %d not registered\n",
0457 pcct_ss->platform_interrupt);
0458 return -EINVAL;
0459 }
0460
0461 if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
0462 struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
0463
0464 ret = pcc_chan_reg_init(&pchan->plat_irq_ack,
0465 &pcct2_ss->platform_ack_register,
0466 pcct2_ss->ack_preserve_mask,
0467 pcct2_ss->ack_write_mask, 0,
0468 "PLAT IRQ ACK");
0469
0470 } else if (pcct_ss->header.type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE ||
0471 pcct_ss->header.type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) {
0472 struct acpi_pcct_ext_pcc_master *pcct_ext = (void *)pcct_ss;
0473
0474 ret = pcc_chan_reg_init(&pchan->plat_irq_ack,
0475 &pcct_ext->platform_ack_register,
0476 pcct_ext->ack_preserve_mask,
0477 pcct_ext->ack_set_mask, 0,
0478 "PLAT IRQ ACK");
0479 }
0480
0481 return ret;
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492 static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
0493 struct acpi_subtable_header *pcct_entry)
0494 {
0495 int ret = 0;
0496
0497 if (pcct_entry->type <= ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
0498 struct acpi_pcct_subspace *pcct_ss;
0499
0500 pcct_ss = (struct acpi_pcct_subspace *)pcct_entry;
0501
0502 ret = pcc_chan_reg_init(&pchan->db,
0503 &pcct_ss->doorbell_register,
0504 pcct_ss->preserve_mask,
0505 pcct_ss->write_mask, 0, "Doorbell");
0506
0507 } else {
0508 struct acpi_pcct_ext_pcc_master *pcct_ext;
0509
0510 pcct_ext = (struct acpi_pcct_ext_pcc_master *)pcct_entry;
0511
0512 ret = pcc_chan_reg_init(&pchan->db,
0513 &pcct_ext->doorbell_register,
0514 pcct_ext->preserve_mask,
0515 pcct_ext->write_mask, 0, "Doorbell");
0516 if (ret)
0517 return ret;
0518
0519 ret = pcc_chan_reg_init(&pchan->cmd_complete,
0520 &pcct_ext->cmd_complete_register,
0521 0, 0, pcct_ext->cmd_complete_mask,
0522 "Command Complete Check");
0523 if (ret)
0524 return ret;
0525
0526 ret = pcc_chan_reg_init(&pchan->cmd_update,
0527 &pcct_ext->cmd_update_register,
0528 pcct_ext->cmd_update_preserve_mask,
0529 pcct_ext->cmd_update_set_mask, 0,
0530 "Command Complete Update");
0531 if (ret)
0532 return ret;
0533
0534 ret = pcc_chan_reg_init(&pchan->error,
0535 &pcct_ext->error_status_register,
0536 0, 0, pcct_ext->error_status_mask,
0537 "Error Status");
0538 }
0539 return ret;
0540 }
0541
0542
0543
0544
0545
0546
0547
0548
0549 static void pcc_parse_subspace_shmem(struct pcc_chan_info *pchan,
0550 struct acpi_subtable_header *pcct_entry)
0551 {
0552 if (pcct_entry->type <= ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
0553 struct acpi_pcct_subspace *pcct_ss =
0554 (struct acpi_pcct_subspace *)pcct_entry;
0555
0556 pchan->chan.shmem_base_addr = pcct_ss->base_address;
0557 pchan->chan.shmem_size = pcct_ss->length;
0558 pchan->chan.latency = pcct_ss->latency;
0559 pchan->chan.max_access_rate = pcct_ss->max_access_rate;
0560 pchan->chan.min_turnaround_time = pcct_ss->min_turnaround_time;
0561 } else {
0562 struct acpi_pcct_ext_pcc_master *pcct_ext =
0563 (struct acpi_pcct_ext_pcc_master *)pcct_entry;
0564
0565 pchan->chan.shmem_base_addr = pcct_ext->base_address;
0566 pchan->chan.shmem_size = pcct_ext->length;
0567 pchan->chan.latency = pcct_ext->latency;
0568 pchan->chan.max_access_rate = pcct_ext->max_access_rate;
0569 pchan->chan.min_turnaround_time = pcct_ext->min_turnaround_time;
0570 }
0571 }
0572
0573
0574
0575
0576
0577
0578 static int __init acpi_pcc_probe(void)
0579 {
0580 int count, i, rc = 0;
0581 acpi_status status;
0582 struct acpi_table_header *pcct_tbl;
0583 struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED];
0584
0585 status = acpi_get_table(ACPI_SIG_PCCT, 0, &pcct_tbl);
0586 if (ACPI_FAILURE(status) || !pcct_tbl)
0587 return -ENODEV;
0588
0589
0590 for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE;
0591 i < ACPI_PCCT_TYPE_RESERVED; i++) {
0592 proc[i].id = i;
0593 proc[i].count = 0;
0594 proc[i].handler = parse_pcc_subspace;
0595 }
0596
0597 count = acpi_table_parse_entries_array(ACPI_SIG_PCCT,
0598 sizeof(struct acpi_table_pcct), proc,
0599 ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES);
0600 if (count <= 0 || count > MAX_PCC_SUBSPACES) {
0601 if (count < 0)
0602 pr_warn("Error parsing PCC subspaces from PCCT\n");
0603 else
0604 pr_warn("Invalid PCCT: %d PCC subspaces\n", count);
0605
0606 rc = -EINVAL;
0607 } else {
0608 pcc_chan_count = count;
0609 }
0610
0611 acpi_put_table(pcct_tbl);
0612
0613 return rc;
0614 }
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627 static int pcc_mbox_probe(struct platform_device *pdev)
0628 {
0629 struct device *dev = &pdev->dev;
0630 struct mbox_controller *pcc_mbox_ctrl;
0631 struct mbox_chan *pcc_mbox_channels;
0632 struct acpi_table_header *pcct_tbl;
0633 struct acpi_subtable_header *pcct_entry;
0634 struct acpi_table_pcct *acpi_pcct_tbl;
0635 acpi_status status = AE_OK;
0636 int i, rc, count = pcc_chan_count;
0637
0638
0639 status = acpi_get_table(ACPI_SIG_PCCT, 0, &pcct_tbl);
0640
0641 if (ACPI_FAILURE(status) || !pcct_tbl)
0642 return -ENODEV;
0643
0644 pcc_mbox_channels = devm_kcalloc(dev, count, sizeof(*pcc_mbox_channels),
0645 GFP_KERNEL);
0646 if (!pcc_mbox_channels) {
0647 rc = -ENOMEM;
0648 goto err;
0649 }
0650
0651 chan_info = devm_kcalloc(dev, count, sizeof(*chan_info), GFP_KERNEL);
0652 if (!chan_info) {
0653 rc = -ENOMEM;
0654 goto err;
0655 }
0656
0657 pcc_mbox_ctrl = devm_kzalloc(dev, sizeof(*pcc_mbox_ctrl), GFP_KERNEL);
0658 if (!pcc_mbox_ctrl) {
0659 rc = -ENOMEM;
0660 goto err;
0661 }
0662
0663
0664 pcct_entry = (struct acpi_subtable_header *) (
0665 (unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct));
0666
0667 acpi_pcct_tbl = (struct acpi_table_pcct *) pcct_tbl;
0668 if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL)
0669 pcc_mbox_ctrl->txdone_irq = true;
0670
0671 for (i = 0; i < count; i++) {
0672 struct pcc_chan_info *pchan = chan_info + i;
0673
0674 pcc_mbox_channels[i].con_priv = pchan;
0675 pchan->chan.mchan = &pcc_mbox_channels[i];
0676
0677 if (pcct_entry->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE &&
0678 !pcc_mbox_ctrl->txdone_irq) {
0679 pr_err("Plaform Interrupt flag must be set to 1");
0680 rc = -EINVAL;
0681 goto err;
0682 }
0683
0684 if (pcc_mbox_ctrl->txdone_irq) {
0685 rc = pcc_parse_subspace_irq(pchan, pcct_entry);
0686 if (rc < 0)
0687 goto err;
0688 }
0689 rc = pcc_parse_subspace_db_reg(pchan, pcct_entry);
0690 if (rc < 0)
0691 goto err;
0692
0693 pcc_parse_subspace_shmem(pchan, pcct_entry);
0694
0695 pcct_entry = (struct acpi_subtable_header *)
0696 ((unsigned long) pcct_entry + pcct_entry->length);
0697 }
0698
0699 pcc_mbox_ctrl->num_chans = count;
0700
0701 pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl->num_chans);
0702
0703 pcc_mbox_ctrl->chans = pcc_mbox_channels;
0704 pcc_mbox_ctrl->ops = &pcc_chan_ops;
0705 pcc_mbox_ctrl->dev = dev;
0706
0707 pr_info("Registering PCC driver as Mailbox controller\n");
0708 rc = mbox_controller_register(pcc_mbox_ctrl);
0709 if (rc)
0710 pr_err("Err registering PCC as Mailbox controller: %d\n", rc);
0711 else
0712 return 0;
0713 err:
0714 acpi_put_table(pcct_tbl);
0715 return rc;
0716 }
0717
0718 static struct platform_driver pcc_mbox_driver = {
0719 .probe = pcc_mbox_probe,
0720 .driver = {
0721 .name = "PCCT",
0722 },
0723 };
0724
0725 static int __init pcc_init(void)
0726 {
0727 int ret;
0728 struct platform_device *pcc_pdev;
0729
0730 if (acpi_disabled)
0731 return -ENODEV;
0732
0733
0734 ret = acpi_pcc_probe();
0735
0736 if (ret) {
0737 pr_debug("ACPI PCC probe failed.\n");
0738 return -ENODEV;
0739 }
0740
0741 pcc_pdev = platform_create_bundle(&pcc_mbox_driver,
0742 pcc_mbox_probe, NULL, 0, NULL, 0);
0743
0744 if (IS_ERR(pcc_pdev)) {
0745 pr_debug("Err creating PCC platform bundle\n");
0746 return PTR_ERR(pcc_pdev);
0747 }
0748
0749 return 0;
0750 }
0751
0752
0753
0754
0755
0756
0757 postcore_initcall(pcc_init);