tpm_crb: Add idle support for the Arm FF-A start method

According to the CRB over FF-A specification [1], a TPM that implements
the ABI must comply with the TCG PTP specification. This requires support
for the Idle and Ready states.

This patch implements CRB control area requests for goIdle and
cmdReady on FF-A based TPMs.

The FF-A message used to notify the TPM of CRB updates includes a
locality parameter, which provides a hint to the TPM about which
locality modified the CRB. This patch adds a locality parameter
to __crb_go_idle() and __crb_cmd_ready() to support this.

[1] https://developer.arm.com/documentation/den0138/latest/

Signed-off-by: Stuart Yoder <stuart.yoder@arm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by Stuart Yoder and committed by Jarkko Sakkinen dbfdaeb3 f406055c

+20 -9
+20 -9
drivers/char/tpm/tpm_crb.c
··· 133 133 { 134 134 return !(start_method == ACPI_TPM2_START_METHOD || 135 135 start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD || 136 - start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC || 137 - start_method == ACPI_TPM2_CRB_WITH_ARM_FFA); 136 + start_method == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC); 138 137 } 139 138 140 139 static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, ··· 190 191 * 191 192 * Return: 0 always 192 193 */ 193 - static int __crb_go_idle(struct device *dev, struct crb_priv *priv) 194 + static int __crb_go_idle(struct device *dev, struct crb_priv *priv, int loc) 194 195 { 195 196 int rc; 196 197 ··· 198 199 return 0; 199 200 200 201 iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); 202 + 203 + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { 204 + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, loc); 205 + if (rc) 206 + return rc; 207 + } 201 208 202 209 rc = crb_try_pluton_doorbell(priv, true); 203 210 if (rc) ··· 225 220 struct device *dev = &chip->dev; 226 221 struct crb_priv *priv = dev_get_drvdata(dev); 227 222 228 - return __crb_go_idle(dev, priv); 223 + return __crb_go_idle(dev, priv, chip->locality); 229 224 } 230 225 231 226 /** ··· 243 238 * 244 239 * Return: 0 on success -ETIME on timeout; 245 240 */ 246 - static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv) 241 + static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv, int loc) 247 242 { 248 243 int rc; 249 244 ··· 251 246 return 0; 252 247 253 248 iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req); 249 + 250 + if (priv->sm == ACPI_TPM2_CRB_WITH_ARM_FFA) { 251 + rc = tpm_crb_ffa_start(CRB_FFA_START_TYPE_COMMAND, loc); 252 + if (rc) 253 + return rc; 254 + } 254 255 255 256 rc = crb_try_pluton_doorbell(priv, true); 256 257 if (rc) ··· 278 267 struct device *dev = &chip->dev; 279 268 struct crb_priv *priv = dev_get_drvdata(dev); 280 269 281 - return __crb_cmd_ready(dev, priv); 270 + return __crb_cmd_ready(dev, priv, chip->locality); 282 271 } 283 272 284 273 static int __crb_request_locality(struct device *dev, ··· 455 444 456 445 /* Seems to be necessary for every command */ 457 446 if (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) 458 - __crb_cmd_ready(&chip->dev, priv); 447 + __crb_cmd_ready(&chip->dev, priv, chip->locality); 459 448 460 449 memcpy_toio(priv->cmd, buf, len); 461 450 ··· 683 672 * PTT HW bug w/a: wake up the device to access 684 673 * possibly not retained registers. 685 674 */ 686 - ret = __crb_cmd_ready(dev, priv); 675 + ret = __crb_cmd_ready(dev, priv, 0); 687 676 if (ret) 688 677 goto out_relinquish_locality; 689 678 ··· 755 744 if (!ret) 756 745 priv->cmd_size = cmd_size; 757 746 758 - __crb_go_idle(dev, priv); 747 + __crb_go_idle(dev, priv, 0); 759 748 760 749 out_relinquish_locality: 761 750