Unverified Commit 377be47f authored by Charlie Jenkins's avatar Charlie Jenkins Committed by Palmer Dabbelt
Browse files

riscv: vector: Use vlenb from DT for thead



If thead,vlenb is provided in the device tree, prefer that over reading
the vlenb csr.

Signed-off-by: default avatarCharlie Jenkins <charlie@rivosinc.com>
Acked-by: default avatarConor Dooley <conor.dooley@microchip.com>
Tested-by: default avatarYangyu Chen <cyy@cyyself.name>
Link: https://lore.kernel.org/r/20241113-xtheadvector-v11-5-236c22791ef9@rivosinc.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent cddd6386
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -26,6 +26,19 @@ config RISCV_ISA_VENDOR_EXT_THEAD
	  extensions. Without this option enabled, T-Head vendor extensions will
	  not be detected at boot and their presence not reported to userspace.

	  If you don't know what to do here, say Y.

config RISCV_ISA_XTHEADVECTOR
	bool "xtheadvector extension support"
	depends on RISCV_ISA_VENDOR_EXT_THEAD
	depends on RISCV_ISA_V
	depends on FPU
	default y
	help
	  Say N here if you want to disable all xtheadvector related procedures
	  in the kernel. This will disable vector for any T-Head board that
	  contains xtheadvector rather than the standard vector.

	  If you don't know what to do here, say Y.
endmenu

+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
/* Per-cpu ISA extensions. */
extern struct riscv_isainfo hart_isa[NR_CPUS];

extern u32 thead_vlenb_of;

void __init riscv_user_isa_enable(void);

#define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) {	\
+6 −0
Original line number Diff line number Diff line
@@ -13,4 +13,10 @@

extern struct riscv_isa_vendor_ext_data_list riscv_isa_vendor_ext_list_thead;

#ifdef CONFIG_RISCV_ISA_VENDOR_EXT_THEAD
void disable_xtheadvector(void);
#else
static inline void disable_xtheadvector(void) { }
#endif

#endif
+48 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
/* Per-cpu ISA extensions. */
struct riscv_isainfo hart_isa[NR_CPUS];

u32 thead_vlenb_of;

/**
 * riscv_isa_extension_base() - Get base extension word
 *
@@ -779,6 +781,46 @@ static void __init riscv_fill_vendor_ext_list(int cpu)
	}
}

static int has_thead_homogeneous_vlenb(void)
{
	int cpu;
	u32 prev_vlenb = 0;
	u32 vlenb;

	/* Ignore thead,vlenb property if xtheavector is not enabled in the kernel */
	if (!IS_ENABLED(CONFIG_RISCV_ISA_XTHEADVECTOR))
		return 0;

	for_each_possible_cpu(cpu) {
		struct device_node *cpu_node;

		cpu_node = of_cpu_device_node_get(cpu);
		if (!cpu_node) {
			pr_warn("Unable to find cpu node\n");
			return -ENOENT;
		}

		if (of_property_read_u32(cpu_node, "thead,vlenb", &vlenb)) {
			of_node_put(cpu_node);

			if (prev_vlenb)
				return -ENOENT;
			continue;
		}

		if (prev_vlenb && vlenb != prev_vlenb) {
			of_node_put(cpu_node);
			return -ENOENT;
		}

		prev_vlenb = vlenb;
		of_node_put(cpu_node);
	}

	thead_vlenb_of = vlenb;
	return 0;
}

static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
{
	unsigned int cpu;
@@ -832,6 +874,12 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
		riscv_fill_vendor_ext_list(cpu);
	}

	if (riscv_isa_vendor_extension_available(THEAD_VENDOR_ID, XTHEADVECTOR) &&
	    has_thead_homogeneous_vlenb() < 0) {
		pr_warn("Unsupported heterogeneous vlenb detected, vector extension disabled.\n");
		disable_xtheadvector();
	}

	if (bitmap_empty(riscv_isa, RISCV_ISA_EXT_MAX))
		return -ENOENT;

+11 −1
Original line number Diff line number Diff line
@@ -33,7 +33,17 @@ int riscv_v_setup_vsize(void)
{
	unsigned long this_vsize;

	/* There are 32 vector registers with vlenb length. */
	/*
	 * There are 32 vector registers with vlenb length.
	 *
	 * If the thead,vlenb property was provided by the firmware, use that
	 * instead of probing the CSRs.
	 */
	if (thead_vlenb_of) {
		riscv_v_vsize = thead_vlenb_of * 32;
		return 0;
	}

	riscv_v_enable();
	this_vsize = csr_read(CSR_VLENB) * 32;
	riscv_v_disable();
Loading