Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a150b085 authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARCv2: boot report CCMs (Closely Coupled Memories)



- ARCv2 uses a seperate BCR for {I,D}CCM base address:
  ARCompact encoded both base/size in same BCR

- Size encoding in common BCR is different for ARCompact/ARCv2

Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent 98341f7d
Loading
Loading
Loading
Loading
+20 −12
Original line number Diff line number Diff line
@@ -10,7 +10,8 @@
#define _ASM_ARC_ARCREGS_H

/* Build Configuration Registers */
#define ARC_REG_DCCMBASE_BCR	0x61	/* DCCM Base Addr */
#define ARC_REG_AUX_DCCM	0x18	/* DCCM Base Addr ARCv2 */
#define ARC_REG_DCCM_BASE_BUILD	0x61	/* DCCM Base Addr ARCompact */
#define ARC_REG_CRC_BCR		0x62
#define ARC_REG_VECBASE_BCR	0x68
#define ARC_REG_PERIBASE_BCR	0x69
@@ -18,10 +19,10 @@
#define ARC_REG_DPFP_BCR	0x6C	/* ARCompact: Dbl Precision FPU */
#define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
#define ARC_REG_SLC_BCR		0xce
#define ARC_REG_DCCM_BCR	0x74	/* DCCM Present + SZ */
#define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
#define ARC_REG_TIMERS_BCR	0x75
#define ARC_REG_AP_BCR		0x76
#define ARC_REG_ICCM_BCR	0x78
#define ARC_REG_ICCM_BUILD	0x78	/* ICCM size (common) */
#define ARC_REG_XY_MEM_BCR	0x79
#define ARC_REG_MAC_BCR		0x7a
#define ARC_REG_MUL_BCR		0x7b
@@ -36,6 +37,7 @@
#define ARC_REG_IRQ_BCR		0xF3
#define ARC_REG_SMART_BCR	0xFF
#define ARC_REG_CLUSTER_BCR	0xcf
#define ARC_REG_AUX_ICCM	0x208	/* ICCM Base Addr (ARCv2) */

/* status32 Bits Positions */
#define STATUS_AE_BIT		5	/* Exception active */
@@ -246,7 +248,7 @@ struct bcr_perip {
#endif
};

struct bcr_iccm {
struct bcr_iccm_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int base:16, pad:5, sz:3, ver:8;
#else
@@ -254,17 +256,15 @@ struct bcr_iccm {
#endif
};

/* DCCM Base Address Register: ARC_REG_DCCMBASE_BCR */
struct bcr_dccm_base {
struct bcr_iccm_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int addr:24, ver:8;
	unsigned int pad:8, sz11:4, sz01:4, sz10:4, sz00:4, ver:8;
#else
	unsigned int ver:8, addr:24;
	unsigned int ver:8, sz00:4, sz10:4, sz01:4, sz11:4, pad:8;
#endif
};

/* DCCM RAM Configuration Register: ARC_REG_DCCM_BCR */
struct bcr_dccm {
struct bcr_dccm_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int res:21, sz:3, ver:8;
#else
@@ -272,6 +272,14 @@ struct bcr_dccm {
#endif
};

struct bcr_dccm_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int pad2:12, cyc:3, pad1:1, sz1:4, sz0:4, ver:8;
#else
	unsigned int ver:8, sz0:4, sz1:4, pad1:1, cyc:3, pad2:12;
#endif
};

/* ARCompact: Both SP and DP FPU BCRs have same format */
struct bcr_fp_arcompact {
#ifdef CONFIG_CPU_BIG_ENDIAN
@@ -315,9 +323,9 @@ struct bcr_bpu_arcv2 {

struct bcr_generic {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int pad:24, ver:8;
	unsigned int info:24, ver:8;
#else
	unsigned int ver:8, pad:24;
	unsigned int ver:8, info:24;
#endif
};

+50 −28
Original line number Diff line number Diff line
@@ -42,6 +42,53 @@ struct task_struct *_current_task[NR_CPUS]; /* For stack switching */

struct cpuinfo_arc cpuinfo_arc700[NR_CPUS];

static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu)
{
	if (is_isa_arcompact()) {
		struct bcr_iccm_arcompact iccm;
		struct bcr_dccm_arcompact dccm;

		READ_BCR(ARC_REG_ICCM_BUILD, iccm);
		if (iccm.ver) {
			cpu->iccm.sz = 4096 << iccm.sz;	/* 8K to 512K */
			cpu->iccm.base_addr = iccm.base << 16;
		}

		READ_BCR(ARC_REG_DCCM_BUILD, dccm);
		if (dccm.ver) {
			unsigned long base;
			cpu->dccm.sz = 2048 << dccm.sz;	/* 2K to 256K */

			base = read_aux_reg(ARC_REG_DCCM_BASE_BUILD);
			cpu->dccm.base_addr = base & ~0xF;
		}
	} else {
		struct bcr_iccm_arcv2 iccm;
		struct bcr_dccm_arcv2 dccm;
		unsigned long region;

		READ_BCR(ARC_REG_ICCM_BUILD, iccm);
		if (iccm.ver) {
			cpu->iccm.sz = 256 << iccm.sz00;	/* 512B to 16M */
			if (iccm.sz00 == 0xF && iccm.sz01 > 0)
				cpu->iccm.sz <<= iccm.sz01;

			region = read_aux_reg(ARC_REG_AUX_ICCM);
			cpu->iccm.base_addr = region & 0xF0000000;
		}

		READ_BCR(ARC_REG_DCCM_BUILD, dccm);
		if (dccm.ver) {
			cpu->dccm.sz = 256 << dccm.sz0;
			if (dccm.sz0 == 0xF && dccm.sz1 > 0)
				cpu->dccm.sz <<= dccm.sz1;

			region = read_aux_reg(ARC_REG_AUX_DCCM);
			cpu->dccm.base_addr = region & 0xF0000000;
		}
	}
}

static void read_arc_build_cfg_regs(void)
{
	struct bcr_perip uncached_space;
@@ -76,36 +123,11 @@ static void read_arc_build_cfg_regs(void)
	cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0;        /* 1,3 */
	cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0;
	cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */

	/* Note that we read the CCM BCRs independent of kernel config
	 * This is to catch the cases where user doesn't know that
	 * CCMs are present in hardware build
	 */
	{
		struct bcr_iccm iccm;
		struct bcr_dccm dccm;
		struct bcr_dccm_base dccm_base;
		unsigned int bcr_32bit_val;

		bcr_32bit_val = read_aux_reg(ARC_REG_ICCM_BCR);
		if (bcr_32bit_val) {
			iccm = *((struct bcr_iccm *)&bcr_32bit_val);
			cpu->iccm.base_addr = iccm.base << 16;
			cpu->iccm.sz = 0x2000 << (iccm.sz - 1);
		}

		bcr_32bit_val = read_aux_reg(ARC_REG_DCCM_BCR);
		if (bcr_32bit_val) {
			dccm = *((struct bcr_dccm *)&bcr_32bit_val);
			cpu->dccm.sz = 0x800 << (dccm.sz);

			READ_BCR(ARC_REG_DCCMBASE_BCR, dccm_base);
			cpu->dccm.base_addr = dccm_base.addr << 8;
		}
	}

	READ_BCR(ARC_REG_XY_MEM_BCR, cpu->extn_xymem);

	/* Read CCM BCRs for boot reporting even if not enabled in Kconfig */
	read_decode_ccm_bcr(cpu);

	read_decode_mmu_bcr();
	read_decode_cache_bcr();