diff options
Diffstat (limited to 'arch/arm/mach-layerscape/ppa.c')
-rw-r--r-- | arch/arm/mach-layerscape/ppa.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/arch/arm/mach-layerscape/ppa.c b/arch/arm/mach-layerscape/ppa.c index 6070451020..21efaae3ab 100644 --- a/arch/arm/mach-layerscape/ppa.c +++ b/arch/arm/mach-layerscape/ppa.c @@ -4,6 +4,7 @@ #include <common.h> #include <init.h> +#include <mmu.h> #include <firmware.h> #include <memory.h> #include <linux/sizes.h> @@ -13,20 +14,40 @@ #include <asm/system.h> #include <image-fit.h> #include <asm/psci.h> -#include <mach/layerscape.h> +#include <mach/layerscape/layerscape.h> +#include <asm/cache.h> int ppa_entry(const void *, u32 *, u32 *); -void dma_flush_range(void *ptr, size_t size); + +#define SEC_JR3_OFFSET 0x40000 static int of_psci_do_fixup(struct device_node *root, void *unused) { unsigned long psci_version; + struct device_node *np; struct arm_smccc_res res = {}; arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res); psci_version = res.a0; - return of_psci_fixup(root, psci_version); + for_each_compatible_node_from(np, root, NULL, "fsl,sec-v4.0-job-ring") { + const void *reg; + int na = of_n_addr_cells(np); + u64 offset; + + reg = of_get_property(np, "reg", NULL); + if (!reg) + continue; + + offset = of_read_number(reg, na); + if (offset != SEC_JR3_OFFSET) + continue; + + of_delete_node(np); + break; + } + + return of_psci_fixup(root, psci_version, "smc"); } static int ppa_init(void *ppa, size_t ppa_size, void *sec_firmware_addr) @@ -34,32 +55,25 @@ static int ppa_init(void *ppa, size_t ppa_size, void *sec_firmware_addr) int ret; u32 *boot_loc_ptr_l, *boot_loc_ptr_h; struct ccsr_scfg __iomem *scfg = (void *)(LSCH2_SCFG_ADDR); - int el = current_el(); struct fit_handle *fit; void *conf; const void *buf; unsigned long firmware_size; - if (el < 3) { - printf("EL%d, skip ppa init\n", el); - return 0; - } - boot_loc_ptr_l = &scfg->scratchrw[1]; boot_loc_ptr_h = &scfg->scratchrw[0]; fit = fit_open_buf(ppa, ppa_size, false, BOOTM_VERIFY_AVAILABLE); if (IS_ERR(fit)) { - pr_err("Cannot open ppa FIT image: %s\n", strerrorp(fit)); + pr_err("Cannot open ppa FIT image: %pe\n", fit); return PTR_ERR(fit); } conf = fit_open_configuration(fit, NULL); if (IS_ERR(conf)) { - pr_err("Cannot open default config in ppa FIT image: %s\n", - strerrorp(conf)); - fit_close(fit); - return PTR_ERR(fit); + pr_err("Cannot open default config in ppa FIT image: %pe\n", conf); + ret = PTR_ERR(conf); + goto err; } @@ -67,13 +81,12 @@ static int ppa_init(void *ppa, size_t ppa_size, void *sec_firmware_addr) if (ret) { pr_err("Cannot open firmware image in ppa FIT image: %s\n", strerror(-ret)); - ret = PTR_ERR(fit); goto err; } /* Copy the secure firmware to secure memory */ memcpy(sec_firmware_addr, buf, firmware_size); - dma_flush_range(sec_firmware_addr, ppa_size); + sync_caches_for_execution(); ret = ppa_entry(sec_firmware_addr, boot_loc_ptr_l, boot_loc_ptr_h); if (ret) { @@ -88,7 +101,7 @@ static int ppa_init(void *ppa, size_t ppa_size, void *sec_firmware_addr) err: fit_close(fit); - return 0; + return ret; } int ls1046a_ppa_init(resource_size_t ppa_start, resource_size_t ppa_size) @@ -97,9 +110,10 @@ int ls1046a_ppa_init(resource_size_t ppa_start, resource_size_t ppa_size) struct resource *res; void *ppa_fw; size_t ppa_fw_size; + int el = current_el(); int ret; - res = request_sdram_region("ppa", ppa_start, ppa_size); + res = reserve_sdram_region("ppa", ppa_start, ppa_size); if (!res) { pr_err("Cannot request SDRAM region %pa - %pa\n", &ppa_start, &ppa_end); @@ -108,11 +122,22 @@ int ls1046a_ppa_init(resource_size_t ppa_start, resource_size_t ppa_size) get_builtin_firmware(ppa_ls1046a_bin, &ppa_fw, &ppa_fw_size); - ret = ppa_init(ppa_fw, ppa_fw_size, (void *)ppa_start); - if (ret) - return ret; + if (el == 3) { + unsigned long cr; + + asm volatile("mrs %0, sctlr_el3" : "=r" (cr) : : "cc"); + remap_range((void *)ppa_start, ppa_size, MAP_CACHED); + + ret = ppa_init(ppa_fw, ppa_fw_size, (void *)ppa_start); + + asm volatile("msr sctlr_el2, %0" : : "r" (cr) : "cc"); + remap_range((void *)ppa_start, ppa_size, MAP_UNCACHED); + + if (ret) + return ret; + } - of_add_reserve_entry(ppa_start, ppa_end); + of_register_fixup(of_fixup_reserved_memory, res); return 0; } |