Lines Matching +full:value +full:- +full:start

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
20 #include <linux/arm-smccc.h>
118 static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, in crb_wait_for_reg_32() argument
121 ktime_t start; in crb_wait_for_reg_32() local
124 start = ktime_get(); in crb_wait_for_reg_32()
125 stop = ktime_add(start, ms_to_ktime(timeout)); in crb_wait_for_reg_32()
128 if ((ioread32(reg) & mask) == value) in crb_wait_for_reg_32()
134 return ((ioread32(reg) & mask) == value); in crb_wait_for_reg_32()
139 if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) in crb_try_pluton_doorbell()
142 if (!crb_wait_for_reg_32(priv->pluton_reply_addr, ~0, 1, TPM2_TIMEOUT_C)) in crb_try_pluton_doorbell()
143 return -ETIME; in crb_try_pluton_doorbell()
145 iowrite32(1, priv->pluton_start_addr); in crb_try_pluton_doorbell()
149 if (!crb_wait_for_reg_32(priv->pluton_start_addr, in crb_try_pluton_doorbell()
151 return -ETIME; in crb_try_pluton_doorbell()
157 * __crb_go_idle - request tpm crb device to go the idle state
167 * The function does nothing for devices with ACPI-start method
168 * or SMC-start method.
176 if ((priv->sm == ACPI_TPM2_START_METHOD) || in __crb_go_idle()
177 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || in __crb_go_idle()
178 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) in __crb_go_idle()
181 iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); in __crb_go_idle()
187 if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req, in __crb_go_idle()
189 0, /* value */ in __crb_go_idle()
192 return -ETIME; in __crb_go_idle()
200 struct device *dev = &chip->dev; in crb_go_idle()
207 * __crb_cmd_ready - request tpm crb device to enter ready state
216 * The function does nothing for devices with ACPI-start method
217 * or SMC-start method.
219 * Return: 0 on success -ETIME on timeout;
225 if ((priv->sm == ACPI_TPM2_START_METHOD) || in __crb_cmd_ready()
226 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || in __crb_cmd_ready()
227 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC)) in __crb_cmd_ready()
230 iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req); in __crb_cmd_ready()
236 if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req, in __crb_cmd_ready()
238 0, /* value */ in __crb_cmd_ready()
241 return -ETIME; in __crb_cmd_ready()
249 struct device *dev = &chip->dev; in crb_cmd_ready()
258 u32 value = CRB_LOC_STATE_LOC_ASSIGNED | in __crb_request_locality() local
261 if (!priv->regs_h) in __crb_request_locality()
264 iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); in __crb_request_locality()
265 if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, in __crb_request_locality()
268 return -ETIME; in __crb_request_locality()
276 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_request_locality()
278 return __crb_request_locality(&chip->dev, priv, loc); in crb_request_locality()
286 u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS; in __crb_relinquish_locality() local
288 if (!priv->regs_h) in __crb_relinquish_locality()
291 iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); in __crb_relinquish_locality()
292 if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, in __crb_relinquish_locality()
295 return -ETIME; in __crb_relinquish_locality()
303 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_relinquish_locality()
305 return __crb_relinquish_locality(&chip->dev, priv, loc); in crb_relinquish_locality()
310 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_status()
313 if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) != in crb_status()
322 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_recv()
329 return -EIO; in crb_recv()
334 if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR) in crb_recv()
335 return -EIO; in crb_recv()
341 memcpy_fromio(buf, priv->rsp, 8); in crb_recv()
345 return -EIO; in crb_recv()
347 memcpy_fromio(&buf[8], &priv->rsp[8], expected - 8); in crb_recv()
357 obj = acpi_evaluate_dsm(chip->acpi_dev_handle, in crb_do_acpi_start()
363 return -ENXIO; in crb_do_acpi_start()
364 rc = obj->integer.value == 0 ? 0 : -ENXIO; in crb_do_acpi_start()
371 * This is a TPM Command Response Buffer start method that invokes a
384 return -EIO; in tpm_crb_smc_start()
392 dev_err(dev, FW_BUG "tpm_crb: incorrect start method\n"); in tpm_crb_smc_start()
393 return -EINVAL; in tpm_crb_smc_start()
399 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_send()
405 iowrite32(0, &priv->regs_t->ctrl_cancel); in crb_send()
407 if (len > priv->cmd_size) { in crb_send()
408 dev_err(&chip->dev, "invalid command count value %zd %d\n", in crb_send()
409 len, priv->cmd_size); in crb_send()
410 return -E2BIG; in crb_send()
414 if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) in crb_send()
415 __crb_cmd_ready(&chip->dev, priv); in crb_send()
417 memcpy_toio(priv->cmd, buf, len); in crb_send()
419 /* Make sure that cmd is populated before issuing start. */ in crb_send()
423 * report only ACPI start but in practice seems to require both in crb_send()
424 * CRB start, hence invoking CRB start method if hid == MSFT0101. in crb_send()
426 if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || in crb_send()
427 (priv->sm == ACPI_TPM2_MEMORY_MAPPED) || in crb_send()
428 (!strcmp(priv->hid, "MSFT0101"))) in crb_send()
429 iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); in crb_send()
431 if ((priv->sm == ACPI_TPM2_START_METHOD) || in crb_send()
432 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) in crb_send()
435 if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) { in crb_send()
436 iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start); in crb_send()
437 rc = tpm_crb_smc_start(&chip->dev, priv->smc_func_id); in crb_send()
448 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_cancel()
450 iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel); in crb_cancel()
452 if (((priv->sm == ACPI_TPM2_START_METHOD) || in crb_cancel()
453 (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD)) && in crb_cancel()
455 dev_err(&chip->dev, "ACPI Start failed\n"); in crb_cancel()
460 struct crb_priv *priv = dev_get_drvdata(&chip->dev); in crb_req_canceled()
461 u32 cancel = ioread32(&priv->regs_t->ctrl_cancel); in crb_req_canceled()
503 void __iomem **iobase_ptr, u64 start, u32 size) in crb_map_res() argument
506 .start = start, in crb_map_res()
507 .end = start + size - 1, in crb_map_res()
512 if (start != new_res.start) in crb_map_res()
513 return IOMEM_ERR_PTR(-EINVAL); in crb_map_res()
524 return *iobase_ptr + (new_res.start - iores->start); in crb_map_res()
533 u64 start, u64 size) in crb_fixup_cmd_size() argument
535 if (io_res->start > start || io_res->end < start) in crb_fixup_cmd_size()
538 if (start + size - 1 <= io_res->end) in crb_fixup_cmd_size()
543 io_res, start, size); in crb_fixup_cmd_size()
545 return io_res->end - start + 1; in crb_fixup_cmd_size()
554 struct device *dev = &device->dev; in crb_map_io()
570 if (priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { in crb_map_io()
580 return -EINVAL; in crb_map_io()
593 if (buf->control_address >= iores_array[i].start && in crb_map_io()
594 buf->control_address + sizeof(struct crb_regs_tail) - 1 <= in crb_map_io()
602 priv->regs_t = crb_map_res(dev, iores, iobase_ptr, buf->control_address, in crb_map_io()
605 if (IS_ERR(priv->regs_t)) in crb_map_io()
606 return PTR_ERR(priv->regs_t); in crb_map_io()
612 if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || in crb_map_io()
613 (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { in crb_map_io()
615 buf->control_address == iores->start + in crb_map_io()
616 sizeof(*priv->regs_h)) in crb_map_io()
617 priv->regs_h = *iobase_ptr; in crb_map_io()
634 pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high); in crb_map_io()
635 pa_low = ioread32(&priv->regs_t->ctrl_cmd_pa_low); in crb_map_io()
637 cmd_size = ioread32(&priv->regs_t->ctrl_cmd_size); in crb_map_io()
642 if (cmd_pa >= iores_array[i].start && in crb_map_io()
656 priv->cmd = crb_map_res(dev, iores, iobase_ptr, cmd_pa, cmd_size); in crb_map_io()
657 if (IS_ERR(priv->cmd)) { in crb_map_io()
658 ret = PTR_ERR(priv->cmd); in crb_map_io()
662 memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8); in crb_map_io()
664 rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size); in crb_map_io()
669 if (rsp_pa >= iores_array[i].start && in crb_map_io()
681 priv->rsp = crb_map_res(dev, iores, iobase_ptr, in crb_map_io()
683 ret = PTR_ERR_OR_ZERO(priv->rsp); in crb_map_io()
692 ret = -EINVAL; in crb_map_io()
696 priv->rsp = priv->cmd; in crb_map_io()
700 priv->cmd_size = cmd_size; in crb_map_io()
714 priv->pluton_start_addr = crb_map_res(dev, NULL, NULL, in crb_map_pluton()
715 crb_pluton->start_addr, 4); in crb_map_pluton()
716 if (IS_ERR(priv->pluton_start_addr)) in crb_map_pluton()
717 return PTR_ERR(priv->pluton_start_addr); in crb_map_pluton()
719 priv->pluton_reply_addr = crb_map_res(dev, NULL, NULL, in crb_map_pluton()
720 crb_pluton->reply_addr, 4); in crb_map_pluton()
721 if (IS_ERR(priv->pluton_reply_addr)) in crb_map_pluton()
722 return PTR_ERR(priv->pluton_reply_addr); in crb_map_pluton()
732 struct device *dev = &device->dev; in crb_acpi_add()
741 if (ACPI_FAILURE(status) || buf->header.length < sizeof(*buf)) { in crb_acpi_add()
743 return -EINVAL; in crb_acpi_add()
747 sm = buf->start_method; in crb_acpi_add()
749 rc = -ENODEV; in crb_acpi_add()
755 rc = -ENOMEM; in crb_acpi_add()
760 if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) { in crb_acpi_add()
762 FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", in crb_acpi_add()
763 buf->header.length, in crb_acpi_add()
765 rc = -EINVAL; in crb_acpi_add()
769 priv->smc_func_id = crb_smc->smc_func_id; in crb_acpi_add()
773 if (buf->header.length < (sizeof(*buf) + sizeof(*crb_pluton))) { in crb_acpi_add()
775 FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", in crb_acpi_add()
776 buf->header.length, in crb_acpi_add()
778 rc = -EINVAL; in crb_acpi_add()
787 priv->sm = sm; in crb_acpi_add()
788 priv->hid = acpi_device_hid(device); in crb_acpi_add()
800 dev_set_drvdata(&chip->dev, priv); in crb_acpi_add()
801 chip->acpi_dev_handle = device->handle; in crb_acpi_add()
802 chip->flags = TPM_CHIP_FLAG_TPM2; in crb_acpi_add()
809 /* A quirk for https://www.amd.com/en/support/kb/faq/pa-410 */ in crb_acpi_add()
811 priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { in crb_acpi_add()
813 chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; in crb_acpi_add()
826 struct device *dev = &device->dev; in crb_acpi_remove()