summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-layerscape/ppa.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-layerscape/ppa.c')
-rw-r--r--arch/arm/mach-layerscape/ppa.c69
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;
}