if (!isp->secure_mode) {
dev_dbg(&isp->pdev->dev, "Skip IPC reset for non-secure mode"); return0;
}
mutex_lock(&b->ipc_mutex);
/* Clear-by-1 CSR (all bits), corresponding internal states. */
val = readl(isp->base + ipc->csr_in);
writel(val, isp->base + ipc->csr_in);
/* Set peer CSR bit IPC_PEER_COMP_ACTIONS_RST_PHASE1 */
writel(ENTRY, isp->base + ipc->csr_out); /* * Clear-by-1 all CSR bits EXCEPT following * bits: * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1. * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2. * C. Possibly custom bits, depending on * their role.
*/
csr_in_clr = BUTTRESS_IU2CSECSR_IPC_PEER_DEASSERTED_REG_VALID_REQ |
BUTTRESS_IU2CSECSR_IPC_PEER_ACKED_REG_VALID |
BUTTRESS_IU2CSECSR_IPC_PEER_ASSERTED_REG_VALID_REQ | QUERY;
do {
usleep_range(400, 500);
val = readl(isp->base + ipc->csr_in); switch (val) { case ENTRY | EXIT: case ENTRY | EXIT | QUERY: /* * 1) Clear-by-1 CSR bits * (IPC_PEER_COMP_ACTIONS_RST_PHASE1, * IPC_PEER_COMP_ACTIONS_RST_PHASE2). * 2) Set peer CSR bit * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE.
*/
writel(ENTRY | EXIT, isp->base + ipc->csr_in);
writel(QUERY, isp->base + ipc->csr_out); break; case ENTRY: case ENTRY | QUERY: /* * 1) Clear-by-1 CSR bits * (IPC_PEER_COMP_ACTIONS_RST_PHASE1, * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE). * 2) Set peer CSR bit * IPC_PEER_COMP_ACTIONS_RST_PHASE1.
*/
writel(ENTRY | QUERY, isp->base + ipc->csr_in);
writel(ENTRY, isp->base + ipc->csr_out); break; caseEXIT: caseEXIT | QUERY: /* * Clear-by-1 CSR bit * IPC_PEER_COMP_ACTIONS_RST_PHASE2. * 1) Clear incoming doorbell. * 2) Clear-by-1 all CSR bits EXCEPT following * bits: * A. IPC_PEER_COMP_ACTIONS_RST_PHASE1. * B. IPC_PEER_COMP_ACTIONS_RST_PHASE2. * C. Possibly custom bits, depending on * their role. * 3) Set peer CSR bit * IPC_PEER_COMP_ACTIONS_RST_PHASE2.
*/
writel(EXIT, isp->base + ipc->csr_in);
writel(0, isp->base + ipc->db0_in);
writel(csr_in_clr, isp->base + ipc->csr_in);
writel(EXIT, isp->base + ipc->csr_out);
/* * Read csr_in again to make sure if RST_PHASE2 is done. * If csr_in is QUERY, it should be handled again.
*/
usleep_range(200, 300);
val = readl(isp->base + ipc->csr_in); if (val & QUERY) {
dev_dbg(&isp->pdev->dev, "RST_PHASE2 retry csr_in = %x\n", val); break;
}
mutex_unlock(&b->ipc_mutex); return0; case QUERY: /* * 1) Clear-by-1 CSR bit * IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE. * 2) Set peer CSR bit * IPC_PEER_COMP_ACTIONS_RST_PHASE1
*/
writel(QUERY, isp->base + ipc->csr_in);
writel(ENTRY, isp->base + ipc->csr_out); break; default:
dev_dbg_ratelimited(&isp->pdev->dev, "Unexpected CSR 0x%x\n", val); break;
}
} while (retries--);
mutex_unlock(&b->ipc_mutex);
dev_err(&isp->pdev->dev, "Timed out while waiting for CSE\n");
ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATE,
val, (val & ctrl->pwr_sts_mask) == pwr_sts, 100, BUTTRESS_POWER_TIMEOUT_US); if (ret)
dev_err(&isp->pdev->dev, "Change power status timeout with 0x%x\n", val);
ret = readl_poll_timeout(isp->base + BUTTRESS_REG_FW_RESET_CTL, val,
val & BUTTRESS_FW_RESET_CTL_DONE, 500,
BUTTRESS_CSE_FWRESET_TIMEOUT_US); if (ret) {
dev_err(&isp->pdev->dev, "Time out while resetting authentication state\n"); return ret;
}
dev_dbg(&isp->pdev->dev, "FW reset for authentication done\n");
writel(0, isp->base + BUTTRESS_REG_FW_RESET_CTL); /* leave some time for HW restore */
usleep_range(800, 1000);
int ipu6_buttress_authenticate(struct ipu6_device *isp)
{ struct ipu6_buttress *b = &isp->buttress; struct ipu6_psys_pdata *psys_pdata;
u32 data, mask, done, fail; int ret;
if (!isp->secure_mode) {
dev_dbg(&isp->pdev->dev, "Skip auth for non-secure mode\n"); return0;
}
psys_pdata = isp->psys->pdata;
mutex_lock(&b->auth_mutex);
if (ipu6_buttress_auth_done(isp)) {
ret = 0; goto out_unlock;
}
/* * Write address of FIT table to FW_SOURCE register * Let's use fw address. I.e. not using FIT table yet
*/
data = lower_32_bits(isp->psys->pkg_dir_dma_addr);
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_LO);
data = upper_32_bits(isp->psys->pkg_dir_dma_addr);
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_HI);
/* * Write boot_load into IU2CSEDATA0 * Write sizeof(boot_load) | 0x2 << CLIENT_ID to * IU2CSEDB.IU2CSECMD and set IU2CSEDB.IU2CSEBUSY as
*/
dev_info(&isp->pdev->dev, "Sending BOOT_LOAD to CSE\n");
ret = ipu6_buttress_ipc_send(isp,
BUTTRESS_IU2CSEDATA0_IPC_BOOT_LOAD, 1, true,
BUTTRESS_CSE2IUDATA0_IPC_BOOT_LOAD_DONE); if (ret) {
dev_err(&isp->pdev->dev, "CSE boot_load failed\n"); goto out_unlock;
}
int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp)
{ unsignedint i;
for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
u32 val; int ret;
ret = ipu6_buttress_send_tsc_request(isp); if (ret != -ETIMEDOUT) return ret;
val = readl(isp->base + BUTTRESS_REG_TSW_CTL);
val = val | BUTTRESS_TSW_CTL_SOFT_RESET;
writel(val, isp->base + BUTTRESS_REG_TSW_CTL);
val = val & ~BUTTRESS_TSW_CTL_SOFT_RESET;
writel(val, isp->base + BUTTRESS_REG_TSW_CTL);
}
/* get ref_clk frequency by reading the indication in btrs control */
val = readl(isp->base + BUTTRESS_REG_BTRS_CTRL);
val = FIELD_GET(BUTTRESS_REG_BTRS_CTRL_REF_CLK_IND, val);
/* Retry couple of times in case of CSE initialization is delayed */ do {
ret = ipu6_buttress_ipc_reset(isp, &b->cse); if (ret) {
dev_warn(&isp->pdev->dev, "IPC reset protocol failed, retrying\n");
} else {
dev_dbg(&isp->pdev->dev, "IPC reset done\n"); return0;
}
} while (ipc_reset_retry--);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.