cpu: rockchip amp: support set PE state

Signed-off-by: Joseph Chen <chenjh@rock-chips.com>
Change-Id: I6b5eb621af1472983cdfbaebfdaa61a4c85b1856
This commit is contained in:
Joseph Chen 2021-02-03 14:39:31 +08:00 committed by Jianhong Chen
parent c3e08fa050
commit f06413e433
3 changed files with 57 additions and 19 deletions

View File

@ -102,10 +102,13 @@ static int amp_pre_probe(struct udevice *dev)
uc_pdata->partition = dev_read_string(dev, "partition"); uc_pdata->partition = dev_read_string(dev, "partition");
uc_pdata->cpu = dev_read_u32_default(dev, "cpu", -ENODATA); uc_pdata->cpu = dev_read_u32_default(dev, "cpu", -ENODATA);
#ifdef CONFIG_ARM64 #ifdef CONFIG_ARM64
uc_pdata->aarch = dev_read_u32_default(dev, "aarch", 64); uc_pdata->aarch64 = dev_read_u32_default(dev, "aarch64", 1);
#else #else
uc_pdata->aarch = dev_read_u32_default(dev, "aarch", 32); uc_pdata->aarch64 = 0;
#endif #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->load = dev_read_u32_default(dev, "load", -ENODATA);
uc_pdata->entry = dev_read_u32_default(dev, "entry", -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 || if (!uc_pdata->desc || !uc_pdata->partition ||
uc_pdata->cpu == -ENODATA || uc_pdata->load == -ENODATA || uc_pdata->cpu == -ENODATA || uc_pdata->load == -ENODATA ||
uc_pdata->entry == -ENODATA || !uc_pdata->reserved_mem[0] || uc_pdata->entry == -ENODATA) {
!uc_pdata->reserved_mem[1] ||
(uc_pdata->aarch != 64 && uc_pdata->aarch != 32)) {
printf("AMP: \"%s\" is not complete\n", dev->name); printf("AMP: \"%s\" is not complete\n", dev->name);
return -EINVAL; return -EINVAL;
} }
@ -127,7 +128,10 @@ static int amp_pre_probe(struct udevice *dev)
printf(" descrption: %s\n", uc_pdata->desc); printf(" descrption: %s\n", uc_pdata->desc);
printf(" partition: %s\n", uc_pdata->partition); printf(" partition: %s\n", uc_pdata->partition);
printf(" cpu: 0x%x\n", uc_pdata->cpu); 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(" load: 0x%08x\n", uc_pdata->load);
printf(" entry: 0x%08x\n", uc_pdata->entry); printf(" entry: 0x%08x\n", uc_pdata->entry);
printf(" reserved_mem: 0x%08x - 0x%08x\n\n", printf(" reserved_mem: 0x%08x - 0x%08x\n\n",

View File

@ -93,6 +93,10 @@ err:
* description = "mcu-os1"; * description = "mcu-os1";
* partition = "mcu1"; * partition = "mcu1";
* cpu = <0x1>; // this is mpidr! * 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>; * load = <0x800000>;
* entry = <0x800000>; * entry = <0x800000>;
* memory = <0x800000 0x400000>; * memory = <0x800000 0x400000>;
@ -105,8 +109,10 @@ err:
* ...... * ......
* }; * };
* *
* U-Boot loads "mcu-os1" firmware to "0x800000" address from partiton * U-Boot load "mcu-os1" firmware to "0x800000" address from partiton
* "mcu1" for cpu[1], the cpu[1] entry address is 0x800000. And * "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 * U-Boot reserve memory from 0x800000 with 0x400000 size in order
* to make it invisible for kernel. * to make it invisible for kernel.
* *
@ -120,6 +126,7 @@ static int rockchip_amp_cpu_on(struct udevice *dev)
struct blk_desc *dev_desc; struct blk_desc *dev_desc;
disk_partition_t part_info; disk_partition_t part_info;
int ret, size; int ret, size;
u32 pe_state;
uc_pdata = dev_get_uclass_platdata(dev); uc_pdata = dev_get_uclass_platdata(dev);
if (!uc_pdata) if (!uc_pdata)
@ -136,14 +143,17 @@ static int rockchip_amp_cpu_on(struct udevice *dev)
return ret; return ret;
} }
ret = bidram_reserve_by_name(uc_pdata->partition, if (uc_pdata->reserved_mem[1]) {
uc_pdata->reserved_mem[0], ret = bidram_reserve_by_name(uc_pdata->partition,
uc_pdata->reserved_mem[1]); uc_pdata->reserved_mem[0],
if (ret) { uc_pdata->reserved_mem[1]);
AMP_E("Reserve \"%s\" region at 0x%08x - 0x%08x failed, ret=%d\n", if (ret) {
uc_pdata->desc, uc_pdata->reserved_mem[0], AMP_E("Reserve \"%s\" region at 0x%08x - 0x%08x failed, ret=%d\n",
uc_pdata->reserved_mem[0] + uc_pdata->reserved_mem[1], ret); uc_pdata->desc, uc_pdata->reserved_mem[0],
return -ENOMEM; uc_pdata->reserved_mem[0] +
uc_pdata->reserved_mem[1], ret);
return -ENOMEM;
}
} }
size = read_rockchip_image(dev_desc, &part_info, 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, flush_dcache_range(uc_pdata->load,
uc_pdata->load + ALIGN(size, ARCH_DMA_MINALIGN)); uc_pdata->load + ALIGN(size, ARCH_DMA_MINALIGN));
AMP_I("Brought up cpu[%x] on \"%s\" entry 0x%08x ...", pe_state = PE_STATE(uc_pdata->aarch64, uc_pdata->hyp,
uc_pdata->cpu, uc_pdata->desc, uc_pdata->entry); 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); ret = psci_cpu_on(uc_pdata->cpu, uc_pdata->entry);
if (ret) { if (ret) {
printf("failed\n"); printf("failed\n");

View File

@ -8,6 +8,22 @@
#include <dm.h> #include <dm.h>
#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 { struct dm_amp_ops {
int (*cpu_on)(struct udevice *dev); int (*cpu_on)(struct udevice *dev);
}; };
@ -16,7 +32,10 @@ struct dm_amp_uclass_platdata {
const char *desc; const char *desc;
const char *partition; const char *partition;
u32 cpu; /* cpu mpidr */ u32 cpu; /* cpu mpidr */
u32 aarch; u32 aarch64;
u32 hyp;
u32 thumb;
u32 secure;
u32 load; u32 load;
u32 entry; u32 entry;
u32 reserved_mem[2]; /* [0]: start, [1]: size */ u32 reserved_mem[2]; /* [0]: start, [1]: size */
@ -27,3 +46,4 @@ int amp_cpus_on(void);
int amp_cpu_on(u32 cpu); int amp_cpu_on(u32 cpu);
#endif /* _AMP_H_ */ #endif /* _AMP_H_ */