platform: generic: mips p8700: cache geometry detection

P8700 has a read-only cache configuration registers.
Provide a CPU specific function to extract cache information.
Use this information in the eyeq7h board for informational
message

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260223-for-upstream-eyeq7h-v3-14-621d004d1a21@mobileye.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Vladimir Kondratiev
2026-02-23 16:54:53 +02:00
committed by Anup Patel
parent 8935f79c95
commit df7bbe7c2e
3 changed files with 126 additions and 0 deletions

View File

@@ -58,6 +58,14 @@ extern const struct p8700_cm_info *p8700_cm_info;
#define CSR_MIPSCONFIG10 0x7da
#define CSR_MIPSCONFIG11 0x7db
#define MIPSCONFIG1_L2C BIT(31)
#define MIPSCONFIG1_IS GENMASK(24,22)
#define MIPSCONFIG1_IL GENMASK(21,19)
#define MIPSCONFIG1_IA GENMASK(18,16)
#define MIPSCONFIG1_DS GENMASK(15,13)
#define MIPSCONFIG1_DL GENMASK(12,10)
#define MIPSCONFIG1_DA GENMASK(9,7)
#define MIPSCONFIG5_MTW 4
#define GEN_MASK(h, l) (((1ul << ((h) + 1 - (l))) - 1) << (l))
@@ -113,6 +121,43 @@ extern const struct p8700_cm_info *p8700_cm_info;
#define L2_PFT_CONTROL_OFFSET 0x0300
#define L2_PFT_CONTROL_B_OFFSET 0x0308
#define GCR_L2_CONFIG 0x0130
#define GCR_L2_ASSOC GENMASK(7, 0)
#define GCR_L2_LINE_SIZE GENMASK(11, 8)
#define GCR_L2_SET_SIZE GENMASK(15, 12)
#define GCR_L2_BYPASS BIT(20)
#define GCR_L2_COP_DATA_ECC_WE BIT(24)
#define GCR_L2_COP_TAG_ECC_WE BIT(25)
#define GCR_L2_COP_LRU_WE BIT(26)
#define GCR_L2_REG_EXISTS BIT(31)
#define GCR_L2_TAG_ADDR 0x0600
#define GCR_L2_TAG_STATE 0x0608
#define GCR_L2_DATA 0x0610
#define GCR_L2_ECC 0x0618
#define GCR_L2SM_COP 0x0620
#define GCR_L2SM_COP_CMD GENMASK(1, 0)
#define L2SM_COP_CMD_NOP 0
#define L2SM_COP_CMD_START 1
#define L2SM_COP_CMD_ABORT 3
#define GCR_L2SM_COP_TYPE GENMASK(4, 2)
#define L2SM_COP_TYPE_IDX_WBINV 0
#define L2SM_COP_TYPE_IDX_STORETAG 1
#define L2SM_COP_TYPE_IDX_STORETAGDATA 2
#define L2SM_COP_TYPE_HIT_INV 4
#define L2SM_COP_TYPE_HIT_WBINV 5
#define L2SM_COP_TYPE_HIT_WB 6
#define L2SM_COP_TYPE_FETCHLOCK 7
#define GCR_L2SM_COP_RUNNING BIT(5)
#define GCR_L2SM_COP_RESULT GENMASK(8, 6)
#define L2SM_COP_RESULT_DONTCARE 0
#define L2SM_COP_RESULT_DONE_OK 1
#define L2SM_COP_RESULT_DONE_ERROR 2
#define L2SM_COP_RESULT_ABORT_OK 3
#define L2SM_COP_RESULT_ABORT_ERROR 4
#define GCR_L2SM_COP_PRESENT BIT(31)
/* CPC Block offsets */
#define CPC_PWRUP_CTL 0x0030
#define CPC_CM_STAT_CONF 0x1008
@@ -138,6 +183,15 @@ void mips_p8700_pmp_set(unsigned int n, unsigned long flags,
void mips_p8700_power_up_other_cluster(u32 hartid);
int mips_p8700_hart_start(u32 hartid, ulong saddr);
int mips_p8700_hart_stop(void);
struct p8700_cache_info {
u32 line;
u32 assoc_ways;
u32 sets;
};
void mips_p8700_cache_info(struct p8700_cache_info *l1d, struct p8700_cache_info *l1i,
struct p8700_cache_info *l2);
struct fdt_match;
int mips_p8700_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match);

