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

Commit ca122fe3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ARC updates from Vineet Gupta:

 - more changes for HS48 cores: supporting MMUv5, detecting new
   micro-arch gizmos

 - axs10x platform wiring up reset driver merged in this cycle

 - ARC perf driver optimizations

* tag 'arc-4.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARC: perf: avoid vmalloc backed mmap
  ARCv2: perf: optimize given that num counters <= 32
  ARCv2: perf: tweak overflow interrupt
  ARC: [plat-axs10x] DTS: Add reset controller node to manage ethernet reset
  ARCv2: boot log: updates for HS48: dual-issue, ECC, Loop Buffer
  ARCv2: Accomodate HS48 MMUv5 by relaxing MMU ver checking
  ARC: [plat-axs10x] auto-select AXS101 or AXS103 given the  ISA config
parents 5e2fda47 82385732
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ config ARC
	select OF
	select OF_EARLY_FLATTREE
	select OF_RESERVED_MEM
	select PERF_USE_VMALLOC
	select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
	select HAVE_DEBUG_STACKOVERFLOW
	select HAVE_GENERIC_DMA_COHERENT
	select HAVE_KERNEL_GZIP
+8 −0
Original line number Diff line number Diff line
@@ -16,6 +16,12 @@
		ranges = <0x00000000 0x0 0xe0000000 0x10000000>;
		interrupt-parent = <&mb_intc>;

		creg_rst: reset-controller@11220 {
			compatible = "snps,axs10x-reset";
			#reset-cells = <1>;
			reg = <0x11220 0x4>;
		};

		i2sclk: i2sclk@100a0 {
			compatible = "snps,axs10x-i2s-pll-clock";
			reg = <0x100a0 0x10>;
@@ -73,6 +79,8 @@
			clocks = <&apbclk>;
			clock-names = "stmmaceth";
			max-speed = <100>;
			resets = <&creg_rst 5>;
			reset-names = "stmmaceth";
		};

		ehci@0x40000 {
+32 −1
Original line number Diff line number Diff line
@@ -11,12 +11,14 @@

/* Build Configuration Registers */
#define ARC_REG_AUX_DCCM	0x18	/* DCCM Base Addr ARCv2 */
#define ARC_REG_ERP_CTRL	0x3F	/* ARCv2 Error protection control */
#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
#define ARC_REG_FP_BCR		0x6B	/* ARCompact: Single-Precision FPU */
#define ARC_REG_DPFP_BCR	0x6C	/* ARCompact: Dbl Precision FPU */
#define ARC_REG_ERP_BUILD	0xc7	/* ARCv2 Error protection Build: ECC/Parity */
#define ARC_REG_FP_V2_BCR	0xc8	/* ARCv2 FPU */
#define ARC_REG_SLC_BCR		0xce
#define ARC_REG_DCCM_BUILD	0x74	/* DCCM size (common) */
@@ -32,11 +34,14 @@
#define ARC_REG_D_UNCACH_BCR	0x6A
#define ARC_REG_BPU_BCR		0xc0
#define ARC_REG_ISA_CFG_BCR	0xc1
#define ARC_REG_LPB_BUILD	0xE9	/* ARCv2 Loop Buffer Build */
#define ARC_REG_RTT_BCR		0xF2
#define ARC_REG_IRQ_BCR		0xF3
#define ARC_REG_MICRO_ARCH_BCR	0xF9	/* ARCv2 Product revision */
#define ARC_REG_SMART_BCR	0xFF
#define ARC_REG_CLUSTER_BCR	0xcf
#define ARC_REG_AUX_ICCM	0x208	/* ICCM Base Addr (ARCv2) */
#define ARC_REG_LPB_CTRL	0x488	/* ARCv2 Loop Buffer control */

/* Common for ARCompact and ARCv2 status register */
#define ARC_REG_STATUS32	0x0A
@@ -229,6 +234,32 @@ struct bcr_bpu_arcv2 {
#endif
};

/* Error Protection Build: ECC/Parity */
struct bcr_erp {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int pad3:5, mmu:3, pad2:4, ic:3, dc:3, pad1:6, ver:8;
#else
	unsigned int ver:8, pad1:6, dc:3, ic:3, pad2:4, mmu:3, pad3:5;
#endif
};

/* Error Protection Control */
struct ctl_erp {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int pad2:27, mpd:1, pad1:2, dpd:1, dpi:1;
#else
	unsigned int dpi:1, dpd:1, pad1:2, mpd:1, pad2:27;
#endif
};

struct bcr_lpb {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int pad:16, entries:8, ver:8;
#else
	unsigned int ver:8, entries:8, pad:16;
#endif
};

struct bcr_generic {
#ifdef CONFIG_CPU_BIG_ENDIAN
	unsigned int info:24, ver:8;
@@ -270,7 +301,7 @@ struct cpuinfo_arc {
	struct cpuinfo_arc_ccm iccm, dccm;
	struct {
		unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, swape:1, pad1:2,
			     fpu_sp:1, fpu_dp:1, dual_iss_enb:1, dual_iss_exist:1, pad2:4,
			     fpu_sp:1, fpu_dp:1, dual:1, dual_enb:1, pad2:4,
			     debug:1, ap:1, smart:1, rtt:1, pad3:4,
			     timer0:1, timer1:1, rtc:1, gfrc:1, pad4:4;
	} extn;
+21 −19
Original line number Diff line number Diff line
@@ -336,15 +336,12 @@ static int arc_pmu_add(struct perf_event *event, int flags)
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	if (__test_and_set_bit(idx, pmu_cpu->used_mask)) {
		idx = find_first_zero_bit(pmu_cpu->used_mask,
					  arc_pmu->n_counters);
	idx = ffz(pmu_cpu->used_mask[0]);
	if (idx == arc_pmu->n_counters)
		return -EAGAIN;

	__set_bit(idx, pmu_cpu->used_mask);
	hwc->idx = idx;
	}

	write_aux_reg(ARC_REG_PCT_INDEX, idx);

@@ -377,21 +374,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
	struct perf_sample_data data;
	struct arc_pmu_cpu *pmu_cpu = this_cpu_ptr(&arc_pmu_cpu);
	struct pt_regs *regs;
	int active_ints;
	unsigned int active_ints;
	int idx;

	arc_pmu_disable(&arc_pmu->pmu);

	active_ints = read_aux_reg(ARC_REG_PCT_INT_ACT);
	if (!active_ints)
		goto done;

	regs = get_irq_regs();

	for (idx = 0; idx < arc_pmu->n_counters; idx++) {
		struct perf_event *event = pmu_cpu->act_counter[idx];
	do {
		struct perf_event *event;
		struct hw_perf_event *hwc;

		if (!(active_ints & (1 << idx)))
			continue;
		idx = __ffs(active_ints);

		/* Reset interrupt flag by writing of 1 */
		write_aux_reg(ARC_REG_PCT_INT_ACT, 1 << idx);
@@ -404,19 +402,22 @@ static irqreturn_t arc_pmu_intr(int irq, void *dev)
		write_aux_reg(ARC_REG_PCT_INT_CTRL,
			read_aux_reg(ARC_REG_PCT_INT_CTRL) | (1 << idx));

		event = pmu_cpu->act_counter[idx];
		hwc = &event->hw;

		WARN_ON_ONCE(hwc->idx != idx);

		arc_perf_event_update(event, &event->hw, event->hw.idx);
		perf_sample_data_init(&data, 0, hwc->last_period);
		if (!arc_pmu_event_set_period(event))
			continue;

		if (arc_pmu_event_set_period(event)) {
			if (perf_event_overflow(event, &data, regs))
				arc_pmu_stop(event, 0);
		}

		active_ints &= ~(1U << idx);
	} while (active_ints);

done:
	arc_pmu_enable(&arc_pmu->pmu);

	return IRQ_HANDLED;
@@ -461,6 +462,7 @@ static int arc_pmu_device_probe(struct platform_device *pdev)
		pr_err("This core does not have performance counters!\n");
		return -ENODEV;
	}
	BUILD_BUG_ON(ARC_PERF_MAX_COUNTERS > 32);
	BUG_ON(pct_bcr.c > ARC_PERF_MAX_COUNTERS);

	READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
+39 −4
Original line number Diff line number Diff line
@@ -199,8 +199,10 @@ static void read_arc_build_cfg_regs(void)
			unsigned int exec_ctrl;

			READ_BCR(AUX_EXEC_CTRL, exec_ctrl);
			cpu->extn.dual_iss_exist = 1;
			cpu->extn.dual_iss_enb = exec_ctrl & 1;
			cpu->extn.dual_enb = exec_ctrl & 1;

			/* dual issue always present for this core */
			cpu->extn.dual = 1;
		}
	}

@@ -253,7 +255,7 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
		       cpu_id, cpu->name, cpu->details,
		       is_isa_arcompact() ? "ARCompact" : "ARCv2",
		       IS_AVAIL1(cpu->isa.be, "[Big-Endian]"),
		       IS_AVAIL3(cpu->extn.dual_iss_exist, cpu->extn.dual_iss_enb, " Dual-Issue"));
		       IS_AVAIL3(cpu->extn.dual, cpu->extn.dual_enb, " Dual-Issue "));

	n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s%s%s\nISA Extn\t: ",
		       IS_AVAIL1(cpu->extn.timer0, "Timer0 "),
