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

Commit ad410674 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Michael Ellerman
Browse files

powerpc/mm: Update the HID bit when switching from radix to hash



Power9 DD1 requires to update the hid0 register when switching from
hash to radix.

Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent c6d1a767
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -475,6 +475,9 @@
#define HID0_POWER8_1TO4LPAR	__MASK(51)
#define HID0_POWER8_DYNLPARDIS	__MASK(48)

/* POWER9 HID0 bits */
#define HID0_POWER9_RADIX	__MASK(63 - 8)

#define SPRN_HID1	0x3F1		/* Hardware Implementation Register 1 */
#ifdef CONFIG_6xx
#define HID1_EMCP	(1<<31)		/* 7450 Machine Check Pin Enable */
+25 −0
Original line number Diff line number Diff line
@@ -711,6 +711,29 @@ int remove_section_mapping(unsigned long start, unsigned long end)
}
#endif /* CONFIG_MEMORY_HOTPLUG */

static void update_hid_for_hash(void)
{
	unsigned long hid0;
	unsigned long rb = 3UL << PPC_BITLSHIFT(53); /* IS = 3 */

	asm volatile("ptesync": : :"memory");
	/* prs = 0, ric = 2, rs = 0, r = 1 is = 3 */
	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
		     : : "r"(rb), "i"(0), "i"(0), "i"(2), "r"(0) : "memory");
	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
	/*
	 * now switch the HID
	 */
	hid0  = mfspr(SPRN_HID0);
	hid0 &= ~HID0_POWER9_RADIX;
	mtspr(SPRN_HID0, hid0);
	asm volatile("isync": : :"memory");

	/* Wait for it to happen */
	while ((mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
		cpu_relax();
}

static void __init hash_init_partition_table(phys_addr_t hash_table,
					     unsigned long htab_size)
{
@@ -737,6 +760,8 @@ static void __init hash_init_partition_table(phys_addr_t hash_table,
	 */
	partition_tb->patb1 = 0;
	pr_info("Partition table %p\n", partition_tb);
	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
		update_hid_for_hash();
	/*
	 * update partition table control register,
	 * 64 K size.
+28 −0
Original line number Diff line number Diff line
@@ -294,6 +294,32 @@ void __init radix__early_init_devtree(void)
	return;
}

static void update_hid_for_radix(void)
{
	unsigned long hid0;
	unsigned long rb = 3UL << PPC_BITLSHIFT(53); /* IS = 3 */

	asm volatile("ptesync": : :"memory");
	/* prs = 0, ric = 2, rs = 0, r = 1 is = 3 */
	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
		     : : "r"(rb), "i"(1), "i"(0), "i"(2), "r"(0) : "memory");
	/* prs = 1, ric = 2, rs = 0, r = 1 is = 3 */
	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
		     : : "r"(rb), "i"(1), "i"(1), "i"(2), "r"(0) : "memory");
	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
	/*
	 * now switch the HID
	 */
	hid0  = mfspr(SPRN_HID0);
	hid0 |= HID0_POWER9_RADIX;
	mtspr(SPRN_HID0, hid0);
	asm volatile("isync": : :"memory");

	/* Wait for it to happen */
	while (!(mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
		cpu_relax();
}

void __init radix__early_init_mmu(void)
{
	unsigned long lpcr;
@@ -345,6 +371,8 @@ void __init radix__early_init_mmu(void)

	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
		radix_init_native();
		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
			update_hid_for_radix();
		lpcr = mfspr(SPRN_LPCR);
		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
		radix_init_partition_table();