View File

@@ -171,6 +171,32 @@ static struct fdt_general_fixup eyeq7h_acc_clusters_fixup = {
.do_fixup = eyeq7h_acc_clusters_do_fixup,
};
static void eyeq7h_cache_do_fixup(struct fdt_general_fixup *f, void *fdt)
{
struct p8700_cache_info l1d, l1i, l2;
mips_p8700_cache_info(&l1d, &l1i, &l2);
sbi_dprintf("Cache geometry:\n"
" D: %4d Kbytes line %3d bytes %2d ways %5d sets\n"
" I: %4d Kbytes line %3d bytes %2d ways %5d sets\n",
l1d.assoc_ways * l1d.line * l1d.sets / 1024,
l1d.line, l1d.assoc_ways, l1d.sets,
l1i.assoc_ways * l1i.line * l1i.sets / 1024,
l1i.line, l1i.assoc_ways, l1i.sets);
if (l2.line) {
sbi_dprintf(" L2: %4d Kbytes line %3d bytes %2d ways %5d sets\n",
l2.assoc_ways * l2.line * l2.sets / 1024,
l2.line, l2.assoc_ways, l2.sets);
} else {
sbi_dprintf(" L2: not present\n");
}
}
static struct fdt_general_fixup eyeq7h_cache_fixup = {
.name = "cache-fixup",
.do_fixup = eyeq7h_cache_do_fixup,
};
static int eyeq7h_final_init(bool cold_boot)
{
if (!cold_boot)
@@ -178,6 +204,7 @@ static int eyeq7h_final_init(bool cold_boot)
sbi_hsm_set_device(&eyeq7h_hsm);
fdt_register_general_fixup(&eyeq7h_acc_clusters_fixup);
fdt_register_general_fixup(&eyeq7h_cache_fixup);
return generic_final_init(cold_boot);
}

View File

@@ -123,6 +123,51 @@ int mips_p8700_hart_stop()
return 0;
}
void mips_p8700_cache_info(struct p8700_cache_info *l1d, struct p8700_cache_info *l1i,
struct p8700_cache_info *l2)
{
u32 mipsconfig1 = csr_read(CSR_MIPSCONFIG1);
if (l1d) {
u32 da = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_DA);
u32 dl = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_DL);
u32 ds = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_DS);
l1d->line = dl ? 1 << (dl + 1) : 0;
l1d->assoc_ways = da +1;
l1d->sets = ds == 7 ? 32 : 1 << (ds + 6);
}
if (l1i) {
u32 ia = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_IA);
u32 il = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_IL);
u32 is = EXTRACT_FIELD(mipsconfig1, MIPSCONFIG1_IS);
l1i->line = il ? 1 << (il + 1) : 0;
l1i->assoc_ways = ia +1;
l1i->sets = is == 7 ? 32 : 1 << (is + 6);
}
if (l2) {
if (mipsconfig1 & MIPSCONFIG1_L2C) {
void *cm_base = (void *)p8700_cm_info->gcr_base[0];
u32 l2_config = readl(cm_base + GCR_L2_CONFIG);
if (l2_config & GCR_L2_REG_EXISTS) {
u32 l2a = EXTRACT_FIELD(l2_config, GCR_L2_ASSOC);
u32 l2l = EXTRACT_FIELD(l2_config, GCR_L2_LINE_SIZE);
u32 l2s = EXTRACT_FIELD(l2_config, GCR_L2_SET_SIZE);
l2->assoc_ways = l2a + 1;
l2->line = 1 << (l2l + 1);
l2->sets = 1 << (l2s + 6);
return;
}
}
l2->line = 0;
l2->assoc_ways = 0;
l2->sets = 0;
}
}
int mips_p8700_platform_init(const void *fdt, int nodeoff, const struct fdt_match *match)
{
const struct p8700_cm_info *data = match->data;