@@ -293,11 +295,26 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)

	if (cpu->bpu.ver)
		n += scnprintf(buf + n, len - n,
			      "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n",
			      "BPU\t\t: %s%s match, cache:%d, Predict Table:%d",
			      IS_AVAIL1(cpu->bpu.full, "full"),
			      IS_AVAIL1(!cpu->bpu.full, "partial"),
			      cpu->bpu.num_cache, cpu->bpu.num_pred);

	if (is_isa_arcv2()) {
		struct bcr_lpb lpb;

		READ_BCR(ARC_REG_LPB_BUILD, lpb);
		if (lpb.ver) {
			unsigned int ctl;
			ctl = read_aux_reg(ARC_REG_LPB_CTRL);

			n += scnprintf(buf + n, len - n, " Loop Buffer:%d %s",
				lpb.entries,
				IS_DISABLED_RUN(!ctl));
		}
	}

	n += scnprintf(buf + n, len - n, "\n");
	return buf;
}

@@ -326,6 +343,24 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
			       cpu->dccm.base_addr, TO_KB(cpu->dccm.sz),
			       cpu->iccm.base_addr, TO_KB(cpu->iccm.sz));

	if (is_isa_arcv2()) {

		/* Error Protection: ECC/Parity */
		struct bcr_erp erp;
		READ_BCR(ARC_REG_ERP_BUILD, erp);

		if (erp.ver) {
			struct  ctl_erp ctl;
			READ_BCR(ARC_REG_ERP_CTRL, ctl);

			/* inverted bits: 0 means enabled */
			n += scnprintf(buf + n, len - n, "Extn [ECC]\t: %s%s%s%s%s%s\n",
				IS_AVAIL3(erp.ic,  !ctl.dpi, "IC "),
				IS_AVAIL3(erp.dc,  !ctl.dpd, "DC "),
				IS_AVAIL3(erp.mmu, !ctl.mpd, "MMU "));
		}
	}

	n += scnprintf(buf + n, len - n, "OS ABI [v%d]\t: %s\n",
			EF_ARC_OSABI_CURRENT >> 8,
			EF_ARC_OSABI_CURRENT == EF_ARC_OSABI_V3 ?
Loading