| // SPDX-License-Identifier: BSD-2-Clause |
| /* |
| * Copyright 2017-2019 NXP |
| * |
| * Brief CAAM Configuration. |
| */ |
| #include <caam_common.h> |
| #include <caam_hal_cfg.h> |
| #include <caam_hal_jr.h> |
| #include <caam_jr.h> |
| #include <kernel/dt.h> |
| #include <libfdt.h> |
| #include <mm/core_memprot.h> |
| #include <mm/core_mmu.h> |
| |
| static const char *dt_caam_match_table = { |
| "fsl,sec-v4.0", |
| }; |
| |
| static const char *dt_jr_match_table = { |
| "fsl,sec-v4.0-job-ring", |
| }; |
| |
| /* |
| * Finds the Job Ring reserved for the Secure Mode in the DTB |
| * |
| * @fdt Reference to the Device Tree |
| * @status Status mask flag of the node to found |
| * @find_node [out] Node offset found |
| */ |
| static paddr_t find_jr_offset(void *fdt, int status, int *find_node) |
| { |
| paddr_t jr_offset = 0; |
| int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table); |
| |
| for (; node != -FDT_ERR_NOTFOUND; |
| node = fdt_node_offset_by_compatible(fdt, node, |
| dt_jr_match_table)) { |
| HAL_TRACE("Found Job Ring node status @%" PRId32, node); |
| if (_fdt_get_status(fdt, node) == status) { |
| HAL_TRACE("Found Job Ring node @%" PRId32, node); |
| jr_offset = _fdt_reg_base_address(fdt, node); |
| *find_node = node; |
| break; |
| } |
| } |
| |
| HAL_TRACE("JR Offset return 0x%" PRIxPTR, jr_offset); |
| return jr_offset; |
| } |
| |
| void caam_hal_cfg_get_ctrl_dt(void *fdt, vaddr_t *ctrl_base) |
| { |
| ssize_t size = 0; |
| int node = 0; |
| paddr_t pctrl_base = 0; |
| |
| *ctrl_base = 0; |
| /* Get the CAAM Node to get the controller base address */ |
| node = fdt_node_offset_by_compatible(fdt, 0, dt_caam_match_table); |
| |
| if (node < 0) |
| return; |
| |
| /* |
| * Map CAAM controller base address as Secure IO if not |
| * already present in the MMU table. |
| * Then get the virtual address of the CAAM controller |
| */ |
| pctrl_base = _fdt_reg_base_address(fdt, node); |
| if (pctrl_base == DT_INFO_INVALID_REG) { |
| HAL_TRACE("CAAM control base address not defined"); |
| return; |
| } |
| |
| size = _fdt_reg_size(fdt, node); |
| if (size < 0) { |
| HAL_TRACE("CAAM control base address size not defined"); |
| return; |
| } |
| |
| if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, pctrl_base, size)) { |
| EMSG("CAAM control base MMU PA mapping failure"); |
| return; |
| } |
| |
| *ctrl_base = (vaddr_t)phys_to_virt(pctrl_base, MEM_AREA_IO_SEC); |
| if (!*ctrl_base) |
| EMSG("CAAM control base MMU VA mapping failure"); |
| |
| HAL_TRACE("Map Controller 0x%" PRIxVA, *ctrl_base); |
| } |
| |
| void caam_hal_cfg_get_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg) |
| { |
| paddr_t jr_offset = 0; |
| int jr_it_num = 0; |
| int node = 0; |
| |
| jr_offset = find_jr_offset(fdt, DT_STATUS_OK_SEC, &node); |
| if (jr_offset) { |
| /* Disable JR for Normal World */ |
| if (dt_enable_secure_status(fdt, node)) { |
| EMSG("Not able to disable JR DTB entry"); |
| return; |
| } |
| |
| /* Get the job ring interrupt */ |
| jr_it_num = dt_get_irq(fdt, node); |
| if (jr_it_num == DT_INFO_INVALID_INTERRUPT) { |
| EMSG("Job Ring interrupt number not defined in DTB"); |
| return; |
| } |
| |
| jrcfg->offset = jr_offset; |
| /* Add index of the first SPI interrupt */ |
| jrcfg->it_num = jr_it_num + 32; |
| } |
| } |
| |
| void caam_hal_cfg_disable_jobring_dt(void *fdt, struct caam_jrcfg *jrcfg) |
| { |
| int node = fdt_node_offset_by_compatible(fdt, 0, dt_jr_match_table); |
| |
| for (; node != -FDT_ERR_NOTFOUND; |
| node = fdt_node_offset_by_compatible(fdt, node, |
| dt_jr_match_table)) { |
| HAL_TRACE("Found Job Ring node @%" PRId32, node); |
| if (_fdt_reg_base_address(fdt, node) == jrcfg->offset) { |
| HAL_TRACE("Disable Job Ring node @%" PRId32, node); |
| if (dt_enable_secure_status(fdt, node)) |
| panic(); |
| break; |
| } |
| } |
| } |