diff --git a/drivers/cpu/amp-uclass.c b/drivers/cpu/amp-uclass.c index 7d52722a2d..33a3050894 100644 --- a/drivers/cpu/amp-uclass.c +++ b/drivers/cpu/amp-uclass.c @@ -102,10 +102,13 @@ static int amp_pre_probe(struct udevice *dev) uc_pdata->partition = dev_read_string(dev, "partition"); uc_pdata->cpu = dev_read_u32_default(dev, "cpu", -ENODATA); #ifdef CONFIG_ARM64 - uc_pdata->aarch = dev_read_u32_default(dev, "aarch", 64); + uc_pdata->aarch64 = dev_read_u32_default(dev, "aarch64", 1); #else - uc_pdata->aarch = dev_read_u32_default(dev, "aarch", 32); + uc_pdata->aarch64 = 0; #endif + uc_pdata->hyp = dev_read_u32_default(dev, "hyp", 0); + uc_pdata->thumb = dev_read_u32_default(dev, "thumb", 0); + uc_pdata->secure = dev_read_u32_default(dev, "secure", 0); uc_pdata->load = dev_read_u32_default(dev, "load", -ENODATA); uc_pdata->entry = dev_read_u32_default(dev, "entry", -ENODATA); @@ -115,9 +118,7 @@ static int amp_pre_probe(struct udevice *dev) if (!uc_pdata->desc || !uc_pdata->partition || uc_pdata->cpu == -ENODATA || uc_pdata->load == -ENODATA || - uc_pdata->entry == -ENODATA || !uc_pdata->reserved_mem[0] || - !uc_pdata->reserved_mem[1] || - (uc_pdata->aarch != 64 && uc_pdata->aarch != 32)) { + uc_pdata->entry == -ENODATA) { printf("AMP: \"%s\" is not complete\n", dev->name); return -EINVAL; } @@ -127,7 +128,10 @@ static int amp_pre_probe(struct udevice *dev) printf(" descrption: %s\n", uc_pdata->desc); printf(" partition: %s\n", uc_pdata->partition); printf(" cpu: 0x%x\n", uc_pdata->cpu); - printf(" aarch: %d\n", uc_pdata->aarch); + printf(" aarch64: %d\n", uc_pdata->aarch64); + printf(" hyp: %d\n", uc_pdata->hyp); + printf(" thumb: %d\n", uc_pdata->thumb); + printf(" secure: %d\n", uc_pdata->secure); printf(" load: 0x%08x\n", uc_pdata->load); printf(" entry: 0x%08x\n", uc_pdata->entry); printf(" reserved_mem: 0x%08x - 0x%08x\n\n", diff --git a/drivers/cpu/rockchip_amp.c b/drivers/cpu/rockchip_amp.c index 6ca0850d35..d07d876077 100644 --- a/drivers/cpu/rockchip_amp.c +++ b/drivers/cpu/rockchip_amp.c @@ -93,6 +93,10 @@ err: * description = "mcu-os1"; * partition = "mcu1"; * cpu = <0x1>; // this is mpidr! + * aarch64 = <1>; // 0: aarch32, 1: aarch64 + * thumb = <0>; // 0: arm, 1: thumb + * hyp = <1>; // 0: el1/svc, 1: el2/hyp + * secure = <0>; // 0: non-secure, 1: secure * load = <0x800000>; * entry = <0x800000>; * memory = <0x800000 0x400000>; @@ -105,8 +109,10 @@ err: * ...... * }; * - * U-Boot loads "mcu-os1" firmware to "0x800000" address from partiton - * "mcu1" for cpu[1], the cpu[1] entry address is 0x800000. And + * U-Boot load "mcu-os1" firmware to "0x800000" address from partiton + * "mcu1" for cpu[1] with ARM, aarch64, hyp(el2) and non-secure state, + * running on 0x800000. + * * U-Boot reserve memory from 0x800000 with 0x400000 size in order * to make it invisible for kernel. * @@ -120,6 +126,7 @@ static int rockchip_amp_cpu_on(struct udevice *dev) struct blk_desc *dev_desc; disk_partition_t part_info; int ret, size; + u32 pe_state; uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata) @@ -136,14 +143,17 @@ static int rockchip_amp_cpu_on(struct udevice *dev) return ret; } - ret = bidram_reserve_by_name(uc_pdata->partition, - uc_pdata->reserved_mem[0], - uc_pdata->reserved_mem[1]); - if (ret) { - AMP_E("Reserve \"%s\" region at 0x%08x - 0x%08x failed, ret=%d\n", - uc_pdata->desc, uc_pdata->reserved_mem[0], - uc_pdata->reserved_mem[0] + uc_pdata->reserved_mem[1], ret); - return -ENOMEM; + if (uc_pdata->reserved_mem[1]) { + ret = bidram_reserve_by_name(uc_pdata->partition, + uc_pdata->reserved_mem[0], + uc_pdata->reserved_mem[1]); + if (ret) { + AMP_E("Reserve \"%s\" region at 0x%08x - 0x%08x failed, ret=%d\n", + uc_pdata->desc, uc_pdata->reserved_mem[0], + uc_pdata->reserved_mem[0] + + uc_pdata->reserved_mem[1], ret); + return -ENOMEM; + } } size = read_rockchip_image(dev_desc, &part_info, @@ -157,9 +167,13 @@ static int rockchip_amp_cpu_on(struct udevice *dev) flush_dcache_range(uc_pdata->load, uc_pdata->load + ALIGN(size, ARCH_DMA_MINALIGN)); - AMP_I("Brought up cpu[%x] on \"%s\" entry 0x%08x ...", - uc_pdata->cpu, uc_pdata->desc, uc_pdata->entry); + pe_state = PE_STATE(uc_pdata->aarch64, uc_pdata->hyp, + uc_pdata->thumb, uc_pdata->secure); + AMP_I("Brought up cpu[%x] with state(%x) from \"%s\" entry 0x%08x ...", + uc_pdata->cpu, pe_state, uc_pdata->desc, uc_pdata->entry); + + sip_smc_amp_cfg(AMP_PE_STATE, uc_pdata->cpu, pe_state); ret = psci_cpu_on(uc_pdata->cpu, uc_pdata->entry); if (ret) { printf("failed\n"); diff --git a/include/amp.h b/include/amp.h index 629dcdcd04..a6bb55279b 100644 --- a/include/amp.h +++ b/include/amp.h @@ -8,6 +8,22 @@ #include +#define MAP_AARCH(aarch64) ((aarch64) ? 1 : 0) +#define MAP_HYP(hyp) ((hyp) ? 1 : 0) +#define MAP_THUMB(thumb) ((thumb) ? 1 : 0) +#define MAP_SECURE(secure) ((secure) ? 0 : 1) + +#define MODE_AARCH64_SHIFT 1 +#define MODE_HYP_SHIFT 2 +#define MODE_THUMB_SHIFT 3 +#define MODE_SECURE_SHIFT 4 + +#define PE_STATE(aarch64, hyp, thumb, secure) \ + (((MAP_AARCH(aarch64) & 0x1) << MODE_AARCH64_SHIFT) | \ + ((MAP_HYP(hyp) & 0x1) << MODE_HYP_SHIFT) | \ + ((MAP_THUMB(thumb) & 0x1) << MODE_THUMB_SHIFT) | \ + ((MAP_SECURE(secure) & 0x1) << MODE_SECURE_SHIFT)) + struct dm_amp_ops { int (*cpu_on)(struct udevice *dev); }; @@ -16,7 +32,10 @@ struct dm_amp_uclass_platdata { const char *desc; const char *partition; u32 cpu; /* cpu mpidr */ - u32 aarch; + u32 aarch64; + u32 hyp; + u32 thumb; + u32 secure; u32 load; u32 entry; u32 reserved_mem[2]; /* [0]: start, [1]: size */ @@ -27,3 +46,4 @@ int amp_cpus_on(void); int amp_cpu_on(u32 cpu); #endif /* _AMP_H_ */ +